Add basic repository authentication (#154)
* basic repository authentication via new `username` and `password` keys * add warning to readme
This commit is contained in:
		
							parent
							
								
									1768e5dea7
								
							
						
					
					
						commit
						1a4f342f25
					
				|  | @ -34,6 +34,8 @@ repositories: | ||||||
|     url: http://roboll.io/charts |     url: http://roboll.io/charts | ||||||
|     certFile: optional_client_cert |     certFile: optional_client_cert | ||||||
|     keyFile: optional_client_key |     keyFile: optional_client_key | ||||||
|  |     username: optional_username | ||||||
|  |     password: optional_password | ||||||
| 
 | 
 | ||||||
| context: kube-context					 # kube-context (--kube-context) | context: kube-context					 # kube-context (--kube-context) | ||||||
| 
 | 
 | ||||||
|  | @ -178,6 +180,8 @@ The `helmfile sync` sub-command sync your cluster state as described in your `he | ||||||
| Under the covers, Helmfile executes `helm upgrade --install` for each `release` declared in the manifest, by optionally decrypting [secrets](#secrets) to be consumed as helm chart values. It also updates specified chart repositories and updates the | Under the covers, Helmfile executes `helm upgrade --install` for each `release` declared in the manifest, by optionally decrypting [secrets](#secrets) to be consumed as helm chart values. It also updates specified chart repositories and updates the | ||||||
| dependencies of any referenced local charts. | dependencies of any referenced local charts. | ||||||
| 
 | 
 | ||||||
|  | For Helm 2.9+ you can use a username and password to authenticate to a remote repository. WARNING - repository password will be exposed unmasked in console using literal value or environment variable. | ||||||
|  | 
 | ||||||
| ### diff | ### diff | ||||||
| 
 | 
 | ||||||
| The `helmfile diff` sub-command executes the [helm-diff](https://github.com/databus23/helm-diff) plugin across all of | The `helmfile diff` sub-command executes the [helm-diff](https://github.com/databus23/helm-diff) plugin across all of | ||||||
|  |  | ||||||
|  | @ -30,12 +30,15 @@ func (helm *execer) SetExtraArgs(args ...string) { | ||||||
| 	helm.extra = args | 	helm.extra = args | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (helm *execer) AddRepo(name, repository, certfile, keyfile string) error { | func (helm *execer) AddRepo(name, repository, certfile, keyfile, username, password string) error { | ||||||
| 	var args []string | 	var args []string | ||||||
| 	args = append(args, "repo", "add", name, repository) | 	args = append(args, "repo", "add", name, repository) | ||||||
| 	if certfile != "" && keyfile != "" { | 	if certfile != "" && keyfile != "" { | ||||||
| 		args = append(args, "--cert-file", certfile, "--key-file", keyfile) | 		args = append(args, "--cert-file", certfile, "--key-file", keyfile) | ||||||
| 	} | 	} | ||||||
|  | 	if username != "" && password != "" { | ||||||
|  | 		args = append(args, "--username", username, "--password", password) | ||||||
|  | 	} | ||||||
| 	out, err := helm.exec(args...) | 	out, err := helm.exec(args...) | ||||||
| 	helm.write(out) | 	helm.write(out) | ||||||
| 	return err | 	return err | ||||||
|  |  | ||||||
|  | @ -59,18 +59,25 @@ func Test_SetExtraArgs(t *testing.T) { | ||||||
| func Test_AddRepo(t *testing.T) { | func Test_AddRepo(t *testing.T) { | ||||||
| 	var buffer bytes.Buffer | 	var buffer bytes.Buffer | ||||||
| 	helm := MockExecer(&buffer, "dev") | 	helm := MockExecer(&buffer, "dev") | ||||||
| 	helm.AddRepo("myRepo", "https://repo.example.com/", "cert.pem", "key.pem") | 	helm.AddRepo("myRepo", "https://repo.example.com/", "cert.pem", "key.pem", "", "") | ||||||
| 	expected := "exec: helm repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem --kube-context dev\n" | 	expected := "exec: helm repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem --kube-context dev\n" | ||||||
| 	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() | 	buffer.Reset() | ||||||
| 	helm.AddRepo("myRepo", "https://repo.example.com/", "", "") | 	helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "") | ||||||
| 	expected = "exec: helm repo add myRepo https://repo.example.com/ --kube-context dev\n" | 	expected = "exec: helm repo add myRepo https://repo.example.com/ --kube-context dev\n" | ||||||
| 	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") | ||||||
|  | 	expected = "exec: helm repo add myRepo https://repo.example.com/ --username example_user --password example_password --kube-context dev\n" | ||||||
|  | 	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) { | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ package helmexec | ||||||
| type Interface interface { | type Interface interface { | ||||||
| 	SetExtraArgs(args ...string) | 	SetExtraArgs(args ...string) | ||||||
| 
 | 
 | ||||||
| 	AddRepo(name, repository, certfile, keyfile string) error | 	AddRepo(name, repository, certfile, keyfile, username, password string) error | ||||||
| 	UpdateRepo() error | 	UpdateRepo() error | ||||||
| 	UpdateDeps(chart string) error | 	UpdateDeps(chart string) error | ||||||
| 	SyncRelease(name, chart string, flags ...string) error | 	SyncRelease(name, chart string, flags ...string) error | ||||||
|  |  | ||||||
|  | @ -37,6 +37,8 @@ type RepositorySpec struct { | ||||||
| 	URL      string `yaml:"url"` | 	URL      string `yaml:"url"` | ||||||
| 	CertFile string `yaml:"certFile"` | 	CertFile string `yaml:"certFile"` | ||||||
| 	KeyFile  string `yaml:"keyFile"` | 	KeyFile  string `yaml:"keyFile"` | ||||||
|  | 	Username string `yaml:"username"` | ||||||
|  | 	Password string `yaml:"password"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ReleaseSpec defines the structure of a helm release
 | // ReleaseSpec defines the structure of a helm release
 | ||||||
|  | @ -152,7 +154,7 @@ func (state *HelmState) SyncRepos(helm helmexec.Interface) []error { | ||||||
| 	errs := []error{} | 	errs := []error{} | ||||||
| 
 | 
 | ||||||
| 	for _, repo := range state.Repositories { | 	for _, repo := range state.Repositories { | ||||||
| 		if err := helm.AddRepo(repo.Name, repo.URL, repo.CertFile, repo.KeyFile); err != nil { | 		if err := helm.AddRepo(repo.Name, repo.URL, repo.CertFile, repo.KeyFile, repo.Username, repo.Password); err != nil { | ||||||
| 			errs = append(errs, err) | 			errs = append(errs, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -521,8 +521,8 @@ func (helm *mockHelmExec) UpdateDeps(chart string) error { | ||||||
| func (helm *mockHelmExec) SetExtraArgs(args ...string) { | func (helm *mockHelmExec) SetExtraArgs(args ...string) { | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| func (helm *mockHelmExec) AddRepo(name, repository, certfile, keyfile string) error { | func (helm *mockHelmExec) AddRepo(name, repository, certfile, keyfile, username, password string) error { | ||||||
| 	helm.repo = []string{name, repository, certfile, keyfile} | 	helm.repo = []string{name, repository, certfile, keyfile, username, password} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| func (helm *mockHelmExec) UpdateRepo() error { | func (helm *mockHelmExec) UpdateRepo() error { | ||||||
|  | @ -576,10 +576,12 @@ func TestHelmState_SyncRepos(t *testing.T) { | ||||||
| 					URL:      "http://example.com/", | 					URL:      "http://example.com/", | ||||||
| 					CertFile: "", | 					CertFile: "", | ||||||
| 					KeyFile:  "", | 					KeyFile:  "", | ||||||
|  | 					Username: "", | ||||||
|  | 					Password: "", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			helm: &mockHelmExec{}, | 			helm: &mockHelmExec{}, | ||||||
| 			want: []string{"name", "http://example.com/", "", ""}, | 			want: []string{"name", "http://example.com/", "", "", "", ""}, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			name: "repository with cert and key", | 			name: "repository with cert and key", | ||||||
|  | @ -589,10 +591,27 @@ func TestHelmState_SyncRepos(t *testing.T) { | ||||||
| 					URL:      "http://example.com/", | 					URL:      "http://example.com/", | ||||||
| 					CertFile: "certfile", | 					CertFile: "certfile", | ||||||
| 					KeyFile:  "keyfile", | 					KeyFile:  "keyfile", | ||||||
|  | 					Username: "", | ||||||
|  | 					Password: "", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			helm: &mockHelmExec{}, | 			helm: &mockHelmExec{}, | ||||||
| 			want: []string{"name", "http://example.com/", "certfile", "keyfile"}, | 			want: []string{"name", "http://example.com/", "certfile", "keyfile", "", ""}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name: "repository with username and password", | ||||||
|  | 			repos: []RepositorySpec{ | ||||||
|  | 				{ | ||||||
|  | 					Name:     "name", | ||||||
|  | 					URL:      "http://example.com/", | ||||||
|  | 					CertFile: "", | ||||||
|  | 					KeyFile:  "", | ||||||
|  | 					Username: "example_user", | ||||||
|  | 					Password: "example_password", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			helm: &mockHelmExec{}, | ||||||
|  | 			want: []string{"name", "http://example.com/", "", "", "example_user", "example_password"}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue