Merge pull request #9980 from schra/feat/password-stdin

feat(helm): add --password-stdin to `helm repo add`
pull/10047/head
Matthew Fisher 3 years ago committed by GitHub
commit 8d8a27ed1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -48,6 +48,7 @@ type repoAddOptions struct {
url string url string
username string username string
password string password string
passwordFromStdinOpt bool
passCredentialsAll bool passCredentialsAll bool
forceUpdate bool forceUpdate bool
allowDeprecatedRepos bool allowDeprecatedRepos bool
@ -85,6 +86,7 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
f.StringVar(&o.username, "username", "", "chart repository username") f.StringVar(&o.username, "username", "", "chart repository username")
f.StringVar(&o.password, "password", "", "chart repository password") f.StringVar(&o.password, "password", "", "chart repository password")
f.BoolVarP(&o.passwordFromStdinOpt, "password-stdin", "", false, "read chart repository password from stdin")
f.BoolVar(&o.forceUpdate, "force-update", false, "replace (overwrite) the repo if it already exists") f.BoolVar(&o.forceUpdate, "force-update", false, "replace (overwrite) the repo if it already exists")
f.BoolVar(&o.deprecatedNoUpdate, "no-update", false, "Ignored. Formerly, it would disabled forced updates. It is deprecated by force-update.") f.BoolVar(&o.deprecatedNoUpdate, "no-update", false, "Ignored. Formerly, it would disabled forced updates. It is deprecated by force-update.")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
@ -143,14 +145,24 @@ func (o *repoAddOptions) run(out io.Writer) error {
} }
if o.username != "" && o.password == "" { if o.username != "" && o.password == "" {
fd := int(os.Stdin.Fd()) if o.passwordFromStdinOpt {
fmt.Fprint(out, "Password: ") passwordFromStdin, err := io.ReadAll(os.Stdin)
password, err := term.ReadPassword(fd) if err != nil {
fmt.Fprintln(out) return err
if err != nil { }
return err password := strings.TrimSuffix(string(passwordFromStdin), "\n")
password = strings.TrimSuffix(password, "\r")
o.password = password
} else {
fd := int(os.Stdin.Fd())
fmt.Fprint(out, "Password: ")
password, err := term.ReadPassword(fd)
fmt.Fprintln(out)
if err != nil {
return err
}
o.password = string(password)
} }
o.password = string(password)
} }
c := repo.Entry{ c := repo.Entry{

@ -21,6 +21,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"sync" "sync"
"testing" "testing"
@ -204,3 +205,33 @@ func TestRepoAddFileCompletion(t *testing.T) {
checkFileCompletion(t, "repo add reponame", false) checkFileCompletion(t, "repo add reponame", false)
checkFileCompletion(t, "repo add reponame https://example.com", false) checkFileCompletion(t, "repo add reponame https://example.com", false)
} }
func TestRepoAddWithPasswordFromStdin(t *testing.T) {
srv := repotest.NewTempServerWithCleanupAndBasicAuth(t, "testdata/testserver/*.*")
defer srv.Stop()
defer resetEnv()()
in, err := os.Open("testdata/password")
if err != nil {
t.Errorf("unexpected error, got '%v'", err)
}
tmpdir := ensure.TempDir(t)
repoFile := filepath.Join(tmpdir, "repositories.yaml")
store := storageFixture()
const testName = "test-name"
const username = "username"
cmd := fmt.Sprintf("repo add %s %s --repository-config %s --repository-cache %s --username %s --password-stdin", testName, srv.URL(), repoFile, tmpdir, username)
var result string
_, result, err = executeActionCommandStdinC(store, in, cmd)
if err != nil {
t.Errorf("unexpected error, got '%v'", err)
}
if !strings.Contains(result, fmt.Sprintf("\"%s\" has been added to your repositories", testName)) {
t.Errorf("Repo was not successfully added. Output: %s", result)
}
}

@ -0,0 +1 @@
password

@ -16,7 +16,6 @@ limitations under the License.
package downloader package downloader
import ( import (
"net/http"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -171,19 +170,7 @@ func TestIsTar(t *testing.T) {
} }
func TestDownloadTo(t *testing.T) { func TestDownloadTo(t *testing.T) {
// Set up a fake repo with basic auth enabled srv := repotest.NewTempServerWithCleanupAndBasicAuth(t, "testdata/*.tgz*")
srv, err := repotest.NewTempServerWithCleanup(t, "testdata/*.tgz*")
srv.Stop()
if err != nil {
t.Fatal(err)
}
srv.WithMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if !ok || username != "username" || password != "password" {
t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password)
}
}))
srv.Start()
defer srv.Stop() defer srv.Stop()
if err := srv.CreateIndex(); err != nil { if err := srv.CreateIndex(); err != nil {
t.Fatal(err) t.Fatal(err)

@ -56,6 +56,23 @@ func NewTempServerWithCleanup(t *testing.T, glob string) (*Server, error) {
return srv, err return srv, err
} }
// Set up a fake repo with basic auth enabled
func NewTempServerWithCleanupAndBasicAuth(t *testing.T, glob string) *Server {
srv, err := NewTempServerWithCleanup(t, glob)
srv.Stop()
if err != nil {
t.Fatal(err)
}
srv.WithMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if !ok || username != "username" || password != "password" {
t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password)
}
}))
srv.Start()
return srv
}
type OCIServer struct { type OCIServer struct {
*registry.Registry *registry.Registry
RegistryURL string RegistryURL string

Loading…
Cancel
Save