From d34dc7bb64cad9962efac8f6261cade135dec73c Mon Sep 17 00:00:00 2001 From: Babis K Date: Tue, 21 Dec 2021 02:18:57 +0200 Subject: [PATCH] Add support for --insecure-skip-tls-verify flag on helm repo add command (#1990) Parses a new field in repositories named `skipTLSVerify` and if set to `true`, it appends `--insecure-skip-tls-verify` in `helm repo add` command. This should be useful with internal self-signed repos, mitm proxies etc. Resolves #1871 --- README.md | 4 ++++ pkg/app/app_test.go | 2 +- pkg/app/mocks_test.go | 2 +- pkg/exectest/helm.go | 4 ++-- pkg/helmexec/exec.go | 5 ++++- pkg/helmexec/exec_test.go | 26 ++++++++++++++++---------- pkg/helmexec/helmexec.go | 2 +- pkg/state/state.go | 5 +++-- pkg/state/state_test.go | 34 ++++++++++++++++++++++++++++------ 9 files changed, 60 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a1e84a6c..1c41bdb2 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,10 @@ repositories: - name: insecure url: https://charts.my-insecure-domain.com caFile: optional_ca_crt +# Advanced configuration: You can skip the verification of TLS for an https repo +- name: skipTLS + url: https://ss.my-insecure-domain.com + skipTLSVerify: true # context: kube-context # this directive is deprecated, please consider using helmDefaults.kubeContext diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 905f4894..e53eb8dc 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2554,7 +2554,7 @@ func (helm *mockHelmExec) SetExtraArgs(args ...string) { func (helm *mockHelmExec) SetHelmBinary(bin string) { return } -func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error { +func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.repos = append(helm.repos, mockRepo{Name: name}) return nil } diff --git a/pkg/app/mocks_test.go b/pkg/app/mocks_test.go index b382eb65..cc00c77a 100644 --- a/pkg/app/mocks_test.go +++ b/pkg/app/mocks_test.go @@ -48,7 +48,7 @@ func (helm *noCallHelmExec) SetHelmBinary(bin string) { helm.doPanic() return } -func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error { +func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { helm.doPanic() return nil } diff --git a/pkg/exectest/helm.go b/pkg/exectest/helm.go index 9bd0b8d7..6319ce6e 100644 --- a/pkg/exectest/helm.go +++ b/pkg/exectest/helm.go @@ -84,8 +84,8 @@ func (helm *Helm) SetExtraArgs(args ...string) { func (helm *Helm) SetHelmBinary(bin string) { return } -func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error { - helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials} +func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { + helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials, skipTLSVerify} return nil } func (helm *Helm) UpdateRepo() error { diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index aecf7949..3071284a 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -108,7 +108,7 @@ func (helm *execer) SetHelmBinary(bin string) { helm.helmBinary = bin } -func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error { +func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error { var args []string var out []byte var err error @@ -144,6 +144,9 @@ func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, usernam if passCredentials == "true" { args = append(args, "--pass-credentials") } + if skipTLSVerify == "true" { + args = append(args, "--insecure-skip-tls-verify") + } helm.logger.Infof("Adding repo %v %v", name, repository) out, err = helm.exec(args, map[string]string{}) default: diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index dab4af68..13463df2 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -89,7 +89,7 @@ func Test_AddRepo_Helm_3_3_2(t *testing.T) { kubeContext: "dev", runner: &mockRunner{}, } - helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "") expected := `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --force-update --cert-file cert.pem --key-file key.pem ` @@ -102,7 +102,7 @@ func Test_AddRepo(t *testing.T) { var buffer bytes.Buffer logger := NewLogger(&buffer, "debug") helm := MockExecer(logger, "dev") - helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", "", "") expected := `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem ` @@ -111,7 +111,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-f } buffer.Reset() - helm.AddRepo("myRepo", "https://repo.example.com/", "ca.crt", "", "", "", "", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "ca.crt", "", "", "", "", "", "", "") expected = `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-file ca.crt ` @@ -120,7 +120,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-fil } buffer.Reset() - helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "") expected = `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ ` @@ -129,7 +129,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ } buffer.Reset() - helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr", "") + helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr", "", "") expected = `Adding repo acrRepo (acr) exec: az acr helm repo add --name acrRepo exec: az acr helm repo add --name acrRepo: @@ -139,7 +139,7 @@ exec: az acr helm repo add --name acrRepo: } buffer.Reset() - helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown", "") + helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown", "", "") expected = `ERROR: unknown type 'unknown' for repository otherRepo ` if buffer.String() != expected { @@ -147,7 +147,7 @@ exec: az acr helm repo add --name acrRepo: } buffer.Reset() - helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "") expected = `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password ` @@ -156,7 +156,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --userna } buffer.Reset() - helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "", "") + helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "", "", "") expected = `empty field name ` @@ -165,7 +165,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --userna } buffer.Reset() - helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "true") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "true", "") expected = `Adding repo myRepo https://repo.example.com/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password --pass-credentials ` @@ -173,6 +173,12 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --userna t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) } + buffer.Reset() + helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "", "true") + expected = `Adding repo myRepo https://repo.example.com/ +exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --insecure-skip-tls-verify +` + } func Test_UpdateRepo(t *testing.T) { @@ -516,7 +522,7 @@ func Test_LogLevels(t *testing.T) { buffer.Reset() logger := NewLogger(&buffer, logLevel) helm := MockExecer(logger, "") - helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "") + helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", "", "") if buffer.String() != expected { t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) } diff --git a/pkg/helmexec/helmexec.go b/pkg/helmexec/helmexec.go index 2bc5b7d3..d5400450 100644 --- a/pkg/helmexec/helmexec.go +++ b/pkg/helmexec/helmexec.go @@ -12,7 +12,7 @@ type Interface interface { SetExtraArgs(args ...string) SetHelmBinary(bin string) - AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error + AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error UpdateRepo() error RegistryLogin(name string, username string, password string) error BuildDeps(name, chart string) error diff --git a/pkg/state/state.go b/pkg/state/state.go index 04f8fcf5..bcb50753 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -173,6 +173,7 @@ type RepositorySpec struct { Managed string `yaml:"managed,omitempty"` OCI bool `yaml:"oci,omitempty"` PassCredentials string `yaml:"passCredentials,omitempty"` + SkipTLSVerify string `yaml:"skipTLSVerify,omitempty"` } // ReleaseSpec defines the structure of a helm release @@ -393,7 +394,7 @@ func (st *HelmState) ApplyOverrides(spec *ReleaseSpec) { type RepoUpdater interface { IsHelm3() bool - AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error + AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string, skipTLSVerify string) error UpdateRepo() error RegistryLogin(name string, username string, password string) error } @@ -412,7 +413,7 @@ func (st *HelmState) SyncRepos(helm RepoUpdater, shouldSkip map[string]bool) ([] err = helm.RegistryLogin(repo.URL, username, password) } } else { - err = helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password, repo.Managed, repo.PassCredentials) + err = helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password, repo.Managed, repo.PassCredentials, repo.SkipTLSVerify) } if err != nil { diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index edb3c99f..5e8b7c14 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -890,10 +890,11 @@ func TestHelmState_SyncRepos(t *testing.T) { Username: "", Password: "", PassCredentials: "", + SkipTLSVerify: "", }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "", "", "", "", "", ""}, + want: []string{"name", "http://example.com/", "", "", "", "", "", "", "", ""}, }, { name: "ACR hosted repository", @@ -904,7 +905,7 @@ func TestHelmState_SyncRepos(t *testing.T) { }, }, helm: &exectest.Helm{}, - want: []string{"name", "", "", "", "", "", "", "acr", ""}, + want: []string{"name", "", "", "", "", "", "", "acr", "", ""}, }, { name: "repository with cert and key", @@ -917,10 +918,11 @@ func TestHelmState_SyncRepos(t *testing.T) { Username: "", Password: "", PassCredentials: "", + SkipTLSVerify: "", }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", "", "", ""}, + want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", "", "", "", ""}, }, { name: "repository with ca file", @@ -932,10 +934,11 @@ func TestHelmState_SyncRepos(t *testing.T) { Username: "", Password: "", PassCredentials: "", + SkipTLSVerify: "", }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "cafile", "", "", "", "", "", ""}, + want: []string{"name", "http://example.com/", "cafile", "", "", "", "", "", "", ""}, }, { name: "repository with username and password", @@ -948,10 +951,11 @@ func TestHelmState_SyncRepos(t *testing.T) { Username: "example_user", Password: "example_password", PassCredentials: "", + SkipTLSVerify: "", }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", "", ""}, + want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", "", "", ""}, }, { name: "repository with username and password and pass-credentials", @@ -964,10 +968,28 @@ func TestHelmState_SyncRepos(t *testing.T) { Username: "example_user", Password: "example_password", PassCredentials: "true", + SkipTLSVerify: "", }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", "", "true"}, + want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", "", "true", ""}, + }, + { + name: "repository with skip-tls-verify", + repos: []RepositorySpec{ + { + Name: "name", + URL: "http://example.com/", + CertFile: "", + KeyFile: "", + Username: "", + Password: "", + PassCredentials: "", + SkipTLSVerify: "true", + }, + }, + helm: &exectest.Helm{}, + want: []string{"name", "http://example.com/", "", "", "", "", "", "", "", "true"}, }, } for i := range tests {