Skip to content

Commit

Permalink
update: update notation CLI with notation-go refactoring (notaryproje…
Browse files Browse the repository at this point in the history
…ct#445)

This PR updates notation CLI logic to use the refactored notation-go
with oras-go v2.0.0-rc.5.

Signed-off-by: Patrick Zheng <[email protected]>
  • Loading branch information
Two-Hearts authored Nov 29, 2022
1 parent 236efca commit 86287b5
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 162 deletions.
10 changes: 9 additions & 1 deletion cmd/notation/cert/generateTest.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,15 @@ func generateTestCert(opts *certGenerateTestOpts) error {
fmt.Println("generated certificate expiring on", rsaCertTuple.Cert.NotAfter.Format(time.RFC3339))

// write private key
keyPath, certPath := dir.Path.Localkey(name)
relativeKeyPath, relativeCertPath := dir.LocalKeyPath(name)
keyPath, err := dir.ConfigFS().SysPath(relativeKeyPath)
if err != nil {
return err
}
certPath, err := dir.ConfigFS().SysPath(relativeCertPath)
if err != nil {
return err
}
if err := osutil.WriteFileWithPermission(keyPath, keyBytes, 0600, false); err != nil {
return fmt.Errorf("failed to write key file: %v", err)
}
Expand Down
12 changes: 6 additions & 6 deletions cmd/notation/cert/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"

"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/verification"
notationgoTruststore "github.com/notaryproject/notation-go/verifier/truststore"
"github.com/notaryproject/notation/cmd/notation/internal/truststore"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -38,7 +38,7 @@ func listCerts(opts *certListOpts) error {
// List all certificates under truststore/x509, display empty if there's
// no certificate yet
if namedStore == "" && storeType == "" {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509")
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509")
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
Expand All @@ -52,7 +52,7 @@ func listCerts(opts *certListOpts) error {
// List all certificates under truststore/x509/storeType/namedStore,
// display empty if there's no such certificate
if namedStore != "" && storeType != "" {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType, namedStore)
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType, namedStore)
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
Expand All @@ -66,7 +66,7 @@ func listCerts(opts *certListOpts) error {
// List all certificates under x509/storeType, display empty if
// there's no certificate yet
if storeType != "" {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType)
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType)
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
Expand All @@ -76,8 +76,8 @@ func listCerts(opts *certListOpts) error {
} else {
// List all certificates under named store namedStore, display empty if
// there's no such certificate
for _, t := range verification.TrustStorePrefixes {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", string(t), namedStore)
for _, t := range notationgoTruststore.Types {
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", string(t), namedStore)
if err := truststore.CheckNonErrNotExistError(err); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/notation/cert/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func showCerts(opts *certShowOpts) error {
return errors.New("certificate fileName cannot be empty")
}

path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType, namedStore, cert)
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType, namedStore, cert)
if err != nil {
return fmt.Errorf("failed to show details of certificate %s, with error: %s", cert, err.Error())
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/notation/internal/truststore/truststore.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

corex509 "github.com/notaryproject/notation-core-go/x509"
"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/verification"
"github.com/notaryproject/notation-go/verifier/truststore"
"github.com/notaryproject/notation/cmd/notation/internal/cmdutil"
"github.com/notaryproject/notation/internal/osutil"
)
Expand Down Expand Up @@ -44,7 +44,7 @@ func AddCert(path, storeType, namedStore string, display bool) error {

// core process
// get the trust store path
trustStorePath, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType, namedStore)
trustStorePath, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType, namedStore)
if err := CheckNonErrNotExistError(err); err != nil {
return err
}
Expand Down Expand Up @@ -119,7 +119,7 @@ func showCert(cert *x509.Certificate) {
// DeleteAllCerts deletes all certificate files from the trust store
// under dir truststore/x509/storeType/namedStore
func DeleteAllCerts(storeType, namedStore string, confirmed bool, errorSlice []error) []error {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType, namedStore)
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType, namedStore)
if err == nil {
prompt := fmt.Sprintf("Are you sure you want to delete all certificate in %q of type %q?", namedStore, storeType)
confirmed, err := cmdutil.AskForConfirmation(os.Stdin, prompt, confirmed)
Expand Down Expand Up @@ -147,7 +147,7 @@ func DeleteAllCerts(storeType, namedStore string, confirmed bool, errorSlice []e
// DeleteCert deletes a specific certificate file from the
// trust store, namely truststore/x509/storeType/namedStore/cert
func DeleteCert(storeType, namedStore, cert string, confirmed bool, errorSlice []error) []error {
path, err := dir.Path.UserConfigFS.GetPath(dir.TrustStoreDir, "x509", storeType, namedStore, cert)
path, err := dir.ConfigFS().SysPath(dir.TrustStoreDir, "x509", storeType, namedStore, cert)
if err == nil {
prompt := fmt.Sprintf("Are you sure you want to delete %q in %q of type %q?", cert, namedStore, storeType)
confirmed, err := cmdutil.AskForConfirmation(os.Stdin, prompt, confirmed)
Expand Down Expand Up @@ -183,7 +183,7 @@ func CheckNonErrNotExistError(err error) error {

// IsValidStoreType checks if storeType is supported
func IsValidStoreType(storeType string) bool {
for _, t := range verification.TrustStorePrefixes {
for _, t := range truststore.Types {
if storeType == string(t) {
return true
}
Expand Down
11 changes: 5 additions & 6 deletions cmd/notation/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"os"

"github.com/notaryproject/notation-go/config"
"github.com/notaryproject/notation-go/plugin/manager"
"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/plugin"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/ioutil"
"github.com/notaryproject/notation/internal/slices"
Expand Down Expand Up @@ -186,14 +187,12 @@ func addExternalKey(ctx context.Context, opts *keyAddOpts, pluginName, keyName s
if id == "" {
return config.KeySuite{}, errors.New("missing key id")
}
mgr := manager.New()
p, err := mgr.Get(ctx, pluginName)
mgr := plugin.NewCLIManager(dir.PluginFS())
// Check existence of plugin with name pluginName
_, err := mgr.Get(ctx, pluginName)
if err != nil {
return config.KeySuite{}, err
}
if p.Err != nil {
return config.KeySuite{}, fmt.Errorf("invalid plugin: %w", p.Err)
}
pluginConfig, err := cmd.ParseFlagPluginConfig(opts.pluginConfig)
if err != nil {
return config.KeySuite{}, err
Expand Down
25 changes: 12 additions & 13 deletions cmd/notation/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import (
"fmt"

notationRegistry "github.com/notaryproject/notation-go/registry"
notationregistry "github.com/notaryproject/notation-go/registry"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
artifactspec "github.com/oras-project/artifacts-spec/specs-go/v1"
"github.com/spf13/cobra"
"oras.land/oras-go/v2/registry"
)
Expand Down Expand Up @@ -61,12 +59,9 @@ func runList(command *cobra.Command, opts *listOpts) error {
return printSignatureManifestDigests(command.Context(), manifestDesc.Digest, sigRepo, reference)
}

// printSignatureManifestDigests returns the signature manifest digest of
// printSignatureManifestDigests returns the signature manifest digests of
// the subject manifest.
//
// TODO: this is a temporary function and will be replaced after
// notation-go refactor.
func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Digest, sigRepo *notationregistry.RepositoryClient, reference string) error {
func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Digest, sigRepo notationRegistry.Repository, reference string) error {
// prepare title
ref, err := registry.ParseReference(reference)
if err != nil {
Expand All @@ -83,22 +78,26 @@ func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Di
}

// traverse referrers
artifactDescriptor, err := sigRepo.Resolve(ctx, reference)
if err != nil {
return err
}
var prevDigest digest.Digest
if err := sigRepo.Repository.Referrers(ctx, ocispec.Descriptor{
Digest: manifestDigest,
}, notationRegistry.ArtifactTypeNotation, func(referrers []artifactspec.Descriptor) error {
for _, desc := range referrers {
err = sigRepo.ListSignatures(ctx, artifactDescriptor, func(signatureManifests []ocispec.Descriptor) error {
for _, sigManifestDesc := range signatureManifests {
if prevDigest != "" {
// check and print title
printTitle()

// print each signature digest
fmt.Printf(" ├── %s\n", prevDigest)
}
prevDigest = desc.Digest
prevDigest = sigManifestDesc.Digest
}
return nil
}); err != nil {
})

if err != nil {
return err
}

Expand Down
12 changes: 6 additions & 6 deletions cmd/notation/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ import (
"context"
"errors"

"github.com/notaryproject/notation-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2/registry"
)

func getManifestDescriptorFromContext(ctx context.Context, opts *SecureFlagOpts, ref string) (notation.Descriptor, error) {
func getManifestDescriptorFromContext(ctx context.Context, opts *SecureFlagOpts, ref string) (ocispec.Descriptor, error) {
if ref == "" {
return notation.Descriptor{}, errors.New("missing reference")
return ocispec.Descriptor{}, errors.New("missing reference")
}

return getManifestDescriptorFromReference(ctx, opts, ref)
}

func getManifestDescriptorFromReference(ctx context.Context, opts *SecureFlagOpts, reference string) (notation.Descriptor, error) {
func getManifestDescriptorFromReference(ctx context.Context, opts *SecureFlagOpts, reference string) (ocispec.Descriptor, error) {
ref, err := registry.ParseReference(reference)
if err != nil {
return notation.Descriptor{}, err
return ocispec.Descriptor{}, err
}
repo, err := getRepositoryClient(opts, ref)
if err != nil {
return notation.Descriptor{}, err
return ocispec.Descriptor{}, err
}
return repo.Resolve(ctx, ref.ReferenceOrDefault())
}
16 changes: 12 additions & 4 deletions cmd/notation/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package main
import (
"os"

"github.com/notaryproject/notation-go/plugin/manager"
"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/plugin"
"github.com/notaryproject/notation/internal/ioutil"
"github.com/spf13/cobra"
)
Expand All @@ -29,10 +30,17 @@ func pluginListCommand() *cobra.Command {
}

func listPlugins(command *cobra.Command) error {
mgr := manager.New()
plugins, err := mgr.List(command.Context())
mgr := plugin.NewCLIManager(dir.PluginFS())
pluginNames, err := mgr.List(command.Context())
if err != nil {
return err
}
return ioutil.PrintPlugins(os.Stdout, plugins)
var plugins []plugin.Plugin
var errors []error
for _, n := range pluginNames {
pl, err := mgr.Get(command.Context(), n)
errors = append(errors, err)
plugins = append(plugins, pl)
}
return ioutil.PrintPlugins(command.Context(), os.Stdout, plugins, errors)
}
12 changes: 9 additions & 3 deletions cmd/notation/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"oras.land/oras-go/v2/registry/remote/auth"
)

func getSignatureRepository(opts *SecureFlagOpts, reference string) (*notationregistry.RepositoryClient, error) {
func getSignatureRepository(opts *SecureFlagOpts, reference string) (notationregistry.Repository, error) {
ref, err := registry.ParseReference(reference)
if err != nil {
return nil, err
Expand All @@ -35,12 +35,18 @@ func getRegistryClient(opts *SecureFlagOpts, serverAddress string) (*remote.Regi
return reg, nil
}

func getRepositoryClient(opts *SecureFlagOpts, ref registry.Reference) (*notationregistry.RepositoryClient, error) {
func getRepositoryClient(opts *SecureFlagOpts, ref registry.Reference) (notationregistry.Repository, error) {
authClient, plainHTTP, err := getAuthClient(opts, ref)
if err != nil {
return nil, err
}
return notationregistry.NewRepositoryClient(authClient, ref, plainHTTP), nil
repo := &remote.Repository{
Client: authClient,
Reference: ref,
PlainHTTP: plainHTTP,
}

return notationregistry.NewRepository(repo), nil
}

func getAuthClient(opts *SecureFlagOpts, ref registry.Reference) (*auth.Client, bool, error) {
Expand Down
57 changes: 17 additions & 40 deletions cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/envelope"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -74,61 +75,37 @@ func runSign(command *cobra.Command, cmdOpts *signOpts) error {
if err != nil {
return err
}
sig, err := signer.Sign(command.Context(), desc, opts)
sigRepo, err := getSignatureRepository(&cmdOpts.SecureFlagOpts, cmdOpts.reference)
if err != nil {
return err
}

// write out
ref := cmdOpts.reference
if _, err := pushSignature(command.Context(), &cmdOpts.SecureFlagOpts, ref, sig); err != nil {
return fmt.Errorf("fail to push signature to %q: %v: %v",
ref,
desc.Digest,
err,
)
_, err = notation.Sign(command.Context(), signer, sigRepo, opts)
if err != nil {
return err
}

// write out
fmt.Println(desc.Digest)
return nil
}

func prepareSigningContent(ctx context.Context, opts *signOpts) (notation.Descriptor, notation.SignOptions, error) {
func prepareSigningContent(ctx context.Context, opts *signOpts) (ocispec.Descriptor, notation.SignOptions, error) {
manifestDesc, err := getManifestDescriptorFromContext(ctx, &opts.SecureFlagOpts, opts.reference)
if err != nil {
return notation.Descriptor{}, notation.SignOptions{}, err
return ocispec.Descriptor{}, notation.SignOptions{}, err
}
mediaType, err := envelope.GetEnvelopeMediaType(opts.SignerFlagOpts.SignatureFormat)
if err != nil {
return ocispec.Descriptor{}, notation.SignOptions{}, err
}
pluginConfig, err := cmd.ParseFlagPluginConfig(opts.pluginConfig)
if err != nil {
return notation.Descriptor{}, notation.SignOptions{}, err
return ocispec.Descriptor{}, notation.SignOptions{}, err
}
return manifestDesc, notation.SignOptions{
Expiry: cmd.GetExpiry(opts.expiry),
PluginConfig: pluginConfig,
ArtifactReference: opts.reference,
SignatureMediaType: mediaType,
Expiry: cmd.GetExpiry(opts.expiry),
PluginConfig: pluginConfig,
}, nil
}

func pushSignature(ctx context.Context, opts *SecureFlagOpts, ref string, sig []byte) (notation.Descriptor, error) {
// initialize
sigRepo, err := getSignatureRepository(opts, ref)
if err != nil {
return notation.Descriptor{}, err
}
manifestDesc, err := getManifestDescriptorFromReference(ctx, opts, ref)
if err != nil {
return notation.Descriptor{}, err
}

// core process
// pass in nonempty annotations if needed
sigMediaType, err := envelope.SpeculateSignatureEnvelopeFormat(sig)
if err != nil {
return notation.Descriptor{}, err
}
sigDesc, _, err := sigRepo.PutSignatureManifest(ctx, sig, sigMediaType, manifestDesc, make(map[string]string))
if err != nil {
return notation.Descriptor{}, fmt.Errorf("put signature manifest failure: %v", err)
}

return sigDesc, nil
}
Loading

0 comments on commit 86287b5

Please sign in to comment.