diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 8c8e91d3..aaf74fd7 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2418,7 +2418,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) error { +func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed 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 aeca04b9..b70f0d77 100644 --- a/pkg/app/mocks_test.go +++ b/pkg/app/mocks_test.go @@ -41,7 +41,7 @@ func (helm *noCallHelmExec) SetHelmBinary(bin string) { helm.doPanic() return } -func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string) error { +func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { helm.doPanic() return nil } diff --git a/pkg/exectest/helm.go b/pkg/exectest/helm.go index d535f5ed..60a24ef5 100644 --- a/pkg/exectest/helm.go +++ b/pkg/exectest/helm.go @@ -82,8 +82,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) error { - helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password} +func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { + helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed} return nil } func (helm *Helm) UpdateRepo() error { diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 47914dc8..8517eb28 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -105,34 +105,46 @@ func (helm *execer) SetHelmBinary(bin string) { helm.helmBinary = bin } -func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string) error { +func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { var args []string + var out []byte + var err error if name == "" && repository != "" { helm.logger.Infof("empty field name\n") return fmt.Errorf("empty field name") } - args = append(args, "repo", "add", name, repository) + switch managed { + case "acr": + helm.logger.Infof("Adding repo %v (acr)", name) + out, err = helm.azcli(name) + case "": + args = append(args, "repo", "add", name, repository) - // See https://github.com/helm/helm/pull/8777 - if cons, err := semver.NewConstraint(">= 3.3.2, < 3.3.4"); err == nil { - if cons.Check(&helm.version) { - args = append(args, "--force-update") + // See https://github.com/helm/helm/pull/8777 + if cons, err := semver.NewConstraint(">= 3.3.2, < 3.3.4"); err == nil { + if cons.Check(&helm.version) { + args = append(args, "--force-update") + } + } else { + panic(err) } - } else { - panic(err) - } - if certfile != "" && keyfile != "" { - args = append(args, "--cert-file", certfile, "--key-file", keyfile) + if certfile != "" && keyfile != "" { + args = append(args, "--cert-file", certfile, "--key-file", keyfile) + } + if cafile != "" { + args = append(args, "--ca-file", cafile) + } + if username != "" && password != "" { + args = append(args, "--username", username, "--password", password) + } + helm.logger.Infof("Adding repo %v %v", name, repository) + out, err = helm.exec(args, map[string]string{}) + default: + helm.logger.Errorf("ERROR: unknown type '%v' for repository %v", managed, name) + out = nil + err = nil } - if cafile != "" { - args = append(args, "--ca-file", cafile) - } - if username != "" && password != "" { - args = append(args, "--username", username, "--password", password) - } - helm.logger.Infof("Adding repo %v %v", name, repository) - out, err := helm.exec(args, map[string]string{}) helm.info(out) return err } @@ -370,6 +382,15 @@ func (helm *execer) exec(args []string, env map[string]string) ([]byte, error) { return bytes, err } +func (helm *execer) azcli(name string) ([]byte, error) { + cmdargs := append(strings.Split("acr helm repo add --name", " "), name) + cmd := fmt.Sprintf("exec: az %s", strings.Join(cmdargs, " ")) + helm.logger.Debug(cmd) + bytes, err := helm.runner.Execute("az", cmdargs, map[string]string{}) + helm.logger.Debugf("%s: %s", cmd, bytes) + return bytes, err +} + func (helm *execer) info(out []byte) { if len(out) > 0 { helm.logger.Infof("%s", out) diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 71eba2fd..11075ae6 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -82,7 +82,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 exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --force-update --cert-file cert.pem --key-file key.pem: @@ -96,7 +96,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 exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem: @@ -106,7 +106,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 exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-file ca.crt: @@ -116,7 +116,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/ exec: helm --kube-context dev repo add myRepo https://repo.example.com/: @@ -126,7 +126,25 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/: } buffer.Reset() - helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password") + 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: +` + if buffer.String() != expected { + t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) + } + + buffer.Reset() + helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown") + expected = `ERROR: unknown type 'unknown' for repository otherRepo +` + if buffer.String() != expected { + t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) + } + + buffer.Reset() + 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 exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --username example_user --password example_password: @@ -136,7 +154,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 ` @@ -482,7 +500,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 53096380..51ccb1b3 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) error + AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error UpdateRepo() error BuildDeps(name, chart string) error UpdateDeps(chart string) error diff --git a/pkg/state/state.go b/pkg/state/state.go index d817158d..80d13014 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -157,6 +157,7 @@ type RepositorySpec struct { KeyFile string `yaml:"keyFile,omitempty"` Username string `yaml:"username,omitempty"` Password string `yaml:"password,omitempty"` + Managed string `yaml:"managed,omitempty"` } // ReleaseSpec defines the structure of a helm release @@ -313,7 +314,7 @@ func (st *HelmState) ApplyOverrides(spec *ReleaseSpec) { } type RepoUpdater interface { - AddRepo(name, repository, cafile, certfile, keyfile, username, password string) error + AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error UpdateRepo() error } @@ -355,7 +356,7 @@ func (st *HelmState) SyncRepos(helm RepoUpdater, shouldSkip map[string]bool) ([] continue } - if err := helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password); err != nil { + if err := helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password, repo.Managed); err != nil { return nil, err } diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 3c4567d9..7b28ea62 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -857,7 +857,18 @@ func TestHelmState_SyncRepos(t *testing.T) { }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "", "", "", ""}, + want: []string{"name", "http://example.com/", "", "", "", "", "", ""}, + }, + { + name: "ACR hosted repository", + repos: []RepositorySpec{ + { + Name: "name", + Managed: "acr", + }, + }, + helm: &exectest.Helm{}, + want: []string{"name", "", "", "", "", "", "", "acr"}, }, { name: "repository with cert and key", @@ -872,7 +883,7 @@ func TestHelmState_SyncRepos(t *testing.T) { }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", ""}, + want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", "", ""}, }, { name: "repository with ca file", @@ -886,7 +897,7 @@ func TestHelmState_SyncRepos(t *testing.T) { }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "cafile", "", "", "", ""}, + want: []string{"name", "http://example.com/", "cafile", "", "", "", "", ""}, }, { name: "repository with username and password", @@ -901,7 +912,7 @@ func TestHelmState_SyncRepos(t *testing.T) { }, }, helm: &exectest.Helm{}, - want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password"}, + want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", ""}, }, } for i := range tests {