From 74940a5ff3bc0444d68f7bb98f9e40107c22b0df Mon Sep 17 00:00:00 2001 From: xh4n3 Date: Fri, 26 Jul 2019 15:41:43 +0800 Subject: [PATCH] read auth info from repo file, add debug Signed-off-by: xh4n3 --- cmd/helmpush/main.go | 50 ++++++++++++++++++++++++++++++-- cmd/helmpush/main_test.go | 1 + pkg/chartmuseum/download.go | 15 ++++++++++ pkg/chartmuseum/download_test.go | 1 + pkg/chartmuseum/option.go | 8 +++++ pkg/chartmuseum/upload.go | 7 +++++ pkg/chartmuseum/upload_test.go | 2 ++ pkg/helm/repo.go | 28 ++++++++++++++++++ 8 files changed, 109 insertions(+), 3 deletions(-) diff --git a/cmd/helmpush/main.go b/cmd/helmpush/main.go index 160e634..339666b 100644 --- a/cmd/helmpush/main.go +++ b/cmd/helmpush/main.go @@ -39,6 +39,7 @@ type ( certFile string keyFile string insecureSkipVerify bool + debug bool } config struct { @@ -78,6 +79,12 @@ func newPushCmd(args []string) *cobra.Command { // If there are 4 args, this is likely being used as a downloader for acr:// protocol if len(args) == 4 && strings.HasPrefix(args[3], Protocol) { p.setFieldsFromEnv() + if p.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Args %s\n", args) + if err != nil { + return err + } + } return p.download(args[3]) } @@ -102,6 +109,7 @@ func newPushCmd(args []string) *cobra.Command { f.StringVarP(&p.keyFile, "key-file", "", "", "Identify HTTPS client using this SSL key file [$HELM_REPO_KEY_FILE]") f.BoolVarP(&p.insecureSkipVerify, "insecure", "", false, "Connect to server with an insecure way by skipping certificate verification [$HELM_REPO_INSECURE]") f.BoolVarP(&p.forceUpload, "force", "f", false, "Force upload even if chart version exists") + f.BoolVarP(&p.debug, "debug", "d", false, "Debug mode") f.Parse(args) return cmd } @@ -137,7 +145,9 @@ func (p *pushCmd) setFieldsFromEnv() { if v, ok := os.LookupEnv("HELM_REPO_INSECURE"); ok { p.insecureSkipVerify, _ = strconv.ParseBool(v) } - + if v, ok := os.LookupEnv("HELM_REPO_PLUGIN_DEBUG"); ok { + p.debug, _ = strconv.ParseBool(v) + } if p.accessToken == "" { p.setAccessTokenFromConfigFile() } @@ -205,6 +215,13 @@ func (p *pushCmd) push() error { password = p.password } + if p.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Username %s Password %s\n", username, password) + if err != nil { + return err + } + } + // in case the repo is stored with acr:// protocol, remove it var url string if p.useHTTP { @@ -225,6 +242,7 @@ func (p *pushCmd) push() error { cm.KeyFile(p.keyFile), cm.InsecureSkipVerify(p.insecureSkipVerify), cm.AutoTokenAuth(true), + cm.Debug(p.debug), ) if err != nil { @@ -288,10 +306,35 @@ func (p *pushCmd) download(fileURL string) error { parsedURL.Scheme = "https" } + var username, password string + var repo *helm.Repo + + // auth info from repo file + if p.username == "" || p.password == "" { + repoUrl := strings.Replace(strings.TrimSuffix(parsedURL.String(), filePath), "https", "acr", 1) + repo, err = helm.GetRepoByURL(repoUrl) + if err != nil { + return err + } + username = repo.Username + password = repo.Password + } else { + // auth info from env or arg + username = p.username + password = p.password + } + + if p.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Username %s Password %s\n", username, password) + if err != nil { + return err + } + } + client, err := cm.NewClient( cm.URL(parsedURL.String()), - cm.Username(p.username), - cm.Password(p.password), + cm.Username(username), + cm.Password(password), cm.AccessToken(p.accessToken), cm.AuthHeader(p.authHeader), cm.ContextPath(p.contextPath), @@ -300,6 +343,7 @@ func (p *pushCmd) download(fileURL string) error { cm.KeyFile(p.keyFile), cm.InsecureSkipVerify(p.insecureSkipVerify), cm.AutoTokenAuth(true), + cm.Debug(p.debug), ) if err != nil { diff --git a/cmd/helmpush/main_test.go b/cmd/helmpush/main_test.go index 3e50a41..e63cdb3 100644 --- a/cmd/helmpush/main_test.go +++ b/cmd/helmpush/main_test.go @@ -222,6 +222,7 @@ func TestPushCmdWithTlsEnabledServer(t *testing.T) { os.Setenv("HELM_REPO_CA_FILE", testCAPath) os.Setenv("HELM_REPO_CERT_FILE", testServerCertPath) os.Setenv("HELM_REPO_KEY_FILE", testServerKeyPath) + os.Setenv("HELM_REPO_INSECURE", "true") err = cmd.RunE(cmd, args) if err != nil { diff --git a/pkg/chartmuseum/download.go b/pkg/chartmuseum/download.go index baca29a..d9963dd 100644 --- a/pkg/chartmuseum/download.go +++ b/pkg/chartmuseum/download.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "net/http" "net/url" + "os" "path" "strings" ) @@ -42,6 +43,13 @@ func (client *Client) DownloadFile(filePath string) (*http.Response, error) { } } + if client.opts.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Token %s\n", accessToken) + if err != nil { + return nil, err + } + } + if accessToken != "" { if client.opts.authHeader != "" { req.Header.Set(client.opts.authHeader, client.opts.accessToken) @@ -81,6 +89,13 @@ func (client *Client) GetAuthTokenFromResponse(resp *http.Response) (string, err if scope == "" { return "", fmt.Errorf("missing scope in bearer auth challenge") } + + if client.opts.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Realm %s Service %s Scope %s\n", realm, service, scope) + if err != nil { + return "", err + } + } return client.getBearerToken(realm, service, scope) } diff --git a/pkg/chartmuseum/download_test.go b/pkg/chartmuseum/download_test.go index 281ceba..15e1549 100644 --- a/pkg/chartmuseum/download_test.go +++ b/pkg/chartmuseum/download_test.go @@ -94,6 +94,7 @@ func TestDownloadFileFromTlsServer(t *testing.T) { Username("user"), Password("pass"), CAFile(testCAPath), + InsecureSkipVerify(true), ) if err != nil { t.Fatalf("[with ca file] expect creating a client instance but met error: %s", err) diff --git a/pkg/chartmuseum/option.go b/pkg/chartmuseum/option.go index 6e52cb2..b951ec7 100644 --- a/pkg/chartmuseum/option.go +++ b/pkg/chartmuseum/option.go @@ -24,6 +24,7 @@ type ( keyFile string insecureSkipVerify bool autoTokenAuth bool + debug bool } ) @@ -110,3 +111,10 @@ func AutoTokenAuth(autoTokenAuth bool) Option { opts.autoTokenAuth = autoTokenAuth } } + +//Debug to indicate if we turn client's debug mode +func Debug(debug bool) Option { + return func(opts *options) { + opts.debug = debug + } +} diff --git a/pkg/chartmuseum/upload.go b/pkg/chartmuseum/upload.go index 862d344..473f6f4 100644 --- a/pkg/chartmuseum/upload.go +++ b/pkg/chartmuseum/upload.go @@ -60,6 +60,13 @@ func (client *Client) UploadChartPackage(chartPackagePath string, force bool) (* } } + if client.opts.debug { + _, err := fmt.Fprintf(os.Stderr, "[ACR PLUGIN DEBUG] Token %s\n", accessToken) + if err != nil { + return nil, err + } + } + if accessToken != "" { if client.opts.authHeader != "" { req.Header.Set(client.opts.authHeader, client.opts.accessToken) diff --git a/pkg/chartmuseum/upload_test.go b/pkg/chartmuseum/upload_test.go index edb6f4a..b88248c 100644 --- a/pkg/chartmuseum/upload_test.go +++ b/pkg/chartmuseum/upload_test.go @@ -214,6 +214,7 @@ func TestUploadChartPackageWithTlsServer(t *testing.T) { Password("pass"), ContextPath("/my/context/path"), CAFile(testCAPath), + InsecureSkipVerify(true), ) if err != nil { t.Fatalf("[upload with ca file] expect creating a client instance but met error: %s", err) @@ -268,6 +269,7 @@ func TestUploadChartPackageWithVerifyingClientCert(t *testing.T) { KeyFile(testServerKeyPath), CertFile(testServerCertPath), CAFile(testCAPath), + InsecureSkipVerify(true), ) if err != nil { t.Fatalf("[upload with cert and key files] expect creating a client instance but met error: %s", err) diff --git a/pkg/helm/repo.go b/pkg/helm/repo.go index adce337..ea23daa 100644 --- a/pkg/helm/repo.go +++ b/pkg/helm/repo.go @@ -1,3 +1,5 @@ +// Modifications copyright (C) 2019 Alibaba Group Holding Limited / Yuning Xie (xyn1016@gmail.com) + package helm import ( @@ -17,6 +19,19 @@ type ( } ) +// GetRepoByURL returns repository by url +func GetRepoByURL(url string) (*Repo, error) { + r, err := repoFile() + if err != nil { + return nil, err + } + entry, exists := findRepoEntryByURL(url, r) + if !exists { + return nil, fmt.Errorf("no repo url %q found", url) + } + return &Repo{entry}, nil +} + // GetRepoByName returns repository by name func GetRepoByName(name string) (*Repo, error) { r, err := repoFile() @@ -76,3 +91,16 @@ func findRepoEntry(name string, r *repo.RepoFile) (*repo.Entry, bool) { } return entry, exists } + +func findRepoEntryByURL(url string, r *repo.RepoFile) (*repo.Entry, bool) { + var entry *repo.Entry + exists := false + for _, re := range r.Repositories { + if strings.TrimSuffix(re.URL, "/") == strings.TrimSuffix(url, "/") { + entry = re + exists = true + break + } + } + return entry, exists +}