diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 7f76b10e..da4eb99d 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -2445,7 +2445,7 @@ func (helm *mockHelmExec) ChartPull(chart string, path string, flags ...string) return nil } -func (helm *mockHelmExec) ChartExport(chart string, path string, flags ...string) error { +func (helm *mockHelmExec) ChartExport(chart string, path string) error { return nil } @@ -2476,7 +2476,7 @@ func (helm *mockHelmExec) AddRepo(name, repository, cafile, certfile, keyfile, u func (helm *mockHelmExec) UpdateRepo() error { return nil } -func (helm *mockHelmExec) RegistryLogin(name string, username string, password string) error { +func (helm *mockHelmExec) RegistryLogin(name, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error { return nil } func (helm *mockHelmExec) SyncRelease(context helmexec.HelmContext, name, chart string, flags ...string) error { diff --git a/pkg/exectest/helm.go b/pkg/exectest/helm.go index ca54bcc4..f6539ee9 100644 --- a/pkg/exectest/helm.go +++ b/pkg/exectest/helm.go @@ -101,7 +101,7 @@ func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, func (helm *Helm) UpdateRepo() error { return nil } -func (helm *Helm) RegistryLogin(name string, username string, password string) error { +func (helm *Helm) RegistryLogin(name, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error { return nil } func (helm *Helm) SyncRelease(context helmexec.HelmContext, name, chart string, flags ...string) error { @@ -198,7 +198,7 @@ func (helm *Helm) TemplateRelease(name, chart string, flags ...string) error { func (helm *Helm) ChartPull(chart string, path string, flags ...string) error { return nil } -func (helm *Helm) ChartExport(chart string, path string, flags ...string) error { +func (helm *Helm) ChartExport(chart string, path string) error { return nil } func (helm *Helm) IsHelm3() bool { diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 2e527243..8b8d5d59 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -205,18 +205,37 @@ func (helm *execer) UpdateRepo() error { return err } -func (helm *execer) RegistryLogin(repository string, username string, password string) error { - helm.logger.Info("Logging in to registry") +func (helm *execer) RegistryLogin(repository, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error { + if username == "" || password == "" { + return nil + } + + buffer := bytes.Buffer{} args := []string{ "registry", "login", repository, - "--username", - username, - "--password-stdin", } - buffer := bytes.Buffer{} + helmVersionConstraint, _ := semver.NewConstraint(">= 3.12.0") + if helmVersionConstraint.Check(helm.version) { + // in the 3.12.0 version, the registry login support --key-file --cert-file and --ca-file + // https://github.com/helm/helm/releases/tag/v3.12.0 + if certFile != "" && keyFile != "" { + args = append(args, "--cert-file", certFile, "--key-file", keyFile) + } + if caFile != "" { + args = append(args, "--ca-file", caFile) + } + } + + if skipTLSVerify { + args = append(args, "--insecure") + } + + args = append(args, "--username", username, "--password-stdin", password) buffer.Write([]byte(fmt.Sprintf("%s\n", password))) + + helm.logger.Info("Logging in to registry") out, err := helm.execStdIn(args, map[string]string{"HELM_EXPERIMENTAL_OCI": "1"}, &buffer) helm.info(out) return err @@ -468,15 +487,16 @@ func (helm *execer) ChartPull(chart string, path string, flags ...string) error // https://github.com/helm/helm/releases/tag/v3.7.0 ociChartURL, ociChartTag := resolveOciChart(chart) helmArgs = []string{"pull", ociChartURL, "--version", ociChartTag, "--destination", path, "--untar"} + helmArgs = append(helmArgs, flags...) } else { helmArgs = []string{"chart", "pull", chart} } - out, err := helm.exec(append(helmArgs, flags...), map[string]string{"HELM_EXPERIMENTAL_OCI": "1"}, nil) + out, err := helm.exec(helmArgs, map[string]string{"HELM_EXPERIMENTAL_OCI": "1"}, nil) helm.info(out) return err } -func (helm *execer) ChartExport(chart string, path string, flags ...string) error { +func (helm *execer) ChartExport(chart string, path string) error { helmVersionConstraint, _ := semver.NewConstraint(">= 3.7.0") if helmVersionConstraint.Check(helm.version) { // in the 3.7.0 version, the chart export has been removed @@ -486,7 +506,8 @@ func (helm *execer) ChartExport(chart string, path string, flags ...string) erro var helmArgs []string helm.logger.Infof("Exporting %v", chart) helmArgs = []string{"chart", "export", chart, "--destination", path} - out, err := helm.exec(append(helmArgs, flags...), map[string]string{"HELM_EXPERIMENTAL_OCI": "1"}, nil) + // no extra flags for before v3.7.0, details in helm chart export --help + out, err := helm.exec(helmArgs, map[string]string{"HELM_EXPERIMENTAL_OCI": "1"}, nil) helm.info(out) return err } diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index e8069141..30bbaccc 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -755,7 +755,7 @@ func Test_ChartPull(t *testing.T) { chartPath: "path1", chartFlags: []string{"--untar", "--untardir", "/tmp/dir"}, listResult: `Pulling chart -exec: helm --kube-context dev chart pull chart --untar --untardir /tmp/dir +exec: helm --kube-context dev chart pull chart `, }, { @@ -802,7 +802,6 @@ func Test_ChartExport(t *testing.T) { helmVersion string chartName string chartPath string - chartFlags []string listResult string expectedError string }{ @@ -812,9 +811,8 @@ func Test_ChartExport(t *testing.T) { helmVersion: "v3.6.0", chartName: "chart", chartPath: "path1", - chartFlags: []string{"--untar", "--untardir", "/tmp/dir"}, listResult: `Exporting chart -exec: helm --kube-context dev chart export chart --destination path1 --untar --untardir /tmp/dir +exec: helm --kube-context dev chart export chart --destination path1 `, expectedError: "", }, @@ -830,7 +828,7 @@ exec: helm --kube-context dev chart export chart --destination path1 --untar --u kubeContext: "dev", runner: &mockRunner{}, } - err := helm.ChartExport(tt.chartName, tt.chartPath, tt.chartFlags...) + err := helm.ChartExport(tt.chartName, tt.chartPath) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/pkg/helmexec/helmexec.go b/pkg/helmexec/helmexec.go index 0ced7c3a..dcd66902 100644 --- a/pkg/helmexec/helmexec.go +++ b/pkg/helmexec/helmexec.go @@ -18,7 +18,7 @@ type Interface interface { AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials, skipTLSVerify bool) error UpdateRepo() error - RegistryLogin(name string, username string, password string) error + RegistryLogin(name, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error BuildDeps(name, chart string, flags ...string) error UpdateDeps(chart string) error SyncRelease(context HelmContext, name, chart string, flags ...string) error @@ -26,7 +26,7 @@ type Interface interface { TemplateRelease(name, chart string, flags ...string) error Fetch(chart string, flags ...string) error ChartPull(chart string, path string, flags ...string) error - ChartExport(chart string, path string, flags ...string) error + ChartExport(chart string, path string) error Lint(name, chart string, flags ...string) error ReleaseStatus(context HelmContext, name string, flags ...string) error DeleteRelease(context HelmContext, name string, flags ...string) error diff --git a/pkg/state/state.go b/pkg/state/state.go index 67fd3a4b..fc70884d 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -501,7 +501,7 @@ type RepoUpdater interface { IsHelm3() bool AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials, skipTLSVerify bool) error UpdateRepo() error - RegistryLogin(name string, username string, password string) error + RegistryLogin(name, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error } func (st *HelmState) SyncRepos(helm RepoUpdater, shouldSkip map[string]bool) ([]string, error) { @@ -514,9 +514,7 @@ func (st *HelmState) SyncRepos(helm RepoUpdater, shouldSkip map[string]bool) ([] username, password := gatherUsernamePassword(repo.Name, repo.Username, repo.Password) var err error if repo.OCI { - if username != "" && password != "" { - err = helm.RegistryLogin(repo.URL, username, password) - } + err = helm.RegistryLogin(repo.URL, username, password, repo.CaFile, repo.CertFile, repo.KeyFile, repo.SkipTLSVerify) } else { err = helm.AddRepo(repo.Name, repo.URL, repo.CaFile, repo.CertFile, repo.KeyFile, username, password, repo.Managed, repo.PassCredentials, repo.SkipTLSVerify) } @@ -3481,10 +3479,25 @@ func (st *HelmState) getOCIChart(release *ReleaseSpec, tempDir string, helm helm if st.fs.DirectoryExistsAt(chartPath) { st.logger.Debugf("chart already exists at %s", chartPath) } else { - err := helm.ChartPull(qualifiedChartName, chartPath) + flags := []string{} + repo, _ := st.GetRepositoryAndNameFromChartName(release.Chart) + if repo != nil { + if repo.CaFile != "" { + flags = append(flags, "--ca-file", repo.CaFile) + } + if repo.CertFile != "" && repo.KeyFile != "" { + flags = append(flags, "--cert-file", repo.CertFile, "--key-file", repo.KeyFile) + } + if repo.SkipTLSVerify { + flags = append(flags, "--insecure-skip-tls-verify") + } + } + + err := helm.ChartPull(qualifiedChartName, chartPath, flags...) if err != nil { return nil, err } + err = helm.ChartExport(qualifiedChartName, chartPath) if err != nil { return nil, err diff --git a/pkg/testutil/mocks.go b/pkg/testutil/mocks.go index be79e3cc..8aaecd59 100644 --- a/pkg/testutil/mocks.go +++ b/pkg/testutil/mocks.go @@ -50,7 +50,7 @@ func (helm *noCallHelmExec) ChartPull(chart string, path string, flags ...string helm.doPanic() return nil } -func (helm *noCallHelmExec) ChartExport(chart string, path string, flags ...string) error { +func (helm *noCallHelmExec) ChartExport(chart string, path string) error { helm.doPanic() return nil } @@ -85,7 +85,7 @@ func (helm *noCallHelmExec) UpdateRepo() error { helm.doPanic() return nil } -func (helm *noCallHelmExec) RegistryLogin(name string, username string, password string) error { +func (helm *noCallHelmExec) RegistryLogin(name, username, password, caFile, certFile, keyFile string, skipTLSVerify bool) error { helm.doPanic() return nil }