Skip to content

Commit

Permalink
update: added log to notation login and logout commands (notaryprojec…
Browse files Browse the repository at this point in the history
…t#484)

This PR adds logs to the login and logout commands.

This PR is a part of resolving
notaryproject/roadmap#71.

Signed-off-by: Patrick Zheng <[email protected]>
  • Loading branch information
Two-Hearts authored Dec 20, 2022
1 parent 4a4a820 commit 9e4e47e
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 26 deletions.
16 changes: 11 additions & 5 deletions cmd/notation/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
"os"
"strings"

"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/pkg/auth"
"github.com/spf13/cobra"
orasauth "oras.land/oras-go/v2/registry/remote/auth"
)

type loginOpts struct {
cmd.LoggingFlagOpts
SecureFlagOpts
passwordStdin bool
server string
Expand Down Expand Up @@ -47,23 +49,27 @@ Example - Login using $NOTATION_USERNAME $NOTATION_PASSWORD variables:
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return runLogin(cmd, opts)
return runLogin(cmd.Context(), opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
command.Flags().BoolVar(&opts.passwordStdin, "password-stdin", false, "take the password from stdin")
opts.ApplyFlags(command.Flags())
return command
}

func runLogin(cmd *cobra.Command, opts *loginOpts) error {
func runLogin(ctx context.Context, opts *loginOpts) error {
// set log level
ctx = opts.LoggingFlagOpts.SetLoggerLevel(ctx)

// initialize
serverAddress := opts.server

if err := validateAuthConfig(cmd.Context(), opts, serverAddress); err != nil {
if err := validateAuthConfig(ctx, opts, serverAddress); err != nil {
return err
}

nativeStore, err := auth.GetCredentialsStore(serverAddress)
nativeStore, err := auth.GetCredentialsStore(ctx, serverAddress)
if err != nil {
return fmt.Errorf("could not get the credentials store: %v", err)
}
Expand Down
25 changes: 20 additions & 5 deletions cmd/notation/logout.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package main

import (
"context"
"errors"
"fmt"

"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/pkg/auth"
"github.com/spf13/cobra"
)

type logoutOpts struct {
cmd.LoggingFlagOpts
server string
}

func logoutCommand(opts *logoutOpts) *cobra.Command {
if opts == nil {
opts = &logoutOpts{}
}
return &cobra.Command{
command := &cobra.Command{
Use: "logout [flags] <server>",
Short: "Log out from the logged in registries",
Args: func(cmd *cobra.Command, args []string) error {
Expand All @@ -26,17 +30,28 @@ func logoutCommand(opts *logoutOpts) *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return runLogout(cmd, opts)
return runLogout(cmd.Context(), opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
return command
}

func runLogout(cmd *cobra.Command, opts *logoutOpts) error {
func runLogout(ctx context.Context, opts *logoutOpts) error {
// set log level
ctx = opts.LoggingFlagOpts.SetLoggerLevel(ctx)

// initialize
serverAddress := opts.server
nativeStore, err := auth.GetCredentialsStore(serverAddress)
nativeStore, err := auth.GetCredentialsStore(ctx, serverAddress)
if err != nil {
return err
}
return nativeStore.Erase(serverAddress)
err = nativeStore.Erase(serverAddress)
if err != nil {
return err
}

fmt.Println("Logout Succeeded")
return nil
}
6 changes: 3 additions & 3 deletions cmd/notation/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func getAuthClient(ctx context.Context, opts *SecureFlagOpts, ref registry.Refer
}
if cred == auth.EmptyCredential {
var err error
cred, err = getSavedCreds(ref.Registry)
cred, err = getSavedCreds(ctx, ref.Registry)
// local registry may not need credentials
if err != nil && !errors.Is(err, loginauth.ErrCredentialsConfigNotSet) {
return nil, false, err
Expand All @@ -119,8 +119,8 @@ func getAuthClient(ctx context.Context, opts *SecureFlagOpts, ref registry.Refer
return authClient, plainHTTP, nil
}

func getSavedCreds(serverAddress string) (auth.Credential, error) {
nativeStore, err := loginauth.GetCredentialsStore(serverAddress)
func getSavedCreds(ctx context.Context, serverAddress string) (auth.Credential, error) {
nativeStore, err := loginauth.GetCredentialsStore(ctx, serverAddress)
if err != nil {
return auth.EmptyCredential, err
}
Expand Down
10 changes: 7 additions & 3 deletions pkg/auth/native_store.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package auth

import (
"context"
"fmt"

"github.com/docker/docker-credential-helpers/client"
"github.com/docker/docker-credential-helpers/credentials"
"github.com/notaryproject/notation-go/config"
"github.com/notaryproject/notation-go/log"
"oras.land/oras-go/v2/registry/remote/auth"
)

Expand All @@ -25,22 +27,24 @@ type nativeAuthStore struct {

// GetCredentialsStore returns a new credentials store from the settings in the
// configuration file
func GetCredentialsStore(registryHostname string) (CredentialStore, error) {
func GetCredentialsStore(ctx context.Context, registryHostname string) (CredentialStore, error) {
configFile, err := loadConfig()
if err != nil {
return nil, fmt.Errorf("failed to load config file, error: %w", err)
}
if helper := getConfiguredCredentialStore(configFile, registryHostname); helper != "" {
return newNativeAuthStore(helper), nil
return newNativeAuthStore(ctx, helper), nil
}
return nil, fmt.Errorf("could not get the configured credentials store for registry: %s", registryHostname)
}

// newNativeAuthStore creates a new native store that uses a remote helper
// program to manage credentials. Note: it's different from the nativeStore in
// docker-cli which may fall back to plain text store
func newNativeAuthStore(helperSuffix string) CredentialStore {
func newNativeAuthStore(ctx context.Context, helperSuffix string) CredentialStore {
logger := log.GetLogger(ctx)
name := remoteCredentialsPrefix + helperSuffix
logger.Infoln("Executing remote credential helper program:", name)
return &nativeAuthStore{
programFunc: client.NewShellProgramFunc(name),
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/auth/native_store_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package auth

import (
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -168,7 +169,7 @@ func TestNativeStore_GetCredentialsStore_LoadConfigFailed(t *testing.T) {
loadConfig = func() (*config.Config, error) {
return nil, fmt.Errorf("loadConfig err")
}
_, err := GetCredentialsStore(validServerAddress)
_, err := GetCredentialsStore(context.Background(), validServerAddress)
if err == nil {
t.Fatalf("expect error, got nil")
}
Expand All @@ -178,7 +179,7 @@ func TestNativeStore_GetCredentialsStore_NoHelperSet(t *testing.T) {
loadConfig = func() (*config.Config, error) {
return &config.Config{}, nil
}
_, err := GetCredentialsStore(validServerAddress)
_, err := GetCredentialsStore(context.Background(), validServerAddress)
if err == nil || err.Error() != "could not get the configured credentials store for registry: "+validServerAddress {
t.Fatalf("Didn't get the expected error, but got: %v", err)
}
Expand All @@ -192,7 +193,7 @@ func TestNativeStore_GetCredentialsStore_HelperSet(t *testing.T) {
},
}, nil
}
_, err := GetCredentialsStore(validServerAddress)
_, err := GetCredentialsStore(context.Background(), validServerAddress)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand Down
2 changes: 2 additions & 0 deletions specs/commandline/login.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ Usage:
notation login [flags] <server>
Flags:
-d, --debug debug mode
-h, --help help for login
-p, --password string password for registry operations (default to $NOTATION_PASSWORD if not specified)
--password-stdin take the password from stdin
--plain-http registry access via plain HTTP
-u, --username string username for registry operations (default to $NOTATION_USERNAME if not specified)
-v, --verbose verbose mode
```

## Usage
Expand Down
10 changes: 3 additions & 7 deletions specs/commandline/logout.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Usage:
notation logout [flags] <server>
Flags:
-h, --help help for logout
-d, --debug debug mode
-h, --help help for logout
-v, --verbose verbose mode
```

## Usage
Expand All @@ -23,9 +25,3 @@ Flags:
```shell
notation logout registry.example.com
```

### Log out from all logged in registries

```shell
notation logout --all
```

0 comments on commit 9e4e47e

Please sign in to comment.