From cd8d4f6e466c23b66f61ea5906ddd58d6f1e31c9 Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Thu, 15 Feb 2024 15:54:23 -0500 Subject: [PATCH] add login command Signed-off-by: Adam Martin --- cmd/hauler/cli/cli.go | 1 + cmd/hauler/cli/login.go | 75 +++++++++++++++++++++++++++++++++++++++++ pkg/cosign/cosign.go | 3 +- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 cmd/hauler/cli/login.go diff --git a/cmd/hauler/cli/cli.go b/cmd/hauler/cli/cli.go index dc9eb65..934d8a9 100644 --- a/cmd/hauler/cli/cli.go +++ b/cmd/hauler/cli/cli.go @@ -32,6 +32,7 @@ func New() *cobra.Command { // Add subcommands addDownload(cmd) + addLogin(cmd) addStore(cmd) addServe(cmd) addVersion(cmd) diff --git a/cmd/hauler/cli/login.go b/cmd/hauler/cli/login.go new file mode 100644 index 0000000..0f28c64 --- /dev/null +++ b/cmd/hauler/cli/login.go @@ -0,0 +1,75 @@ +package cli + +import ( + "context" + "strings" + "os" + "io" + "fmt" + "github.com/spf13/cobra" + + "oras.land/oras-go/pkg/content" + + "github.com/rancherfederal/hauler/pkg/cosign" +) + +type Opts struct { + Username string + Password string + PasswordStdin bool +} + +func (o *Opts) AddArgs(cmd *cobra.Command) { + f := cmd.Flags() + f.StringVarP(&o.Username, "username", "u", "", "Username") + f.StringVarP(&o.Password, "password", "p", "", "Password") + f.BoolVarP(&o.PasswordStdin, "password-stdin", "", false, "Take the password from stdin") +} + +func addLogin(parent *cobra.Command) { + o := &Opts{} + + cmd := &cobra.Command{ + Use: "login", + Short: "Log in to a registry", + Example: ` +# Log in to reg.example.com +hauler login reg.example.com -u bob -p haulin`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, arg []string) error { + ctx := cmd.Context() + + if o.PasswordStdin { + contents, err := io.ReadAll(os.Stdin) + if err != nil { + return err + } + o.Password = strings.TrimSuffix(string(contents), "\n") + o.Password = strings.TrimSuffix(o.Password, "\r") + } + + if o.Username == "" && o.Password == "" { + return fmt.Errorf("username and password required") + } + + return login(ctx, o, arg[0]) + }, + } + o.AddArgs(cmd) + + parent.AddCommand(cmd) +} + +func login(ctx context.Context, o *Opts, registry string) error { + ropts := content.RegistryOptions{ + Username: o.Username, + Password: o.Password, + } + + err := cosign.RegistryLogin(ctx, nil, registry, ropts) + if err != nil { + return err + } + + return nil +} \ No newline at end of file diff --git a/pkg/cosign/cosign.go b/pkg/cosign/cosign.go index dbd0703..e6e928d 100644 --- a/pkg/cosign/cosign.go +++ b/pkg/cosign/cosign.go @@ -140,17 +140,18 @@ func LoadImages(ctx context.Context, s *store.Layout, registry string, ropts con // RegistryLogin - performs cosign login func RegistryLogin(ctx context.Context, s *store.Layout, registry string, ropts content.RegistryOptions) error { + log := log.FromContext(ctx) cosignBinaryPath, err := getCosignPath(ctx) if err != nil { return err } cmd := exec.Command(cosignBinaryPath, "login", registry, "-u", ropts.Username, "-p", ropts.Password) - output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("error logging into registry: %v, output: %s", err, output) } + log.Infof(strings.Trim(string(output), "\n")) return nil }