mirror of https://github.com/docker/cli.git
tests: address review feedback
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
parent
f667bd7559
commit
6fca400f1e
|
@ -1,108 +0,0 @@
|
|||
package trust
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/docker/client"
|
||||
notaryclient "github.com/docker/notary/client"
|
||||
)
|
||||
|
||||
type notaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
||||
|
||||
// FakeCli emulates the default DockerCli
|
||||
type FakeCli struct {
|
||||
command.DockerCli
|
||||
client client.APIClient
|
||||
configfile *configfile.ConfigFile
|
||||
out *command.OutStream
|
||||
outBuffer *bytes.Buffer
|
||||
err *bytes.Buffer
|
||||
in *command.InStream
|
||||
server command.ServerInfo
|
||||
notaryClientFunc notaryClientFuncType
|
||||
}
|
||||
|
||||
// NewFakeCliWithNotaryClient returns a fake for the command.Cli interface with a specified Notary Client
|
||||
func NewFakeCliWithNotaryClient(client client.APIClient, notaryClientFunc notaryClientFuncType) *FakeCli {
|
||||
outBuffer := new(bytes.Buffer)
|
||||
errBuffer := new(bytes.Buffer)
|
||||
return &FakeCli{
|
||||
client: client,
|
||||
out: command.NewOutStream(outBuffer),
|
||||
outBuffer: outBuffer,
|
||||
err: errBuffer,
|
||||
in: command.NewInStream(ioutil.NopCloser(strings.NewReader(""))),
|
||||
configfile: configfile.New("configfile"),
|
||||
notaryClientFunc: notaryClientFunc,
|
||||
}
|
||||
}
|
||||
|
||||
// SetIn sets the input of the cli to the specified ReadCloser
|
||||
func (c *FakeCli) SetIn(in *command.InStream) {
|
||||
c.in = in
|
||||
}
|
||||
|
||||
// SetErr sets the stderr stream for the cli to the specified io.Writer
|
||||
func (c *FakeCli) SetErr(err *bytes.Buffer) {
|
||||
c.err = err
|
||||
}
|
||||
|
||||
// SetConfigFile sets the "fake" config file
|
||||
func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) {
|
||||
c.configfile = configfile
|
||||
}
|
||||
|
||||
// Client returns a docker API client
|
||||
func (c *FakeCli) Client() client.APIClient {
|
||||
return c.client
|
||||
}
|
||||
|
||||
// Out returns the output stream (stdout) the cli should write on
|
||||
func (c *FakeCli) Out() *command.OutStream {
|
||||
return c.out
|
||||
}
|
||||
|
||||
// Err returns the output stream (stderr) the cli should write on
|
||||
func (c *FakeCli) Err() io.Writer {
|
||||
return c.err
|
||||
}
|
||||
|
||||
// In returns the input stream the cli will use
|
||||
func (c *FakeCli) In() *command.InStream {
|
||||
return c.in
|
||||
}
|
||||
|
||||
// ConfigFile returns the cli configfile object (to get client configuration)
|
||||
func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
|
||||
return c.configfile
|
||||
}
|
||||
|
||||
// ServerInfo returns API server information for the server used by this client
|
||||
func (c *FakeCli) ServerInfo() command.ServerInfo {
|
||||
return c.server
|
||||
}
|
||||
|
||||
// OutBuffer returns the stdout buffer
|
||||
func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
||||
return c.outBuffer
|
||||
}
|
||||
|
||||
// ErrBuffer Buffer returns the stderr buffer
|
||||
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
|
||||
return c.err
|
||||
}
|
||||
|
||||
// NotaryClient returns an err for testing unless defined
|
||||
func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
|
||||
if c.notaryClientFunc != nil {
|
||||
return c.notaryClientFunc(imgRefAndAuth, actions)
|
||||
}
|
||||
return nil, fmt.Errorf("no notary client available unless defined")
|
||||
}
|
|
@ -0,0 +1,393 @@
|
|||
package trust
|
||||
|
||||
import (
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/notary/client"
|
||||
"github.com/docker/notary/client/changelist"
|
||||
"github.com/docker/notary/cryptoservice"
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/docker/notary/storage"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
)
|
||||
|
||||
// Sample mock CLI interfaces
|
||||
|
||||
func getOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return OfflineNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// OfflineNotaryRepository is a mock Notary repository that is offline
|
||||
type OfflineNotaryRepository struct{}
|
||||
|
||||
func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
func (o OfflineNotaryRepository) Publish() error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetChangelist() (changelist.Changelist, error) {
|
||||
return changelist.NewMemChangelist(), nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) SetLegacyVersions(version int) {}
|
||||
|
||||
func (o OfflineNotaryRepository) GetGUN() data.GUN {
|
||||
return data.GUN("gun")
|
||||
}
|
||||
|
||||
func getUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return UninitializedNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// UninitializedNotaryRepository is a mock Notary repository that is uninintialized
|
||||
// it builds on top of the OfflineNotaryRepository, instead returning ErrRepositoryNotExist
|
||||
// for any online operation
|
||||
type UninitializedNotaryRepository struct {
|
||||
OfflineNotaryRepository
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
func (u UninitializedNotaryRepository) Publish() error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func getEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return EmptyTargetsNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// EmptyTargetsNotaryRepository is a mock Notary repository that is initialized
|
||||
// but does not have any signed targets
|
||||
type EmptyTargetsNotaryRepository struct {
|
||||
OfflineNotaryRepository
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (e EmptyTargetsNotaryRepository) Publish() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return []*client.TargetWithRole{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return []client.RoleWithSignatures{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return []data.Role{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return LoadedNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// LoadedNotaryRepository is a mock Notary repository that is loaded with targets, delegations, and keys
|
||||
type LoadedNotaryRepository struct {
|
||||
EmptyTargetsNotaryRepository
|
||||
statefulCryptoService signed.CryptoService
|
||||
}
|
||||
|
||||
// LoadedNotaryRepository has three delegations:
|
||||
// - targets/releases: includes keys A and B
|
||||
// - targets/alice: includes key A
|
||||
// - targets/bob: includes key B
|
||||
var loadedReleasesRole = data.DelegationRole{
|
||||
BaseRole: data.BaseRole{
|
||||
Name: "targets/releases",
|
||||
Keys: map[string]data.PublicKey{"A": nil, "B": nil},
|
||||
Threshold: 1,
|
||||
},
|
||||
}
|
||||
var loadedAliceRole = data.DelegationRole{
|
||||
BaseRole: data.BaseRole{
|
||||
Name: "targets/alice",
|
||||
Keys: map[string]data.PublicKey{"A": nil},
|
||||
Threshold: 1,
|
||||
},
|
||||
}
|
||||
var loadedBobRole = data.DelegationRole{
|
||||
BaseRole: data.BaseRole{
|
||||
Name: "targets/bob",
|
||||
Keys: map[string]data.PublicKey{"B": nil},
|
||||
Threshold: 1,
|
||||
},
|
||||
}
|
||||
var loadedDelegationRoles = []data.Role{
|
||||
{
|
||||
Name: loadedReleasesRole.Name,
|
||||
RootRole: data.RootRole{
|
||||
KeyIDs: []string{"A", "B"},
|
||||
Threshold: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: loadedAliceRole.Name,
|
||||
RootRole: data.RootRole{
|
||||
KeyIDs: []string{"A"},
|
||||
Threshold: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: loadedBobRole.Name,
|
||||
RootRole: data.RootRole{
|
||||
KeyIDs: []string{"B"},
|
||||
Threshold: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
var loadedTargetsRole = data.DelegationRole{
|
||||
BaseRole: data.BaseRole{
|
||||
Name: data.CanonicalTargetsRole,
|
||||
Keys: map[string]data.PublicKey{"C": nil},
|
||||
Threshold: 1,
|
||||
},
|
||||
}
|
||||
|
||||
// LoadedNotaryRepository has three targets:
|
||||
// - red: signed by targets/releases, targets/alice, targets/bob
|
||||
// - blue: signed by targets/releases, targets/alice
|
||||
// - green: signed by targets/releases
|
||||
var loadedRedTarget = client.Target{
|
||||
Name: "red",
|
||||
Hashes: data.Hashes{"sha256": []byte("red-digest")},
|
||||
}
|
||||
var loadedBlueTarget = client.Target{
|
||||
Name: "blue",
|
||||
Hashes: data.Hashes{"sha256": []byte("blue-digest")},
|
||||
}
|
||||
var loadedGreenTarget = client.Target{
|
||||
Name: "green",
|
||||
Hashes: data.Hashes{"sha256": []byte("green-digest")},
|
||||
}
|
||||
var loadedTargets = []client.TargetSignedStruct{
|
||||
// red is signed by all three delegations
|
||||
{Target: loadedRedTarget, Role: loadedReleasesRole},
|
||||
{Target: loadedRedTarget, Role: loadedAliceRole},
|
||||
{Target: loadedRedTarget, Role: loadedBobRole},
|
||||
|
||||
// blue is signed by targets/releases, targets/alice
|
||||
{Target: loadedBlueTarget, Role: loadedReleasesRole},
|
||||
{Target: loadedBlueTarget, Role: loadedAliceRole},
|
||||
|
||||
// green is signed by targets/releases
|
||||
{Target: loadedGreenTarget, Role: loadedReleasesRole},
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
filteredTargets := []*client.TargetWithRole{}
|
||||
for _, tgt := range loadedTargets {
|
||||
if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) {
|
||||
filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name})
|
||||
}
|
||||
}
|
||||
return filteredTargets, nil
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
for _, tgt := range loadedTargets {
|
||||
if name == tgt.Target.Name {
|
||||
if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) {
|
||||
return &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
if name == "" {
|
||||
return loadedTargets, nil
|
||||
}
|
||||
filteredTargets := []client.TargetSignedStruct{}
|
||||
for _, tgt := range loadedTargets {
|
||||
if name == tgt.Target.Name {
|
||||
filteredTargets = append(filteredTargets, tgt)
|
||||
}
|
||||
}
|
||||
if len(filteredTargets) == 0 {
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
return filteredTargets, nil
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) GetGUN() data.GUN {
|
||||
return data.GUN("signed-repo")
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return loadedDelegationRoles, nil
|
||||
}
|
||||
|
||||
func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||
if l.statefulCryptoService == nil {
|
||||
// give it an in-memory cryptoservice with a root key and targets key
|
||||
l.statefulCryptoService = cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("password")))
|
||||
l.statefulCryptoService.AddKey(data.CanonicalRootRole, l.GetGUN(), nil)
|
||||
l.statefulCryptoService.AddKey(data.CanonicalTargetsRole, l.GetGUN(), nil)
|
||||
}
|
||||
return l.statefulCryptoService
|
||||
}
|
||||
|
||||
func getLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return LoadedWithNoSignersNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// LoadedWithNoSignersNotaryRepository is a mock Notary repository that is loaded with targets but no delegations
|
||||
// it only contains the green target
|
||||
type LoadedWithNoSignersNotaryRepository struct {
|
||||
LoadedNotaryRepository
|
||||
}
|
||||
|
||||
func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
filteredTargets := []*client.TargetWithRole{}
|
||||
for _, tgt := range loadedTargets {
|
||||
if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) {
|
||||
filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name})
|
||||
}
|
||||
}
|
||||
return filteredTargets, nil
|
||||
}
|
||||
|
||||
func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
if name == "" || name == loadedGreenTarget.Name {
|
||||
return &client.TargetWithRole{Target: loadedGreenTarget, Role: data.CanonicalTargetsRole}, nil
|
||||
}
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
if name == "" || name == loadedGreenTarget.Name {
|
||||
return []client.TargetSignedStruct{{Target: loadedGreenTarget, Role: loadedTargetsRole}}, nil
|
||||
}
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (l LoadedWithNoSignersNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return []data.Role{}, nil
|
||||
}
|
|
@ -11,10 +11,7 @@ import (
|
|||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/docker/notary"
|
||||
"github.com/docker/notary/client"
|
||||
"github.com/docker/notary/client/changelist"
|
||||
"github.com/docker/notary/storage"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -58,13 +55,15 @@ func TestTrustInspectCommandErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustInspectCommandOfflineErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd = newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -72,13 +71,15 @@ func TestTrustInspectCommandOfflineErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getUninitializedNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"reg/unsigned-img"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getUninitializedNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
||||
cmd = newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -86,7 +87,8 @@ func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustInspectCommandEmptyNotaryRepoErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getEmptyTargetsNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -94,7 +96,8 @@ func TestTrustInspectCommandEmptyNotaryRepoErrors(t *testing.T) {
|
|||
assert.Contains(t, cli.OutBuffer().String(), "No signatures for reg/img:unsigned-tag")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for reg/img:")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getEmptyTargetsNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd = newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"reg/img"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -105,8 +108,9 @@ func TestTrustInspectCommandEmptyNotaryRepoErrors(t *testing.T) {
|
|||
|
||||
func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"alpine"})
|
||||
cmd.SetArgs([]string{"signed-repo"})
|
||||
assert.NoError(t, cmd.Execute())
|
||||
|
||||
// Check for the signed tag headers
|
||||
|
@ -114,7 +118,7 @@ func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
|||
assert.Contains(t, cli.OutBuffer().String(), "DIGEST")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNERS")
|
||||
// Check for the signer headers
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for alpine:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "(Repo Admin)")
|
||||
// no delegations on this repo
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "List of signers and their keys:")
|
||||
|
@ -122,66 +126,70 @@ func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
|||
|
||||
func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"alpine:3.5"})
|
||||
cmd.SetArgs([]string{"signed-repo:green"})
|
||||
assert.NoError(t, cmd.Execute())
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNED TAG")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "DIGEST")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNERS")
|
||||
// Check for the signer headers
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for alpine:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:")
|
||||
// make sure the tag isn't included
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "Administrative keys for alpine:3.5")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "3.5")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:green")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "green")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "(Repo Admin)")
|
||||
// no delegations on this repo
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "3.6")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "alice")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "bob")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "List of signers and their keys:")
|
||||
}
|
||||
|
||||
func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"dockerorcadev/trust-fixture"})
|
||||
cmd.SetArgs([]string{"signed-repo"})
|
||||
assert.NoError(t, cmd.Execute())
|
||||
|
||||
// Check for the signed tag headers
|
||||
// Check for the signed tag headers and contents
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNED TAG")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "DIGEST")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNERS")
|
||||
// Check for the signer headers
|
||||
assert.Contains(t, cli.OutBuffer().String(), "blue 626c75652d646967657374 alice")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "green 677265656e2d646967657374 (Repo Admin)")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "red 7265642d646967657374 alice, bob")
|
||||
|
||||
// Check for the signer headers and contents
|
||||
assert.Contains(t, cli.OutBuffer().String(), "List of signers and their keys:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNER")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "KEYS")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for dockerorcadev/trust-fixture:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Repository Key")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Root Key")
|
||||
// all signers have names
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "(Repo Admin)")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "alice A")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "bob B")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:")
|
||||
}
|
||||
|
||||
func TestTrustInspectCommandUnsignedTagInSignedRepo(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
||||
cmd := newInspectCommand(cli)
|
||||
cmd.SetArgs([]string{"dockerorcadev/trust-fixture:unsigned"})
|
||||
cmd.SetArgs([]string{"signed-repo:unsigned"})
|
||||
assert.NoError(t, cmd.Execute())
|
||||
|
||||
// Check that the signatures table does not show up, and instead we get the message
|
||||
assert.Contains(t, cli.OutBuffer().String(), "No signatures for dockerorcadev/trust-fixture:unsigned")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "No signatures for signed-repo:unsigned")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "SIGNED TAG")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "DIGEST")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "SIGNERS")
|
||||
// Check for the signer headers
|
||||
|
||||
// Check for the signer headers and contents
|
||||
assert.Contains(t, cli.OutBuffer().String(), "List of signers and their keys:")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "SIGNER")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "KEYS")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for dockerorcadev/trust-fixture:")
|
||||
// make sure the tag isn't included
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "Administrative keys for dockerorcadev/trust-fixture:unsigned")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Repository Key")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Root Key")
|
||||
// all signers have names
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "(Repo Admin)")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "alice A")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "bob B")
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:")
|
||||
assert.NotContains(t, cli.OutBuffer().String(), "Administrative keys for signed-repo:unsigned")
|
||||
}
|
||||
|
||||
func TestNotaryRoleToSigner(t *testing.T) {
|
||||
|
@ -468,194 +476,3 @@ func TestFormatAdminRole(t *testing.T) {
|
|||
targetsRoleWithSigs := client.RoleWithSignatures{Role: targetsRole, Signatures: nil}
|
||||
assert.Equal(t, "Repository Key:\tabc, key11, key99\n", formatAdminRole(targetsRoleWithSigs))
|
||||
}
|
||||
|
||||
// Sample mock CLI interfaces
|
||||
|
||||
func getOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return OfflineNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// OfflineNotaryRepository is a mock Notary repository that is offline
|
||||
type OfflineNotaryRepository struct{}
|
||||
|
||||
func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
func (o OfflineNotaryRepository) Publish() error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetChangelist() (changelist.Changelist, error) {
|
||||
return changelist.NewMemChangelist(), nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return nil, storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return storage.ErrOffline{}
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o OfflineNotaryRepository) SetLegacyVersions(version int) {}
|
||||
|
||||
func (o OfflineNotaryRepository) GetGUN() data.GUN {
|
||||
return data.GUN("gun")
|
||||
}
|
||||
|
||||
func getUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return UninitializedNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// UninitializedNotaryRepository is a mock Notary repository that is uninintialized
|
||||
// it builds on top of the OfflineNotaryRepository, instead returning ErrRepoNotInitialized
|
||||
// for any online operation
|
||||
type UninitializedNotaryRepository struct {
|
||||
OfflineNotaryRepository
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
func (u UninitializedNotaryRepository) Publish() error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return nil, client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return client.ErrRepositoryNotExist{}
|
||||
}
|
||||
|
||||
func getEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||
return EmptyTargetsNotaryRepository{}, nil
|
||||
}
|
||||
|
||||
// EmptyTargetsNotaryRepository is a mock Notary repository that is initialized
|
||||
// but does not have any signed targets
|
||||
type EmptyTargetsNotaryRepository struct {
|
||||
OfflineNotaryRepository
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||
return nil
|
||||
}
|
||||
func (e EmptyTargetsNotaryRepository) Publish() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||
return []*client.TargetWithRole{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||
return nil, client.ErrNoSuchTarget(name)
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||
return []client.RoleWithSignatures{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||
return []data.Role{}, nil
|
||||
}
|
||||
|
||||
func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -38,11 +38,6 @@ func TestTrustRevokeCommandErrors(t *testing.T) {
|
|||
args: []string{"ALPINE"},
|
||||
expectedError: "invalid reference format",
|
||||
},
|
||||
// {
|
||||
// name: "no-signing-keys-for-image",
|
||||
// args: []string{"alpine", "-y"},
|
||||
// expectedError: "could not remove signature for alpine: could not find necessary signing keys",
|
||||
// },
|
||||
{
|
||||
name: "digest-reference",
|
||||
args: []string{"ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2"},
|
||||
|
@ -59,20 +54,23 @@ func TestTrustRevokeCommandErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd := newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
assert.NoError(t, cmd.Execute())
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action.")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
testutil.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: client is offline")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -80,20 +78,23 @@ func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getUninitializedNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
||||
cmd := newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
assert.NoError(t, cmd.Execute())
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action.")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getUninitializedNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
testutil.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: does not have trust data for")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getUninitializedNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -101,21 +102,24 @@ func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getEmptyTargetsNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd := newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
assert.NoError(t, cmd.Execute())
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action.")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getEmptyTargetsNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
assert.NoError(t, cmd.Execute())
|
||||
assert.Contains(t, cli.OutBuffer().String(), "Successfully deleted signature for reg-name.io/image")
|
||||
|
||||
cli = NewFakeCliWithNotaryClient(&fakeClient{}, getEmptyTargetsNotaryRepository)
|
||||
cli = test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd = newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
@ -125,6 +129,7 @@ func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
|||
|
||||
func TestNewRevokeTrustAllSigConfirmation(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
||||
cmd := newRevokeCommand(cli)
|
||||
cmd.SetArgs([]string{"alpine"})
|
||||
assert.NoError(t, cmd.Execute())
|
||||
|
|
|
@ -41,11 +41,6 @@ func TestTrustSignCommandErrors(t *testing.T) {
|
|||
args: []string{"870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"},
|
||||
expectedError: "invalid repository name",
|
||||
},
|
||||
{
|
||||
name: "nonexistent-reg",
|
||||
args: []string{"nonexistent-reg-name.io/image:tag"},
|
||||
expectedError: "no such host",
|
||||
},
|
||||
{
|
||||
name: "invalid-img-reference",
|
||||
args: []string{"ALPINE:latest"},
|
||||
|
@ -77,7 +72,8 @@ func TestTrustSignCommandErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTrustSignCommandOfflineErrors(t *testing.T) {
|
||||
cli := NewFakeCliWithNotaryClient(&fakeClient{}, getOfflineNotaryRepository)
|
||||
cli := test.NewFakeCli(&fakeClient{})
|
||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
||||
cmd := newSignCommand(cli)
|
||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
|
|
|
@ -2,15 +2,20 @@ package test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/docker/client"
|
||||
notaryclient "github.com/docker/notary/client"
|
||||
)
|
||||
|
||||
type notaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
||||
|
||||
// FakeCli emulates the default DockerCli
|
||||
type FakeCli struct {
|
||||
command.DockerCli
|
||||
|
@ -21,6 +26,7 @@ type FakeCli struct {
|
|||
err *bytes.Buffer
|
||||
in *command.InStream
|
||||
server command.ServerInfo
|
||||
notaryClientFunc notaryClientFuncType
|
||||
}
|
||||
|
||||
// NewFakeCli returns a fake for the command.Cli interface
|
||||
|
@ -91,3 +97,16 @@ func (c *FakeCli) OutBuffer() *bytes.Buffer {
|
|||
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
|
||||
return c.err
|
||||
}
|
||||
|
||||
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
||||
func (c *FakeCli) SetNotaryClient(notaryClientFunc notaryClientFuncType) {
|
||||
c.notaryClientFunc = notaryClientFunc
|
||||
}
|
||||
|
||||
// NotaryClient returns an err for testing unless defined
|
||||
func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
|
||||
if c.notaryClientFunc != nil {
|
||||
return c.notaryClientFunc(imgRefAndAuth, actions)
|
||||
}
|
||||
return nil, fmt.Errorf("no notary client available unless defined")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue