diff --git a/cli/command/cli.go b/cli/command/cli.go index 1452e1a240..dfb4fba69a 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -25,7 +25,6 @@ import ( manifeststore "github.com/docker/cli/cli/manifest/store" registryclient "github.com/docker/cli/cli/registry/client" "github.com/docker/cli/cli/streams" - "github.com/docker/cli/cli/trust" "github.com/docker/cli/cli/version" dopts "github.com/docker/cli/opts" "github.com/docker/docker/api" @@ -36,7 +35,6 @@ import ( "github.com/docker/go-connections/tlsconfig" "github.com/pkg/errors" "github.com/spf13/cobra" - notaryclient "github.com/theupdateframework/notary/client" ) const defaultInitTimeout = 2 * time.Second @@ -56,7 +54,6 @@ type Cli interface { Apply(ops ...CLIOption) error ConfigFile() *configfile.ConfigFile ServerInfo() ServerInfo - NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) DefaultVersion() string CurrentVersion() string ManifestStore() manifeststore.Store @@ -67,6 +64,7 @@ type Cli interface { CurrentContext() string DockerEndpoint() docker.Endpoint TelemetryClient + DeprecatedNotaryClient } // DockerCli is an instance the docker command line client. @@ -405,11 +403,6 @@ func (cli *DockerCli) initializeFromClient() { cli.client.NegotiateAPIVersionPing(ping) } -// NotaryClient provides a Notary Repository to interact with signed metadata for an image -func (cli *DockerCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) { - return trust.GetNotaryRepository(cli.In(), cli.Out(), UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), actions...) -} - // ContextStore returns the ContextStore func (cli *DockerCli) ContextStore() store.Store { return cli.contextStore diff --git a/cli/command/cli_deprecated.go b/cli/command/cli_deprecated.go new file mode 100644 index 0000000000..d179f42f22 --- /dev/null +++ b/cli/command/cli_deprecated.go @@ -0,0 +1,18 @@ +package command + +import ( + "github.com/docker/cli/cli/trust" + notaryclient "github.com/theupdateframework/notary/client" +) + +type DeprecatedNotaryClient interface { + // NotaryClient provides a Notary Repository to interact with signed metadata for an image + // + // Deprecated: use [trust.GetNotaryRepository] instead. This method is no longer used and will be removed in the next release. + NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) +} + +// NotaryClient provides a Notary Repository to interact with signed metadata for an image +func (cli *DockerCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) { + return trust.GetNotaryRepository(cli.In(), cli.Out(), UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), actions...) +} diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go index c47e174737..89d6e54eae 100644 --- a/cli/command/image/trust.go +++ b/cli/command/image/trust.go @@ -30,6 +30,20 @@ type target struct { size int64 } +// notaryClientProvider is used in tests to provide a dummy notary client. +type notaryClientProvider interface { + NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) +} + +// newNotaryClient provides a Notary Repository to interact with signed metadata for an image. +func newNotaryClient(cli command.Streams, imgRefAndAuth trust.ImageRefAndAuth) (client.Repository, error) { + if ncp, ok := cli.(notaryClientProvider); ok { + // notaryClientProvider is used in tests to provide a dummy notary client. + return ncp.NotaryClient(imgRefAndAuth, []string{"pull"}) + } + return trust.GetNotaryRepository(cli.In(), cli.Out(), command.UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), "pull") +} + // TrustedPush handles content trust pushing of an image func TrustedPush(ctx context.Context, cli command.Cli, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig registrytypes.AuthConfig, options image.PushOptions) error { responseBody, err := cli.Client().ImagePush(ctx, reference.FamiliarString(ref), options) @@ -200,7 +214,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image } func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) ([]target, error) { - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly) + notaryRepo, err := newNotaryClient(cli, imgRefAndAuth) if err != nil { return nil, errors.Wrap(err, "error establishing connection to trust repository") } @@ -280,7 +294,7 @@ func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedT return nil, err } - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, []string{"pull"}) + notaryRepo, err := newNotaryClient(cli, imgRefAndAuth) if err != nil { return nil, errors.Wrap(err, "error establishing connection to trust repository") } diff --git a/cli/command/trust/common.go b/cli/command/trust/common.go index 1248bb487e..7d1d50e296 100644 --- a/cli/command/trust/common.go +++ b/cli/command/trust/common.go @@ -49,6 +49,20 @@ type trustKey struct { ID string `json:",omitempty"` } +// notaryClientProvider is used in tests to provide a dummy notary client. +type notaryClientProvider interface { + NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) +} + +// newNotaryClient provides a Notary Repository to interact with signed metadata for an image. +func newNotaryClient(cli command.Streams, imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { + if ncp, ok := cli.(notaryClientProvider); ok { + // notaryClientProvider is used in tests to provide a dummy notary client. + return ncp.NotaryClient(imgRefAndAuth, actions) + } + return trust.GetNotaryRepository(cli.In(), cli.Out(), command.UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), actions...) +} + // lookupTrustInfo returns processed signature and role information about a notary repository. // This information is to be pretty printed or serialized into a machine-readable format. func lookupTrustInfo(ctx context.Context, cli command.Cli, remote string) ([]trustTagRow, []client.RoleWithSignatures, []data.Role, error) { @@ -57,7 +71,7 @@ func lookupTrustInfo(ctx context.Context, cli command.Cli, remote string) ([]tru return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, err } tag := imgRefAndAuth.Tag() - notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly) + notaryRepo, err := newNotaryClient(cli, imgRefAndAuth, trust.ActionsPullOnly) if err != nil { return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } diff --git a/cli/command/trust/revoke.go b/cli/command/trust/revoke.go index a30d6cccc6..7d1651679e 100644 --- a/cli/command/trust/revoke.go +++ b/cli/command/trust/revoke.go @@ -53,7 +53,7 @@ func revokeTrust(ctx context.Context, dockerCLI command.Cli, remote string, opti } } - notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return err } diff --git a/cli/command/trust/sign.go b/cli/command/trust/sign.go index bf974d0dc0..1875e257b5 100644 --- a/cli/command/trust/sign.go +++ b/cli/command/trust/sign.go @@ -52,7 +52,7 @@ func runSignImage(ctx context.Context, dockerCLI command.Cli, options signOption return err } - notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } diff --git a/cli/command/trust/signer_add.go b/cli/command/trust/signer_add.go index 1593a591ad..9822df3d17 100644 --- a/cli/command/trust/signer_add.go +++ b/cli/command/trust/signer_add.go @@ -85,7 +85,7 @@ func addSignerToRepo(ctx context.Context, dockerCLI command.Cli, signerName stri return err } - notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return trust.NotaryError(imgRefAndAuth.Reference().Name(), err) } diff --git a/cli/command/trust/signer_remove.go b/cli/command/trust/signer_remove.go index d2c5e9c711..ff6a29d5c5 100644 --- a/cli/command/trust/signer_remove.go +++ b/cli/command/trust/signer_remove.go @@ -103,7 +103,7 @@ func removeSingleSigner(ctx context.Context, dockerCLI command.Cli, repoName, si if signerDelegation == releasesRoleTUFName { return false, errors.Errorf("releases is a reserved keyword and cannot be removed") } - notaryRepo, err := dockerCLI.NotaryClient(imgRefAndAuth, trust.ActionsPushAndPull) + notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull) if err != nil { return false, trust.NotaryError(imgRefAndAuth.Reference().Name(), err) }