Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update notation cert list command output #798

Merged
merged 7 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions cmd/notation/cert/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ package cert
import (
"context"
"fmt"
"os"

"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/log"
notationgoTruststore "github.com/notaryproject/notation-go/verifier/truststore"
"github.com/notaryproject/notation/cmd/notation/internal/truststore"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/ioutil"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -72,34 +74,35 @@ func listCerts(ctx context.Context, opts *certListOpts) error {
storeType := opts.storeType
configFS := dir.ConfigFS()

var certPaths []string
// List all certificates under truststore/x509, display empty if there's
// no certificate yet
if namedStore == "" && storeType == "" {
path, err := configFS.SysPath(dir.TrustStoreDir, "x509")
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 2)); err != nil {
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 2, &certPaths)); err != nil {
logger.Debugln("Failed to complete list at path:", path)
return fmt.Errorf("failed to list all certificates stored in the trust store, with error: %s", err.Error())
}

return nil
return ioutil.PrintCertMap(os.Stdout, certPaths)
}

// List all certificates under truststore/x509/storeType/namedStore,
// display empty if there's no such certificate
// display empty if there's no certificate yet
if namedStore != "" && storeType != "" {
path, err := configFS.SysPath(dir.TrustStoreDir, "x509", storeType, namedStore)
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 0)); err != nil {
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 0, &certPaths)); err != nil {
logger.Debugln("Failed to complete list at path:", path)
return fmt.Errorf("failed to list all certificates stored in the named store %s of type %s, with error: %s", namedStore, storeType, err.Error())
}

return nil
return ioutil.PrintCertMap(os.Stdout, certPaths)
}

// List all certificates under x509/storeType, display empty if
Expand All @@ -109,24 +112,24 @@ func listCerts(ctx context.Context, opts *certListOpts) error {
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 1)); err != nil {
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 1, &certPaths)); err != nil {
logger.Debugln("Failed to complete list at path:", path)
return fmt.Errorf("failed to list all certificates stored of type %s, with error: %s", storeType, err.Error())
}
} else {
// List all certificates under named store namedStore, display empty if
// there's no such certificate
// there's no certificate yet
for _, t := range notationgoTruststore.Types {
path, err := configFS.SysPath(dir.TrustStoreDir, "x509", string(t), namedStore)
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 0)); err != nil {
if err := truststore.CheckNonErrNotExistError(truststore.ListCerts(path, 0, &certPaths)); err != nil {
logger.Debugln("Failed to complete list at path:", path)
return fmt.Errorf("failed to list all certificates stored in the named store %s, with error: %s", namedStore, err.Error())
}
}
}

return nil
return ioutil.PrintCertMap(os.Stdout, certPaths)
}
8 changes: 5 additions & 3 deletions cmd/notation/internal/truststore/truststore.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ func AddCert(path, storeType, namedStore string, display bool) error {

// ListCerts walks through root and lists all x509 certificates in it,
// sub-dirs are ignored.
func ListCerts(root string, depth int) error {
func ListCerts(root string, depth int, certPaths *[]string) error {
Two-Hearts marked this conversation as resolved.
Show resolved Hide resolved
maxDepth := strings.Count(root, string(os.PathSeparator)) + depth

if certPaths == nil {
return errors.New("certPaths cannot be nil")
}
return filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
Expand All @@ -107,7 +109,7 @@ func ListCerts(root string, depth int) error {
return err
}
if len(certs) != 0 {
fmt.Println(path)
*certPaths = append(*certPaths, path)
}
}
return nil
Expand Down
15 changes: 15 additions & 0 deletions internal/ioutil/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"encoding/json"
"fmt"
"io"
"path/filepath"
"text/tabwriter"

"github.com/notaryproject/notation-go/config"
Expand Down Expand Up @@ -58,6 +59,20 @@ func PrintMetadataMap(w io.Writer, metadata map[string]string) error {
return tw.Flush()
}

func PrintCertMap(w io.Writer, certPaths []string) error {
Two-Hearts marked this conversation as resolved.
Show resolved Hide resolved
tw := newTabWriter(w)
fmt.Fprintln(tw, "STORE TYPE\tSTORE NAME\tCERTIFICATE\t")
for _, cert := range certPaths {
fileName := filepath.Base(cert)
dir := filepath.Dir(cert)
namedStore := filepath.Base(dir)
dir = filepath.Dir(dir)
storeType := filepath.Base(dir)
Two-Hearts marked this conversation as resolved.
Show resolved Hide resolved
fmt.Fprintf(tw, "%s\t%s\t%s\t\n", storeType, namedStore, fileName)
}
return tw.Flush()
}

// PrintObjectAsJSON takes an interface and prints it as an indented JSON string
func PrintObjectAsJSON(i interface{}) error {
jsonBytes, err := json.MarshalIndent(i, "", " ")
Expand Down
8 changes: 4 additions & 4 deletions specs/commandline/certificate.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,31 +151,31 @@ Upon successful adding, the certificate files are added into directory`{NOTATION
notation certificate list
```

Upon successful listing, all the certificate files in the trust store are printed out in a format of absolute filepath. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.
Upon successful listing, all the certificate files in the trust store are printed out with information of store type, store name and certificate file name. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.
Two-Hearts marked this conversation as resolved.
Show resolved Hide resolved

### List all certificate files of a certain named store

```bash
notation cert list --store <name>
```

Upon successful listing, all the certificate files in the trust store named `<name>` are printed out in a format of absolute filepath. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.
Upon successful listing, all the certificate files in the trust store named `<name>` are printed out with information of store type, store name and certificate file name. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.

### List all certificate files of a certain type of store

```bash
notation cert list --type <type>
```

Upon successful listing, all the certificate files in the trust store of type `<type>` are printed out in a format of absolute filepath. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.
Upon successful listing, all the certificate files in the trust store of type `<type>` are printed out with information of store type, store name and certificate file name. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.

### List all certificate files of a certain named store of a certain type

```bash
notation cert list --type <type> --store <name>
```

Upon successful listing, all the certificate files in the trust store named `<name>` of type `<type>` are printed out in a format of absolute filepath. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.
Upon successful listing, all the certificate files in the trust store named `<name>` of type `<type>` are printed out with information of store type, store name and certificate file name. If the listing fails, an error message is printed out with specific reasons. Nothing is printed out if the trust store is empty.

### Show details of a certain certificate file

Expand Down
6 changes: 5 additions & 1 deletion test/e2e/suite/scenario/quickstart.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ var _ = Describe("notation quickstart E2E test", Ordered, func() {
)

notation.Exec("cert", "ls").
MatchKeyWords("notation/truststore/x509/ca/wabbit-networks.io/wabbit-networks.io.crt")
MatchKeyWords(
"ca",
"wabbit-networks.io",
"wabbit-networks.io.crt",
)
})

It("sign the container image with jws format (by default)", func() {
Expand Down
Loading