|
|
@ -17,8 +17,15 @@ limitations under the License.
|
|
|
|
package main
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
|
|
|
|
"bufio"
|
|
|
|
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/docker/docker/pkg/term"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
|
|
|
|
|
|
|
"helm.sh/helm/cmd/helm/require"
|
|
|
|
"helm.sh/helm/cmd/helm/require"
|
|
|
@ -30,14 +37,98 @@ Authenticate to a remote registry.
|
|
|
|
`
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
|
|
func newChartLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
|
|
|
|
func newChartLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
|
|
|
|
return &cobra.Command{
|
|
|
|
var usernameOpt, passwordOpt string
|
|
|
|
|
|
|
|
var passwordFromStdinOpt bool
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "login [host]",
|
|
|
|
Use: "login [host]",
|
|
|
|
Short: "login to a registry",
|
|
|
|
Short: "login to a registry",
|
|
|
|
Long: chartLoginDesc,
|
|
|
|
Long: chartLoginDesc,
|
|
|
|
Args: require.MinimumNArgs(1),
|
|
|
|
Args: require.MinimumNArgs(1),
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
hostname := args[0]
|
|
|
|
hostname := args[0]
|
|
|
|
return action.NewChartLogin(cfg).Run(out, hostname, "myuser", "mypass")
|
|
|
|
|
|
|
|
|
|
|
|
username, password, err := getUsernamePassword(usernameOpt, passwordOpt, passwordFromStdinOpt)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return action.NewChartLogin(cfg).Run(out, hostname, username, password)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
f := cmd.Flags()
|
|
|
|
|
|
|
|
f.StringVarP(&usernameOpt, "username", "u", "", "registry username")
|
|
|
|
|
|
|
|
f.StringVarP(&passwordOpt, "password", "p", "", "registry password or identity token")
|
|
|
|
|
|
|
|
f.BoolVarP(&passwordFromStdinOpt, "password-stdin", "", false, "read password or identity token from stdin")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Adapted from https://github.com/deislabs/oras
|
|
|
|
|
|
|
|
func getUsernamePassword(usernameOpt string, passwordOpt string, passwordFromStdinOpt bool) (string, string, error) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
username := usernameOpt
|
|
|
|
|
|
|
|
password := passwordOpt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if passwordFromStdinOpt {
|
|
|
|
|
|
|
|
passwordFromStdin, err := ioutil.ReadAll(os.Stdin)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", "", err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
password = strings.TrimSuffix(string(passwordFromStdin), "\n")
|
|
|
|
|
|
|
|
password = strings.TrimSuffix(password, "\r")
|
|
|
|
|
|
|
|
} else if password == "" {
|
|
|
|
|
|
|
|
if username == "" {
|
|
|
|
|
|
|
|
username, err = readLine("Username: ", false)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", "", err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
username = strings.TrimSpace(username)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if username == "" {
|
|
|
|
|
|
|
|
password, err = readLine("Token: ", true)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", "", err
|
|
|
|
|
|
|
|
} else if password == "" {
|
|
|
|
|
|
|
|
return "", "", errors.New("token required")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
password, err = readLine("Password: ", true)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", "", err
|
|
|
|
|
|
|
|
} else if password == "" {
|
|
|
|
|
|
|
|
return "", "", errors.New("password required")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
fmt.Fprintln(os.Stderr, "WARNING! Using --password via the CLI is insecure. Use --password-stdin.")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return username, password, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copied from https://github.com/deislabs/oras
|
|
|
|
|
|
|
|
func readLine(prompt string, slient bool) (string, error) {
|
|
|
|
|
|
|
|
fmt.Print(prompt)
|
|
|
|
|
|
|
|
if slient {
|
|
|
|
|
|
|
|
fd := os.Stdin.Fd()
|
|
|
|
|
|
|
|
state, err := term.SaveState(fd)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
term.DisableEcho(fd, state)
|
|
|
|
|
|
|
|
defer term.RestoreTerminal(fd, state)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
|
|
|
|
line, _, err := reader.ReadLine()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if slient {
|
|
|
|
|
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return string(line), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|