cli/command: internalize constructing Notary client

The CLI.NotaryClient method is a shallow wrapper around trust.GetNotaryRepository
and only depends on the CLI itself to pass its StdErr/StrOut streams.

- This patch inlines the code to produce the client, skipping the wrapper.
- Define a local interface for some tests where a dummy notary client was used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-03-04 17:40:06 +01:00
parent 539f6de682
commit 2793731977
6 changed files with 35 additions and 7 deletions
+16 -2
View File
@@ -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")
}
+15 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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
}
+1 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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)
}