feat: pass-credentials to repo (#1899)

This adds the ability to include the --pass-credentials flag to the helm add repo command by:

- Adding repo.passCredentials to the helmfile yaml
- Changing state, helmexec, and app to include RepositorySpec.PassCredentials

Resolves #1898

Co-authored-by: almed4 <alexandre.meddin@ingka.ikea.com>
This commit is contained in:
Alex Meddin 2021-07-01 18:31:16 -04:00 committed by GitHub
parent c623730374
commit 46b17e2cdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 89 additions and 54 deletions

View File

@ -62,6 +62,7 @@ repositories:
username: optional_username username: optional_username
password: optional_password password: optional_password
oci: true oci: true
passCredentials: true
# Advanced configuration: You can use a ca bundle to use an https repo # Advanced configuration: You can use a ca bundle to use an https repo
# with a self-signed certificate # with a self-signed certificate
- name: insecure - name: insecure

View File

@ -2519,7 +2519,7 @@ func (helm *mockHelmExec) SetExtraArgs(args ...string) {
func (helm *mockHelmExec) SetHelmBinary(bin string) { func (helm *mockHelmExec) SetHelmBinary(bin string) {
return return
} }
func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error {
helm.repos = append(helm.repos, mockRepo{Name: name}) helm.repos = append(helm.repos, mockRepo{Name: name})
return nil return nil
} }

View File

@ -48,7 +48,7 @@ func (helm *noCallHelmExec) SetHelmBinary(bin string) {
helm.doPanic() helm.doPanic()
return return
} }
func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { func (helm *noCallHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error {
helm.doPanic() helm.doPanic()
return nil return nil
} }

View File

@ -84,8 +84,8 @@ func (helm *Helm) SetExtraArgs(args ...string) {
func (helm *Helm) SetHelmBinary(bin string) { func (helm *Helm) SetHelmBinary(bin string) {
return return
} }
func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { 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} helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, passCredentials}
return nil return nil
} }
func (helm *Helm) UpdateRepo() error { func (helm *Helm) UpdateRepo() error {

View File

@ -108,7 +108,7 @@ func (helm *execer) SetHelmBinary(bin string) {
helm.helmBinary = bin helm.helmBinary = bin
} }
func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error { func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error {
var args []string var args []string
var out []byte var out []byte
var err error var err error
@ -141,6 +141,9 @@ func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, usernam
if username != "" && password != "" { if username != "" && password != "" {
args = append(args, "--username", username, "--password", password) args = append(args, "--username", username, "--password", password)
} }
if passCredentials == "true" {
args = append(args, "--pass-credentials")
}
helm.logger.Infof("Adding repo %v %v", name, repository) helm.logger.Infof("Adding repo %v %v", name, repository)
out, err = helm.exec(args, map[string]string{}) out, err = helm.exec(args, map[string]string{})
default: default:

View File

@ -89,7 +89,7 @@ func Test_AddRepo_Helm_3_3_2(t *testing.T) {
kubeContext: "dev", kubeContext: "dev",
runner: &mockRunner{}, 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/ 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
` `
@ -102,7 +102,7 @@ func Test_AddRepo(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") 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/ 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
` `
@ -111,7 +111,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --cert-f
} }
buffer.Reset() 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/ 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
` `
@ -120,7 +120,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --ca-fil
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "") helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "", "", "", "")
expected = `Adding repo 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/
` `
@ -129,7 +129,7 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr") helm.AddRepo("acrRepo", "", "", "", "", "", "", "acr", "")
expected = `Adding repo acrRepo (acr) expected = `Adding repo acrRepo (acr)
exec: az acr helm repo add --name acrRepo exec: az acr helm repo add --name acrRepo
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() buffer.Reset()
helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown") helm.AddRepo("otherRepo", "", "", "", "", "", "", "unknown", "")
expected = `ERROR: unknown type 'unknown' for repository otherRepo expected = `ERROR: unknown type 'unknown' for repository otherRepo
` `
if buffer.String() != expected { if buffer.String() != expected {
@ -147,7 +147,7 @@ exec: az acr helm repo add --name acrRepo:
} }
buffer.Reset() 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/ 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
` `
@ -156,13 +156,23 @@ exec: helm --kube-context dev repo add myRepo https://repo.example.com/ --userna
} }
buffer.Reset() buffer.Reset()
helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "") helm.AddRepo("", "https://repo.example.com/", "", "", "", "", "", "", "")
expected = `empty field name expected = `empty field name
` `
if buffer.String() != expected { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", 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", "", "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
`
if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
} }
func Test_UpdateRepo(t *testing.T) { func Test_UpdateRepo(t *testing.T) {
@ -506,7 +516,7 @@ func Test_LogLevels(t *testing.T) {
buffer.Reset() buffer.Reset()
logger := NewLogger(&buffer, logLevel) logger := NewLogger(&buffer, logLevel)
helm := MockExecer(logger, "") 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 { if buffer.String() != expected {
t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected) t.Errorf("helmexec.AddRepo()\nactual = %v\nexpect = %v", buffer.String(), expected)
} }

View File

@ -12,7 +12,7 @@ type Interface interface {
SetExtraArgs(args ...string) SetExtraArgs(args ...string)
SetHelmBinary(bin string) SetHelmBinary(bin string)
AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error
UpdateRepo() error UpdateRepo() error
RegistryLogin(name string, username string, password string) error RegistryLogin(name string, username string, password string) error
BuildDeps(name, chart string) error BuildDeps(name, chart string) error

View File

@ -163,15 +163,16 @@ type HelmSpec struct {
// RepositorySpec that defines values for a helm repo // RepositorySpec that defines values for a helm repo
type RepositorySpec struct { type RepositorySpec struct {
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty"`
URL string `yaml:"url,omitempty"` URL string `yaml:"url,omitempty"`
CaFile string `yaml:"caFile,omitempty"` CaFile string `yaml:"caFile,omitempty"`
CertFile string `yaml:"certFile,omitempty"` CertFile string `yaml:"certFile,omitempty"`
KeyFile string `yaml:"keyFile,omitempty"` KeyFile string `yaml:"keyFile,omitempty"`
Username string `yaml:"username,omitempty"` Username string `yaml:"username,omitempty"`
Password string `yaml:"password,omitempty"` Password string `yaml:"password,omitempty"`
Managed string `yaml:"managed,omitempty"` Managed string `yaml:"managed,omitempty"`
OCI bool `yaml:"oci,omitempty"` OCI bool `yaml:"oci,omitempty"`
PassCredentials string `yaml:"passCredentials,omitempty"`
} }
// ReleaseSpec defines the structure of a helm release // ReleaseSpec defines the structure of a helm release
@ -392,7 +393,7 @@ func (st *HelmState) ApplyOverrides(spec *ReleaseSpec) {
type RepoUpdater interface { type RepoUpdater interface {
IsHelm3() bool IsHelm3() bool
AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string) error AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials string) error
UpdateRepo() error UpdateRepo() error
RegistryLogin(name string, username string, password string) error RegistryLogin(name string, username string, password string) error
} }
@ -441,7 +442,7 @@ func (st *HelmState) SyncRepos(helm RepoUpdater, shouldSkip map[string]bool) ([]
err = helm.RegistryLogin(repo.URL, username, password) err = helm.RegistryLogin(repo.URL, username, password)
} }
} else { } else {
err = helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password, repo.Managed) err = helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, repo.Username, repo.Password, repo.Managed, repo.PassCredentials)
} }
if err != nil { if err != nil {

View File

@ -883,16 +883,17 @@ func TestHelmState_SyncRepos(t *testing.T) {
name: "normal repository", name: "normal repository",
repos: []RepositorySpec{ repos: []RepositorySpec{
{ {
Name: "name", Name: "name",
URL: "http://example.com/", URL: "http://example.com/",
CertFile: "", CertFile: "",
KeyFile: "", KeyFile: "",
Username: "", Username: "",
Password: "", Password: "",
PassCredentials: "",
}, },
}, },
helm: &exectest.Helm{}, helm: &exectest.Helm{},
want: []string{"name", "http://example.com/", "", "", "", "", "", ""}, want: []string{"name", "http://example.com/", "", "", "", "", "", "", ""},
}, },
{ {
name: "ACR hosted repository", name: "ACR hosted repository",
@ -903,51 +904,70 @@ func TestHelmState_SyncRepos(t *testing.T) {
}, },
}, },
helm: &exectest.Helm{}, helm: &exectest.Helm{},
want: []string{"name", "", "", "", "", "", "", "acr"}, want: []string{"name", "", "", "", "", "", "", "acr", ""},
}, },
{ {
name: "repository with cert and key", name: "repository with cert and key",
repos: []RepositorySpec{ repos: []RepositorySpec{
{ {
Name: "name", Name: "name",
URL: "http://example.com/", URL: "http://example.com/",
CertFile: "certfile", CertFile: "certfile",
KeyFile: "keyfile", KeyFile: "keyfile",
Username: "", Username: "",
Password: "", Password: "",
PassCredentials: "",
}, },
}, },
helm: &exectest.Helm{}, helm: &exectest.Helm{},
want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", "", ""}, want: []string{"name", "http://example.com/", "", "certfile", "keyfile", "", "", "", ""},
}, },
{ {
name: "repository with ca file", name: "repository with ca file",
repos: []RepositorySpec{ repos: []RepositorySpec{
{ {
Name: "name", Name: "name",
URL: "http://example.com/", URL: "http://example.com/",
CaFile: "cafile", CaFile: "cafile",
Username: "", Username: "",
Password: "", Password: "",
PassCredentials: "",
}, },
}, },
helm: &exectest.Helm{}, helm: &exectest.Helm{},
want: []string{"name", "http://example.com/", "cafile", "", "", "", "", ""}, want: []string{"name", "http://example.com/", "cafile", "", "", "", "", "", ""},
}, },
{ {
name: "repository with username and password", name: "repository with username and password",
repos: []RepositorySpec{ repos: []RepositorySpec{
{ {
Name: "name", Name: "name",
URL: "http://example.com/", URL: "http://example.com/",
CertFile: "", CertFile: "",
KeyFile: "", KeyFile: "",
Username: "example_user", Username: "example_user",
Password: "example_password", Password: "example_password",
PassCredentials: "",
}, },
}, },
helm: &exectest.Helm{}, 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",
repos: []RepositorySpec{
{
Name: "name",
URL: "http://example.com/",
CertFile: "",
KeyFile: "",
Username: "example_user",
Password: "example_password",
PassCredentials: "true",
},
},
helm: &exectest.Helm{},
want: []string{"name", "http://example.com/", "", "", "", "example_user", "example_password", "", "true"},
}, },
} }
for i := range tests { for i := range tests {