gitlab.azmi.pl/azmi-open-source/helm@v3.0.0-beta.3+incompatible/cmd/helm/registry_login.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bufio"
    21  	"errors"
    22  	"fmt"
    23  	"io"
    24  	"io/ioutil"
    25  	"os"
    26  	"strings"
    27  
    28  	"github.com/docker/docker/pkg/term"
    29  	"github.com/spf13/cobra"
    30  
    31  	"helm.sh/helm/cmd/helm/require"
    32  	"helm.sh/helm/pkg/action"
    33  )
    34  
    35  const registryLoginDesc = `
    36  Authenticate to a remote registry.
    37  `
    38  
    39  func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
    40  	var usernameOpt, passwordOpt string
    41  	var passwordFromStdinOpt, insecureOpt bool
    42  
    43  	cmd := &cobra.Command{
    44  		Use:    "login [host]",
    45  		Short:  "login to a registry",
    46  		Long:   registryLoginDesc,
    47  		Args:   require.MinimumNArgs(1),
    48  		Hidden: !FeatureGateOCI.IsEnabled(),
    49  		RunE: func(cmd *cobra.Command, args []string) error {
    50  			hostname := args[0]
    51  
    52  			username, password, err := getUsernamePassword(usernameOpt, passwordOpt, passwordFromStdinOpt)
    53  			if err != nil {
    54  				return err
    55  			}
    56  
    57  			return action.NewRegistryLogin(cfg).Run(out, hostname, username, password, insecureOpt)
    58  		},
    59  	}
    60  
    61  	f := cmd.Flags()
    62  	f.StringVarP(&usernameOpt, "username", "u", "", "registry username")
    63  	f.StringVarP(&passwordOpt, "password", "p", "", "registry password or identity token")
    64  	f.BoolVarP(&passwordFromStdinOpt, "password-stdin", "", false, "read password or identity token from stdin")
    65  	f.BoolVarP(&insecureOpt, "insecure", "", false, "allow connections to TLS registry without certs")
    66  
    67  	return cmd
    68  }
    69  
    70  // Adapted from https://github.com/deislabs/oras
    71  func getUsernamePassword(usernameOpt string, passwordOpt string, passwordFromStdinOpt bool) (string, string, error) {
    72  	var err error
    73  	username := usernameOpt
    74  	password := passwordOpt
    75  
    76  	if passwordFromStdinOpt {
    77  		passwordFromStdin, err := ioutil.ReadAll(os.Stdin)
    78  		if err != nil {
    79  			return "", "", err
    80  		}
    81  		password = strings.TrimSuffix(string(passwordFromStdin), "\n")
    82  		password = strings.TrimSuffix(password, "\r")
    83  	} else if password == "" {
    84  		if username == "" {
    85  			username, err = readLine("Username: ", false)
    86  			if err != nil {
    87  				return "", "", err
    88  			}
    89  			username = strings.TrimSpace(username)
    90  		}
    91  		if username == "" {
    92  			password, err = readLine("Token: ", true)
    93  			if err != nil {
    94  				return "", "", err
    95  			} else if password == "" {
    96  				return "", "", errors.New("token required")
    97  			}
    98  		} else {
    99  			password, err = readLine("Password: ", true)
   100  			if err != nil {
   101  				return "", "", err
   102  			} else if password == "" {
   103  				return "", "", errors.New("password required")
   104  			}
   105  		}
   106  	} else {
   107  		fmt.Fprintln(os.Stderr, "WARNING! Using --password via the CLI is insecure. Use --password-stdin.")
   108  	}
   109  
   110  	return username, password, nil
   111  }
   112  
   113  // Copied/adapted from https://github.com/deislabs/oras
   114  func readLine(prompt string, silent bool) (string, error) {
   115  	fmt.Print(prompt)
   116  	if silent {
   117  		fd := os.Stdin.Fd()
   118  		state, err := term.SaveState(fd)
   119  		if err != nil {
   120  			return "", err
   121  		}
   122  		term.DisableEcho(fd, state)
   123  		defer term.RestoreTerminal(fd, state)
   124  	}
   125  
   126  	reader := bufio.NewReader(os.Stdin)
   127  	line, _, err := reader.ReadLine()
   128  	if err != nil {
   129  		return "", err
   130  	}
   131  	if silent {
   132  		fmt.Println()
   133  	}
   134  
   135  	return string(line), nil
   136  }