From af01394e9fdc44a30b3deda2dc310ad0b0ae6a1f Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 19 Oct 2020 14:37:32 -0600 Subject: [PATCH] warn and block old repo URLs (#8903) Signed-off-by: Matt Butcher --- cmd/helm/repo_add.go | 27 ++++++++++++++++++----- cmd/helm/root.go | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index f79c213c0..f51e402fa 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -37,12 +37,19 @@ import ( "helm.sh/helm/v3/pkg/repo" ) +// Repositories that have been permanently deleted and no longer work +var deprecatedRepos = map[string]string{ + "//kubernetes-charts.storage.googleapis.com": "https://charts.helm.sh/stable", + "//kubernetes-charts-incubator.storage.googleapis.com": "https://charts.helm.sh/incubator", +} + type repoAddOptions struct { - name string - url string - username string - password string - forceUpdate bool + name string + url string + username string + password string + forceUpdate bool + allowDeprecatedRepos bool certFile string keyFile string @@ -83,11 +90,21 @@ func newRepoAddCmd(out io.Writer) *cobra.Command { f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the repository") + f.BoolVar(&o.allowDeprecatedRepos, "allow-deprecated-repos", false, "by default, this command will not allow adding official repos that have been permanently deleted. This disables that behavior") return cmd } func (o *repoAddOptions) run(out io.Writer) error { + // Block deprecated repos + if !o.allowDeprecatedRepos { + for oldURL, newURL := range deprecatedRepos { + if strings.Contains(o.url, oldURL) { + return fmt.Errorf("repo %q is no longer available; try %q instead", o.url, newURL) + } + } + } + //Ensure the file directory exists as it is required for file locking err := os.MkdirAll(filepath.Dir(o.repoFile), os.ModePerm) if err != nil && !os.IsExist(err) { diff --git a/cmd/helm/root.go b/cmd/helm/root.go index cc97a5541..23b8d7be6 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "log" + "os" "strings" "github.com/spf13/cobra" @@ -30,6 +31,7 @@ import ( "helm.sh/helm/v3/internal/experimental/registry" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/repo" ) var globalUsage = `The Kubernetes package manager @@ -208,5 +210,54 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string // Check permissions on critical files checkPerms() + // Check for expired repositories + checkForExpiredRepos(settings.RepositoryConfig) + return cmd, nil } + +func checkForExpiredRepos(repofile string) { + + expiredRepos := []struct { + name string + old string + new string + }{ + { + name: "stable", + old: "kubernetes-charts.storage.googleapis.com", + new: "https://charts.helm.sh/stable", + }, + { + name: "incubator", + old: "kubernetes-charts-incubator.storage.googleapis.com", + new: "https://charts.helm.sh/incubator", + }, + } + + // parse repo file. + // Ignore the error because it is okay for a repo file to be unparseable at this + // stage. Later checks will trap the error and respond accordingly. + repoFile, err := repo.LoadFile(repofile) + if err != nil { + return + } + + for _, exp := range expiredRepos { + r := repoFile.Get(exp.name) + if r == nil { + return + } + + if url := r.URL; strings.Contains(url, exp.old) { + fmt.Fprintf( + os.Stderr, + "WARNING: %q is deprecated for %q and will be deleted Nov. 13, 2020.\nWARNING: You should switch to %q\n", + exp.old, + exp.name, + exp.new, + ) + } + } + +}