diff --git a/cmd/oras/login.go b/cmd/oras/login.go index a76a5b29c..112ea50d2 100644 --- a/cmd/oras/login.go +++ b/cmd/oras/login.go @@ -24,6 +24,7 @@ type loginOptions struct { configs []string username string password string + insecure bool } func loginCmd() *cobra.Command { @@ -47,6 +48,9 @@ Example - Login with identity token from stdin: Example - Login with username and password by prompt: oras login localhost:5000 + +Example - Login with insecure registry from command line: + oras login --insecure localhost:5000 `, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -60,6 +64,7 @@ Example - Login with username and password by prompt: cmd.Flags().StringVarP(&opts.username, "username", "u", "", "registry username") cmd.Flags().StringVarP(&opts.password, "password", "p", "", "registry password or identity token") cmd.Flags().BoolVarP(&opts.fromStdin, "password-stdin", "", false, "read password or identity token from stdin") + cmd.Flags().BoolVarP(&opts.insecure, "insecure", "k", false, "allow connections to SSL registry without certs") return cmd } @@ -108,7 +113,7 @@ func runLogin(opts loginOptions) error { } // Login - if err := cli.Login(context.Background(), opts.hostname, opts.username, opts.password); err != nil { + if err := cli.Login(context.Background(), opts.hostname, opts.username, opts.password, opts.insecure); err != nil { return err } diff --git a/pkg/auth/client.go b/pkg/auth/client.go index 372585703..b36d4d019 100644 --- a/pkg/auth/client.go +++ b/pkg/auth/client.go @@ -15,7 +15,7 @@ var ( // Client provides authentication operations for remotes. type Client interface { // Login logs in to a remote server identified by the hostname. - Login(ctx context.Context, hostname, username, secret string) error + Login(ctx context.Context, hostname, username, secret string, insecure bool) error // Logout logs out from a remote server identified by the hostname. Logout(ctx context.Context, hostname string) error // Resolver returns a new authenticated resolver. diff --git a/pkg/auth/docker/client_test.go b/pkg/auth/docker/client_test.go index 04593812f..652d0850e 100644 --- a/pkg/auth/docker/client_test.go +++ b/pkg/auth/docker/client_test.go @@ -84,10 +84,10 @@ func (suite *DockerClientTestSuite) TearDownSuite() { func (suite *DockerClientTestSuite) Test_0_Login() { var err error - err = suite.Client.Login(newContext(), suite.DockerRegistryHost, "oscar", "opponent") + err = suite.Client.Login(newContext(), suite.DockerRegistryHost, "oscar", "opponent", false) suite.NotNil(err, "error logging into registry with invalid credentials") - err = suite.Client.Login(newContext(), suite.DockerRegistryHost, testUsername, testPassword) + err = suite.Client.Login(newContext(), suite.DockerRegistryHost, testUsername, testPassword, false) suite.Nil(err, "no error logging into registry with valid credentials") } func (suite *DockerClientTestSuite) Test_2_Logout() { diff --git a/pkg/auth/docker/login.go b/pkg/auth/docker/login.go index 803c945b3..a57449cd5 100644 --- a/pkg/auth/docker/login.go +++ b/pkg/auth/docker/login.go @@ -9,7 +9,7 @@ import ( ) // Login logs in to a docker registry identified by the hostname. -func (c *Client) Login(ctx context.Context, hostname, username, secret string) error { +func (c *Client) Login(ctx context.Context, hostname, username, secret string, insecure bool) error { hostname = resolveHostname(hostname) cred := types.AuthConfig{ Username: username, @@ -21,10 +21,16 @@ func (c *Client) Login(ctx context.Context, hostname, username, secret string) e cred.Password = secret } - // Login to ensure valid credential - remote, err := registry.NewService(registry.ServiceOptions{ + opts := registry.ServiceOptions{ V2Only: true, - }) + } + + if insecure { + opts.InsecureRegistries = []string{hostname} + } + + // Login to ensure valid credential + remote, err := registry.NewService(opts) if err != nil { return err }