mirror of https://github.com/docker/cli.git
Merge pull request #929 from vdemeester/trust-no-global-var
Refactor content_trust cli/flags handling
This commit is contained in:
commit
240c03a7f8
|
@ -52,6 +52,7 @@ type Cli interface {
|
||||||
DefaultVersion() string
|
DefaultVersion() string
|
||||||
ManifestStore() manifeststore.Store
|
ManifestStore() manifeststore.Store
|
||||||
RegistryClient(bool) registryclient.RegistryClient
|
RegistryClient(bool) registryclient.RegistryClient
|
||||||
|
ContentTrustEnabled() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// DockerCli is an instance the docker command line client.
|
// DockerCli is an instance the docker command line client.
|
||||||
|
@ -64,6 +65,7 @@ type DockerCli struct {
|
||||||
client client.APIClient
|
client client.APIClient
|
||||||
serverInfo ServerInfo
|
serverInfo ServerInfo
|
||||||
clientInfo ClientInfo
|
clientInfo ClientInfo
|
||||||
|
contentTrust bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultVersion returns api.defaultVersion or DOCKER_API_VERSION if specified.
|
// DefaultVersion returns api.defaultVersion or DOCKER_API_VERSION if specified.
|
||||||
|
@ -121,6 +123,12 @@ func (cli *DockerCli) ClientInfo() ClientInfo {
|
||||||
return cli.clientInfo
|
return cli.clientInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContentTrustEnabled returns if content trust has been enabled by an
|
||||||
|
// environment variable.
|
||||||
|
func (cli *DockerCli) ContentTrustEnabled() bool {
|
||||||
|
return cli.contentTrust
|
||||||
|
}
|
||||||
|
|
||||||
// ManifestStore returns a store for local manifests
|
// ManifestStore returns a store for local manifests
|
||||||
func (cli *DockerCli) ManifestStore() manifeststore.Store {
|
func (cli *DockerCli) ManifestStore() manifeststore.Store {
|
||||||
// TODO: support override default location from config file
|
// TODO: support override default location from config file
|
||||||
|
@ -237,8 +245,8 @@ func (c ClientInfo) HasKubernetes() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
|
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
|
||||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer) *DockerCli {
|
func NewDockerCli(in io.ReadCloser, out, err io.Writer, isTrusted bool) *DockerCli {
|
||||||
return &DockerCli{in: NewInStream(in), out: NewOutStream(out), err: err}
|
return &DockerCli{in: NewInStream(in), out: NewOutStream(out), err: err, contentTrust: isTrusted}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPIClientFromFlags creates a new APIClient from command line flags
|
// NewAPIClientFromFlags creates a new APIClient from command line flags
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
type createOptions struct {
|
type createOptions struct {
|
||||||
name string
|
name string
|
||||||
platform string
|
platform string
|
||||||
|
untrusted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCreateCommand creates a new cobra.Command for `docker create`
|
// NewCreateCommand creates a new cobra.Command for `docker create`
|
||||||
|
@ -53,7 +54,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.Bool("help", false, "Print usage")
|
flags.Bool("help", false, "Print usage")
|
||||||
|
|
||||||
command.AddPlatformFlag(flags, &opts.platform)
|
command.AddPlatformFlag(flags, &opts.platform)
|
||||||
command.AddTrustVerificationFlags(flags)
|
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
copts = addFlags(flags)
|
copts = addFlags(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
|
||||||
reportError(dockerCli.Err(), "create", err.Error(), true)
|
reportError(dockerCli.Err(), "create", err.Error(), true)
|
||||||
return cli.StatusError{StatusCode: 125}
|
return cli.StatusError{StatusCode: 125}
|
||||||
}
|
}
|
||||||
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name, opts.platform)
|
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -158,7 +159,7 @@ func newCIDFile(path string) (*cidFile, error) {
|
||||||
return &cidFile{path: path, file: f}, nil
|
return &cidFile{path: path, file: f}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string, platform string) (*container.ContainerCreateCreatedBody, error) {
|
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, opts *createOptions) (*container.ContainerCreateCreatedBody, error) {
|
||||||
config := containerConfig.Config
|
config := containerConfig.Config
|
||||||
hostConfig := containerConfig.HostConfig
|
hostConfig := containerConfig.HostConfig
|
||||||
networkingConfig := containerConfig.NetworkingConfig
|
networkingConfig := containerConfig.NetworkingConfig
|
||||||
|
@ -182,7 +183,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
|
||||||
if named, ok := ref.(reference.Named); ok {
|
if named, ok := ref.(reference.Named); ok {
|
||||||
namedRef = reference.TagNameOnly(named)
|
namedRef = reference.TagNameOnly(named)
|
||||||
|
|
||||||
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && command.IsTrusted() {
|
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !opts.untrusted {
|
||||||
var err error
|
var err error
|
||||||
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef, nil)
|
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -193,7 +194,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
//create the container
|
//create the container
|
||||||
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
|
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, opts.name)
|
||||||
|
|
||||||
//if image not found try to pull it
|
//if image not found try to pull it
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -201,7 +202,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
|
||||||
fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
|
fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
|
||||||
|
|
||||||
// we don't want to write to stdout anything apart from container.ID
|
// we don't want to write to stdout anything apart from container.ID
|
||||||
if err := pullImage(ctx, dockerCli, config.Image, platform, stderr); err != nil {
|
if err := pullImage(ctx, dockerCli, config.Image, opts.platform, stderr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
|
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
|
||||||
|
@ -211,7 +212,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
|
||||||
}
|
}
|
||||||
// Retry
|
// Retry
|
||||||
var retryErr error
|
var retryErr error
|
||||||
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
|
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, opts.name)
|
||||||
if retryErr != nil {
|
if retryErr != nil {
|
||||||
return nil, retryErr
|
return nil, retryErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,11 @@ func TestCreateContainerPullsImageIfMissing(t *testing.T) {
|
||||||
},
|
},
|
||||||
HostConfig: &container.HostConfig{},
|
HostConfig: &container.HostConfig{},
|
||||||
}
|
}
|
||||||
body, err := createContainer(context.Background(), cli, config, "name", runtime.GOOS)
|
body, err := createContainer(context.Background(), cli, config, &createOptions{
|
||||||
|
name: "name",
|
||||||
|
platform: runtime.GOOS,
|
||||||
|
untrusted: true,
|
||||||
|
})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
expected := container.ContainerCreateCreatedBody{ID: containerID}
|
expected := container.ContainerCreateCreatedBody{ID: containerID}
|
||||||
assert.Check(t, is.DeepEqual(expected, *body))
|
assert.Check(t, is.DeepEqual(expected, *body))
|
||||||
|
|
|
@ -25,11 +25,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type runOptions struct {
|
type runOptions struct {
|
||||||
|
createOptions
|
||||||
detach bool
|
detach bool
|
||||||
sigProxy bool
|
sigProxy bool
|
||||||
name string
|
|
||||||
detachKeys string
|
detachKeys string
|
||||||
platform string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRunCommand create a new `docker run` command
|
// NewRunCommand create a new `docker run` command
|
||||||
|
@ -64,7 +63,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.Bool("help", false, "Print usage")
|
flags.Bool("help", false, "Print usage")
|
||||||
|
|
||||||
command.AddPlatformFlag(flags, &opts.platform)
|
command.AddPlatformFlag(flags, &opts.platform)
|
||||||
command.AddTrustVerificationFlags(flags)
|
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
copts = addFlags(flags)
|
copts = addFlags(flags)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -162,7 +161,7 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
|
||||||
|
|
||||||
ctx, cancelFun := context.WithCancel(context.Background())
|
ctx, cancelFun := context.WithCancel(context.Background())
|
||||||
|
|
||||||
createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name, opts.platform)
|
createResponse, err := createContainer(ctx, dockerCli, containerConfig, &opts.createOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reportError(stderr, cmdPath, err.Error(), true)
|
reportError(stderr, cmdPath, err.Error(), true)
|
||||||
return runStartContainerErr(err)
|
return runStartContainerErr(err)
|
||||||
|
|
|
@ -67,6 +67,7 @@ type buildOptions struct {
|
||||||
imageIDFile string
|
imageIDFile string
|
||||||
stream bool
|
stream bool
|
||||||
platform string
|
platform string
|
||||||
|
untrusted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// dockerfileFromStdin returns true when the user specified that the Dockerfile
|
// dockerfileFromStdin returns true when the user specified that the Dockerfile
|
||||||
|
@ -137,7 +138,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.StringVar(&options.target, "target", "", "Set the target build stage to build.")
|
flags.StringVar(&options.target, "target", "", "Set the target build stage to build.")
|
||||||
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
|
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
|
||||||
|
|
||||||
command.AddTrustVerificationFlags(flags)
|
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
command.AddPlatformFlag(flags, &options.platform)
|
command.AddPlatformFlag(flags, &options.platform)
|
||||||
|
|
||||||
flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
|
flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
|
||||||
|
@ -285,7 +286,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
var resolvedTags []*resolvedTag
|
var resolvedTags []*resolvedTag
|
||||||
if command.IsTrusted() {
|
if !options.untrusted {
|
||||||
translator := func(ctx context.Context, ref reference.NamedTagged) (reference.Canonical, error) {
|
translator := func(ctx context.Context, ref reference.NamedTagged) (reference.Canonical, error) {
|
||||||
return TrustedReference(ctx, dockerCli, ref, nil)
|
return TrustedReference(ctx, dockerCli, ref, nil)
|
||||||
}
|
}
|
||||||
|
@ -293,10 +294,10 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
||||||
if buildCtx != nil {
|
if buildCtx != nil {
|
||||||
// Wrap the tar archive to replace the Dockerfile entry with the rewritten
|
// Wrap the tar archive to replace the Dockerfile entry with the rewritten
|
||||||
// Dockerfile which uses trusted pulls.
|
// Dockerfile which uses trusted pulls.
|
||||||
buildCtx = replaceDockerfileTarWrapper(ctx, buildCtx, relDockerfile, translator, &resolvedTags)
|
buildCtx = replaceDockerfileForContentTrust(ctx, buildCtx, relDockerfile, translator, &resolvedTags)
|
||||||
} else if dockerfileCtx != nil {
|
} else if dockerfileCtx != nil {
|
||||||
// if there was not archive context still do the possible replacements in Dockerfile
|
// if there was not archive context still do the possible replacements in Dockerfile
|
||||||
newDockerfile, _, err := rewriteDockerfileFrom(ctx, dockerfileCtx, translator)
|
newDockerfile, _, err := rewriteDockerfileFrom(ctx, dockerfileCtx, translator, !options.untrusted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -460,7 +461,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if command.IsTrusted() {
|
if !options.untrusted {
|
||||||
// Since the build was successful, now we must tag any of the resolved
|
// Since the build was successful, now we must tag any of the resolved
|
||||||
// images from the above Dockerfile rewrite.
|
// images from the above Dockerfile rewrite.
|
||||||
for _, resolved := range resolvedTags {
|
for _, resolved := range resolvedTags {
|
||||||
|
@ -503,7 +504,7 @@ type resolvedTag struct {
|
||||||
// "FROM <image>" instructions to a digest reference. `translator` is a
|
// "FROM <image>" instructions to a digest reference. `translator` is a
|
||||||
// function that takes a repository name and tag reference and returns a
|
// function that takes a repository name and tag reference and returns a
|
||||||
// trusted digest reference.
|
// trusted digest reference.
|
||||||
func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator translatorFunc) (newDockerfile []byte, resolvedTags []*resolvedTag, err error) {
|
func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator translatorFunc, istrusted bool) (newDockerfile []byte, resolvedTags []*resolvedTag, err error) {
|
||||||
scanner := bufio.NewScanner(dockerfile)
|
scanner := bufio.NewScanner(dockerfile)
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
|
@ -520,7 +521,7 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
ref = reference.TagNameOnly(ref)
|
ref = reference.TagNameOnly(ref)
|
||||||
if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
|
if ref, ok := ref.(reference.NamedTagged); ok && istrusted {
|
||||||
trustedRef, err := translator(ctx, ref)
|
trustedRef, err := translator(ctx, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -543,11 +544,10 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator
|
||||||
return buf.Bytes(), resolvedTags, scanner.Err()
|
return buf.Bytes(), resolvedTags, scanner.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaceDockerfileTarWrapper wraps the given input tar archive stream and
|
// replaceDockerfileForContentTrust wraps the given input tar archive stream and
|
||||||
// replaces the entry with the given Dockerfile name with the contents of the
|
// uses the translator to replace the Dockerfile which uses a trusted reference.
|
||||||
// new Dockerfile. Returns a new tar archive stream with the replaced
|
// Returns a new tar archive stream with the replaced Dockerfile.
|
||||||
// Dockerfile.
|
func replaceDockerfileForContentTrust(ctx context.Context, inputTarStream io.ReadCloser, dockerfileName string, translator translatorFunc, resolvedTags *[]*resolvedTag) io.ReadCloser {
|
||||||
func replaceDockerfileTarWrapper(ctx context.Context, inputTarStream io.ReadCloser, dockerfileName string, translator translatorFunc, resolvedTags *[]*resolvedTag) io.ReadCloser {
|
|
||||||
pipeReader, pipeWriter := io.Pipe()
|
pipeReader, pipeWriter := io.Pipe()
|
||||||
go func() {
|
go func() {
|
||||||
tarReader := tar.NewReader(inputTarStream)
|
tarReader := tar.NewReader(inputTarStream)
|
||||||
|
@ -574,7 +574,7 @@ func replaceDockerfileTarWrapper(ctx context.Context, inputTarStream io.ReadClos
|
||||||
// generated from a directory on the local filesystem, the
|
// generated from a directory on the local filesystem, the
|
||||||
// Dockerfile will only appear once in the archive.
|
// Dockerfile will only appear once in the archive.
|
||||||
var newDockerfile []byte
|
var newDockerfile []byte
|
||||||
newDockerfile, *resolvedTags, err = rewriteDockerfileFrom(ctx, content, translator)
|
newDockerfile, *resolvedTags, err = rewriteDockerfileFrom(ctx, content, translator, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pipeWriter.CloseWithError(err)
|
pipeWriter.CloseWithError(err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -107,6 +107,7 @@ COPY data /data
|
||||||
options := newBuildOptions()
|
options := newBuildOptions()
|
||||||
options.context = dir.Path()
|
options.context = dir.Path()
|
||||||
options.dockerfileName = df.Path()
|
options.dockerfileName = df.Path()
|
||||||
|
options.untrusted = true
|
||||||
|
|
||||||
err = runBuild(cli, options)
|
err = runBuild(cli, options)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -17,6 +17,7 @@ type pullOptions struct {
|
||||||
remote string
|
remote string
|
||||||
all bool
|
all bool
|
||||||
platform string
|
platform string
|
||||||
|
untrusted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPullCommand creates a new `docker pull` command
|
// NewPullCommand creates a new `docker pull` command
|
||||||
|
@ -38,7 +39,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
|
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
|
||||||
|
|
||||||
command.AddPlatformFlag(flags, &opts.platform)
|
command.AddPlatformFlag(flags, &opts.platform)
|
||||||
command.AddTrustVerificationFlags(flags)
|
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ func runPull(cli command.Cli, opts pullOptions) error {
|
||||||
|
|
||||||
// Check if reference has a digest
|
// Check if reference has a digest
|
||||||
_, isCanonical := distributionRef.(reference.Canonical)
|
_, isCanonical := distributionRef.(reference.Canonical)
|
||||||
if command.IsTrusted() && !isCanonical {
|
if !opts.untrusted && !isCanonical {
|
||||||
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
|
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
|
||||||
} else {
|
} else {
|
||||||
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
|
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
"github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
|
@ -77,3 +78,44 @@ func TestNewPullCommandSuccess(t *testing.T) {
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("pull-command-success.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("pull-command-success.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewPullCommandWithContentTrustErrors(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectedError string
|
||||||
|
notaryFunc test.NotaryClientFuncType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "offline-notary-server",
|
||||||
|
notaryFunc: notary.GetOfflineNotaryRepository,
|
||||||
|
expectedError: "client is offline",
|
||||||
|
args: []string{"image:tag"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty-notary-server",
|
||||||
|
notaryFunc: notary.GetUninitializedNotaryRepository,
|
||||||
|
expectedError: "remote trust data does not exist",
|
||||||
|
args: []string{"image:tag"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty-notary-server",
|
||||||
|
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
|
||||||
|
expectedError: "No valid trust data for tag",
|
||||||
|
args: []string{"image:tag"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
|
imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
|
||||||
|
return ioutil.NopCloser(strings.NewReader("")), fmt.Errorf("shouldn't try to pull image")
|
||||||
|
},
|
||||||
|
}, test.EnableContentTrust)
|
||||||
|
cli.SetNotaryClient(tc.notaryFunc)
|
||||||
|
cmd := NewPullCommand(cli)
|
||||||
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
cmd.SetArgs(tc.args)
|
||||||
|
err := cmd.Execute()
|
||||||
|
assert.ErrorContains(t, err, tc.expectedError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,26 +11,34 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type pushOptions struct {
|
||||||
|
remote string
|
||||||
|
untrusted bool
|
||||||
|
}
|
||||||
|
|
||||||
// NewPushCommand creates a new `docker push` command
|
// NewPushCommand creates a new `docker push` command
|
||||||
func NewPushCommand(dockerCli command.Cli) *cobra.Command {
|
func NewPushCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
|
var opts pushOptions
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "push [OPTIONS] NAME[:TAG]",
|
Use: "push [OPTIONS] NAME[:TAG]",
|
||||||
Short: "Push an image or a repository to a registry",
|
Short: "Push an image or a repository to a registry",
|
||||||
Args: cli.ExactArgs(1),
|
Args: cli.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runPush(dockerCli, args[0])
|
opts.remote = args[0]
|
||||||
|
return runPush(dockerCli, opts)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
command.AddTrustSigningFlags(flags)
|
command.AddTrustSigningFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPush(dockerCli command.Cli, remote string) error {
|
func runPush(dockerCli command.Cli, opts pushOptions) error {
|
||||||
ref, err := reference.ParseNormalizedNamed(remote)
|
ref, err := reference.ParseNormalizedNamed(opts.remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -47,7 +55,7 @@ func runPush(dockerCli command.Cli, remote string) error {
|
||||||
authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
|
authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
|
||||||
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "push")
|
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "push")
|
||||||
|
|
||||||
if command.IsTrusted() {
|
if !opts.untrusted {
|
||||||
return TrustedPush(ctx, dockerCli, repoInfo, ref, authConfig, requestPrivilege)
|
return TrustedPush(ctx, dockerCli, repoInfo, ref, authConfig, requestPrivilege)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,6 @@ func TestNewPushCommandErrors(t *testing.T) {
|
||||||
return ioutil.NopCloser(strings.NewReader("")), errors.Errorf("Failed to push")
|
return ioutil.NopCloser(strings.NewReader("")), errors.Errorf("Failed to push")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "trust-error",
|
|
||||||
args: []string{"--disable-content-trust=false", "image:repo"},
|
|
||||||
expectedError: "you are not authorized to perform this operation: server returned 401.",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc})
|
cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc})
|
||||||
|
|
|
@ -24,11 +24,12 @@ type pluginOptions struct {
|
||||||
disable bool
|
disable bool
|
||||||
args []string
|
args []string
|
||||||
skipRemoteCheck bool
|
skipRemoteCheck bool
|
||||||
|
untrusted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadPullFlags(opts *pluginOptions, flags *pflag.FlagSet) {
|
func loadPullFlags(dockerCli command.Cli, opts *pluginOptions, flags *pflag.FlagSet) {
|
||||||
flags.BoolVar(&opts.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin")
|
flags.BoolVar(&opts.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin")
|
||||||
command.AddTrustVerificationFlags(flags)
|
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInstallCommand(dockerCli command.Cli) *cobra.Command {
|
func newInstallCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
|
@ -47,7 +48,7 @@ func newInstallCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
loadPullFlags(&options, flags)
|
loadPullFlags(dockerCli, &options, flags)
|
||||||
flags.BoolVar(&options.disable, "disable", false, "Do not enable the plugin on install")
|
flags.BoolVar(&options.disable, "disable", false, "Do not enable the plugin on install")
|
||||||
flags.StringVar(&options.localName, "alias", "", "Local name for plugin")
|
flags.StringVar(&options.localName, "alias", "", "Local name for plugin")
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -90,7 +91,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti
|
||||||
remote := ref.String()
|
remote := ref.String()
|
||||||
|
|
||||||
_, isCanonical := ref.(reference.Canonical)
|
_, isCanonical := ref.(reference.Canonical)
|
||||||
if command.IsTrusted() && !isCanonical {
|
if !opts.untrusted && !isCanonical {
|
||||||
ref = reference.TagNameOnly(ref)
|
ref = reference.TagNameOnly(ref)
|
||||||
nt, ok := ref.(reference.NamedTagged)
|
nt, ok := ref.(reference.NamedTagged)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -13,30 +13,37 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type pushOptions struct {
|
||||||
|
name string
|
||||||
|
untrusted bool
|
||||||
|
}
|
||||||
|
|
||||||
func newPushCommand(dockerCli command.Cli) *cobra.Command {
|
func newPushCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
|
var opts pushOptions
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "push [OPTIONS] PLUGIN[:TAG]",
|
Use: "push [OPTIONS] PLUGIN[:TAG]",
|
||||||
Short: "Push a plugin to a registry",
|
Short: "Push a plugin to a registry",
|
||||||
Args: cli.ExactArgs(1),
|
Args: cli.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runPush(dockerCli, args[0])
|
opts.name = args[0]
|
||||||
|
return runPush(dockerCli, opts)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
command.AddTrustSigningFlags(flags)
|
command.AddTrustSigningFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPush(dockerCli command.Cli, name string) error {
|
func runPush(dockerCli command.Cli, opts pushOptions) error {
|
||||||
named, err := reference.ParseNormalizedNamed(name)
|
named, err := reference.ParseNormalizedNamed(opts.name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, ok := named.(reference.Canonical); ok {
|
if _, ok := named.(reference.Canonical); ok {
|
||||||
return errors.Errorf("invalid name: %s", name)
|
return errors.Errorf("invalid name: %s", opts.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
named = reference.TagNameOnly(named)
|
named = reference.TagNameOnly(named)
|
||||||
|
@ -60,7 +67,7 @@ func runPush(dockerCli command.Cli, name string) error {
|
||||||
}
|
}
|
||||||
defer responseBody.Close()
|
defer responseBody.Close()
|
||||||
|
|
||||||
if command.IsTrusted() {
|
if !opts.untrusted {
|
||||||
repoInfo.Class = "plugin"
|
repoInfo.Class = "plugin"
|
||||||
return image.PushTrustedReference(dockerCli, repoInfo, named, authConfig, responseBody)
|
return image.PushTrustedReference(dockerCli, repoInfo, named, authConfig, responseBody)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ func newUpgradeCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
loadPullFlags(&options, flags)
|
loadPullFlags(dockerCli, &options, flags)
|
||||||
flags.BoolVar(&options.skipRemoteCheck, "skip-remote-check", false, "Do not check if specified remote plugin matches existing plugin image")
|
flags.BoolVar(&options.skipRemoteCheck, "skip-remote-check", false, "Do not check if specified remote plugin matches existing plugin image")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func resolveServiceImageDigestContentTrust(dockerCli command.Cli, service *swarm.ServiceSpec) error {
|
func resolveServiceImageDigestContentTrust(dockerCli command.Cli, service *swarm.ServiceSpec) error {
|
||||||
if !command.IsTrusted() {
|
if !dockerCli.ContentTrustEnabled() {
|
||||||
// When not using content trust, digest resolution happens later when
|
// When not using content trust, digest resolution happens later when
|
||||||
// contacting the registry to retrieve image information.
|
// contacting the registry to retrieve image information.
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,47 +1,15 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// TODO: make this not global
|
|
||||||
untrusted bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
untrusted = !getDefaultTrustState()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddTrustVerificationFlags adds content trust flags to the provided flagset
|
// AddTrustVerificationFlags adds content trust flags to the provided flagset
|
||||||
func AddTrustVerificationFlags(fs *pflag.FlagSet) {
|
func AddTrustVerificationFlags(fs *pflag.FlagSet, v *bool, trusted bool) {
|
||||||
trusted := getDefaultTrustState()
|
fs.BoolVar(v, "disable-content-trust", !trusted, "Skip image verification")
|
||||||
fs.BoolVar(&untrusted, "disable-content-trust", !trusted, "Skip image verification")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTrustSigningFlags adds "signing" flags to the provided flagset
|
// AddTrustSigningFlags adds "signing" flags to the provided flagset
|
||||||
func AddTrustSigningFlags(fs *pflag.FlagSet) {
|
func AddTrustSigningFlags(fs *pflag.FlagSet, v *bool, trusted bool) {
|
||||||
trusted := getDefaultTrustState()
|
fs.BoolVar(v, "disable-content-trust", !trusted, "Skip image signing")
|
||||||
fs.BoolVar(&untrusted, "disable-content-trust", !trusted, "Skip image signing")
|
|
||||||
}
|
|
||||||
|
|
||||||
// getDefaultTrustState returns true if content trust is enabled through the $DOCKER_CONTENT_TRUST environment variable.
|
|
||||||
func getDefaultTrustState() bool {
|
|
||||||
var trusted bool
|
|
||||||
if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
|
|
||||||
if t, err := strconv.ParseBool(e); t || err != nil {
|
|
||||||
// treat any other value as true
|
|
||||||
trusted = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trusted
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTrusted returns true if content trust is enabled, either through the $DOCKER_CONTENT_TRUST environment variable,
|
|
||||||
// or through `--disabled-content-trust=false` on a command.
|
|
||||||
func IsTrusted() bool {
|
|
||||||
return !untrusted
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
"github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
"github.com/gotestyourself/gotestyourself/golden"
|
"github.com/gotestyourself/gotestyourself/golden"
|
||||||
)
|
)
|
||||||
|
@ -46,14 +47,14 @@ func TestTrustInspectCommandErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandOfflineErrors(t *testing.T) {
|
func TestTrustInspectCommandOfflineErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notary.GetOfflineNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
|
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
|
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notary.GetOfflineNotaryRepository)
|
||||||
cmd = newInspectCommand(cli)
|
cmd = newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -62,7 +63,7 @@ func TestTrustInspectCommandOfflineErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notary.GetUninitializedNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/unsigned-img"})
|
cmd.SetArgs([]string{"reg/unsigned-img"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -70,7 +71,7 @@ func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-uninitialized.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-uninitialized.golden")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notary.GetUninitializedNotaryRepository)
|
||||||
cmd = newInspectCommand(cli)
|
cmd = newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
|
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -80,7 +81,7 @@ func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandEmptyNotaryRepo(t *testing.T) {
|
func TestTrustInspectCommandEmptyNotaryRepo(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notary.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
|
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -90,7 +91,7 @@ func TestTrustInspectCommandEmptyNotaryRepo(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
cli.SetNotaryClient(notary.GetLoadedWithNoSignersNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo"})
|
cmd.SetArgs([]string{"signed-repo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -99,7 +100,7 @@ func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
|
func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
cli.SetNotaryClient(notary.GetLoadedWithNoSignersNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo:green"})
|
cmd.SetArgs([]string{"signed-repo:green"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -108,7 +109,7 @@ func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
|
func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notary.GetLoadedNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo"})
|
cmd.SetArgs([]string{"signed-repo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -117,7 +118,7 @@ func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandMultipleFullReposWithSigners(t *testing.T) {
|
func TestTrustInspectCommandMultipleFullReposWithSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notary.GetLoadedNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo", "signed-repo"})
|
cmd.SetArgs([]string{"signed-repo", "signed-repo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -126,7 +127,7 @@ func TestTrustInspectCommandMultipleFullReposWithSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustInspectCommandUnsignedTagInSignedRepo(t *testing.T) {
|
func TestTrustInspectCommandUnsignedTagInSignedRepo(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notary.GetLoadedNotaryRepository)
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo:unsigned"})
|
cmd.SetArgs([]string{"signed-repo:unsigned"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
"github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
"github.com/theupdateframework/notary/client"
|
"github.com/theupdateframework/notary/client"
|
||||||
|
@ -55,7 +56,7 @@ func TestTrustRevokeCommandErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notary.GetOfflineNotaryRepository)
|
||||||
cmd := newRevokeCommand(cli)
|
cmd := newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -63,13 +64,13 @@ func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
||||||
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notary.GetOfflineNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notary.GetOfflineNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -78,7 +79,7 @@ func TestTrustRevokeCommandOfflineErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notary.GetUninitializedNotaryRepository)
|
||||||
cmd := newRevokeCommand(cli)
|
cmd := newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -86,14 +87,14 @@ func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
||||||
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notary.GetUninitializedNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: does not have trust data for")
|
assert.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: does not have trust data for")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notary.GetUninitializedNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -102,7 +103,7 @@ func TestTrustRevokeCommandUninitializedErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notary.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newRevokeCommand(cli)
|
cmd := newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image"})
|
cmd.SetArgs([]string{"reg-name.io/image"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -110,14 +111,14 @@ func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
||||||
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] \nAborting action."))
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notary.GetEmptyTargetsNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
cmd.SetArgs([]string{"reg-name.io/image", "-y"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: no signed tags to remove")
|
assert.ErrorContains(t, cmd.Execute(), "could not remove signature for reg-name.io/image: no signed tags to remove")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notary.GetEmptyTargetsNotaryRepository)
|
||||||
cmd = newRevokeCommand(cli)
|
cmd = newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -126,7 +127,7 @@ func TestTrustRevokeCommandEmptyNotaryRepo(t *testing.T) {
|
||||||
|
|
||||||
func TestNewRevokeTrustAllSigConfirmation(t *testing.T) {
|
func TestNewRevokeTrustAllSigConfirmation(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notary.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newRevokeCommand(cli)
|
cmd := newRevokeCommand(cli)
|
||||||
cmd.SetArgs([]string{"alpine"})
|
cmd.SetArgs([]string{"alpine"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/config"
|
"github.com/docker/cli/cli/config"
|
||||||
"github.com/docker/cli/cli/trust"
|
"github.com/docker/cli/cli/trust"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
"github.com/gotestyourself/gotestyourself/skip"
|
"github.com/gotestyourself/gotestyourself/skip"
|
||||||
|
@ -76,7 +77,7 @@ func TestTrustSignCommandErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustSignCommandOfflineErrors(t *testing.T) {
|
func TestTrustSignCommandOfflineErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
|
||||||
cmd := newSignCommand(cli)
|
cmd := newSignCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -282,7 +283,7 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
|
||||||
|
|
||||||
config.SetDir(tmpDir)
|
config.SetDir(tmpDir)
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
cmd := newSignCommand(cli)
|
cmd := newSignCommand(cli)
|
||||||
cmd.SetArgs([]string{"ubuntu:latest"})
|
cmd.SetArgs([]string{"ubuntu:latest"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -299,7 +300,7 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
|
||||||
|
|
||||||
func TestSignCommandLocalFlag(t *testing.T) {
|
func TestSignCommandLocalFlag(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newSignCommand(cli)
|
cmd := newSignCommand(cli)
|
||||||
cmd.SetArgs([]string{"--local", "reg-name.io/image:red"})
|
cmd.SetArgs([]string{"--local", "reg-name.io/image:red"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/cli/config"
|
"github.com/docker/cli/cli/config"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
"github.com/theupdateframework/notary"
|
"github.com/theupdateframework/notary"
|
||||||
|
@ -58,7 +59,7 @@ func TestTrustSignerAddErrors(t *testing.T) {
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
|
||||||
cmd := newSignerAddCommand(cli)
|
cmd := newSignerAddCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -77,7 +78,7 @@ func TestSignerAddCommandNoTargetsKey(t *testing.T) {
|
||||||
defer os.Remove(tmpfile.Name())
|
defer os.Remove(tmpfile.Name())
|
||||||
|
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newSignerAddCommand(cli)
|
cmd := newSignerAddCommand(cli)
|
||||||
cmd.SetArgs([]string{"--key", tmpfile.Name(), "alice", "alpine", "linuxkit/alpine"})
|
cmd.SetArgs([]string{"--key", tmpfile.Name(), "alice", "alpine", "linuxkit/alpine"})
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ func TestSignerAddCommandBadKeyPath(t *testing.T) {
|
||||||
config.SetDir(tmpDir)
|
config.SetDir(tmpDir)
|
||||||
|
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newSignerAddCommand(cli)
|
cmd := newSignerAddCommand(cli)
|
||||||
cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"})
|
cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"})
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ func TestSignerAddCommandInvalidRepoName(t *testing.T) {
|
||||||
assert.NilError(t, ioutil.WriteFile(pubKeyFilepath, pubKeyFixture, notary.PrivNoExecPerms))
|
assert.NilError(t, ioutil.WriteFile(pubKeyFilepath, pubKeyFixture, notary.PrivNoExecPerms))
|
||||||
|
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetUninitializedNotaryRepository)
|
||||||
cmd := newSignerAddCommand(cli)
|
cmd := newSignerAddCommand(cli)
|
||||||
imageName := "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"
|
imageName := "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"
|
||||||
cmd.SetArgs([]string{"--key", pubKeyFilepath, "alice", imageName})
|
cmd.SetArgs([]string{"--key", pubKeyFilepath, "alice", imageName})
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
"github.com/theupdateframework/notary/client"
|
"github.com/theupdateframework/notary/client"
|
||||||
|
@ -57,7 +58,7 @@ func TestTrustSignerRemoveErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tc := range testCasesWithOutput {
|
for _, tc := range testCasesWithOutput {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
|
||||||
cmd := newSignerRemoveCommand(cli)
|
cmd := newSignerRemoveCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -69,7 +70,7 @@ func TestTrustSignerRemoveErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestRemoveSingleSigner(t *testing.T) {
|
func TestRemoveSingleSigner(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
err := removeSingleSigner(cli, "signed-repo", "test", true)
|
err := removeSingleSigner(cli, "signed-repo", "test", true)
|
||||||
assert.Error(t, err, "No signer test for repository signed-repo")
|
assert.Error(t, err, "No signer test for repository signed-repo")
|
||||||
err = removeSingleSigner(cli, "signed-repo", "releases", true)
|
err = removeSingleSigner(cli, "signed-repo", "releases", true)
|
||||||
|
@ -78,7 +79,7 @@ func TestRemoveSingleSigner(t *testing.T) {
|
||||||
|
|
||||||
func TestRemoveMultipleSigners(t *testing.T) {
|
func TestRemoveMultipleSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
err := removeSigner(cli, signerRemoveOptions{signer: "test", repos: []string{"signed-repo", "signed-repo"}, forceYes: true})
|
err := removeSigner(cli, signerRemoveOptions{signer: "test", repos: []string{"signed-repo", "signed-repo"}, forceYes: true})
|
||||||
assert.Error(t, err, "Error removing signer from: signed-repo, signed-repo")
|
assert.Error(t, err, "Error removing signer from: signed-repo, signed-repo")
|
||||||
assert.Check(t, is.Contains(cli.ErrBuffer().String(),
|
assert.Check(t, is.Contains(cli.ErrBuffer().String(),
|
||||||
|
@ -87,7 +88,7 @@ func TestRemoveMultipleSigners(t *testing.T) {
|
||||||
}
|
}
|
||||||
func TestRemoveLastSignerWarning(t *testing.T) {
|
func TestRemoveLastSignerWarning(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
|
|
||||||
err := removeSigner(cli, signerRemoveOptions{signer: "alice", repos: []string{"signed-repo"}, forceYes: false})
|
err := removeSigner(cli, signerRemoveOptions{signer: "alice", repos: []string{"signed-repo"}, forceYes: false})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/cli/trust"
|
"github.com/docker/cli/cli/trust"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
|
notaryfake "github.com/docker/cli/internal/test/notary"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/gotestyourself/gotestyourself/assert"
|
"github.com/gotestyourself/gotestyourself/assert"
|
||||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||||
|
@ -57,14 +58,14 @@ func TestTrustViewCommandErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandOfflineErrors(t *testing.T) {
|
func TestTrustViewCommandOfflineErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
|
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
|
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getOfflineNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
|
||||||
cmd = newViewCommand(cli)
|
cmd = newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
|
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -73,14 +74,14 @@ func TestTrustViewCommandOfflineErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandUninitializedErrors(t *testing.T) {
|
func TestTrustViewCommandUninitializedErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetUninitializedNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/unsigned-img"})
|
cmd.SetArgs([]string{"reg/unsigned-img"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img")
|
assert.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img")
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getUninitializedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetUninitializedNotaryRepository)
|
||||||
cmd = newViewCommand(cli)
|
cmd = newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
|
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -89,7 +90,7 @@ func TestTrustViewCommandUninitializedErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandEmptyNotaryRepoErrors(t *testing.T) {
|
func TestTrustViewCommandEmptyNotaryRepoErrors(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
|
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -98,7 +99,7 @@ func TestTrustViewCommandEmptyNotaryRepoErrors(t *testing.T) {
|
||||||
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img:"))
|
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img:"))
|
||||||
|
|
||||||
cli = test.NewFakeCli(&fakeClient{})
|
cli = test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
|
||||||
cmd = newViewCommand(cli)
|
cmd = newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"reg/img"})
|
cmd.SetArgs([]string{"reg/img"})
|
||||||
cmd.SetOutput(ioutil.Discard)
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
@ -109,7 +110,7 @@ func TestTrustViewCommandEmptyNotaryRepoErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandFullRepoWithoutSigners(t *testing.T) {
|
func TestTrustViewCommandFullRepoWithoutSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedWithNoSignersNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo"})
|
cmd.SetArgs([]string{"signed-repo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -119,7 +120,7 @@ func TestTrustViewCommandFullRepoWithoutSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandOneTagWithoutSigners(t *testing.T) {
|
func TestTrustViewCommandOneTagWithoutSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedWithNoSignersNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo:green"})
|
cmd.SetArgs([]string{"signed-repo:green"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -129,7 +130,7 @@ func TestTrustViewCommandOneTagWithoutSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandFullRepoWithSigners(t *testing.T) {
|
func TestTrustViewCommandFullRepoWithSigners(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo"})
|
cmd.SetArgs([]string{"signed-repo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
@ -139,7 +140,7 @@ func TestTrustViewCommandFullRepoWithSigners(t *testing.T) {
|
||||||
|
|
||||||
func TestTrustViewCommandUnsignedTagInSignedRepo(t *testing.T) {
|
func TestTrustViewCommandUnsignedTagInSignedRepo(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
cli.SetNotaryClient(getLoadedNotaryRepository)
|
cli.SetNotaryClient(notaryfake.GetLoadedNotaryRepository)
|
||||||
cmd := newViewCommand(cli)
|
cmd := newViewCommand(cli)
|
||||||
cmd.SetArgs([]string{"signed-repo:unsigned"})
|
cmd.SetArgs([]string{"signed-repo:unsigned"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -155,7 +156,7 @@ func main() {
|
||||||
stdin, stdout, stderr := term.StdStreams()
|
stdin, stdout, stderr := term.StdStreams()
|
||||||
logrus.SetOutput(stderr)
|
logrus.SetOutput(stderr)
|
||||||
|
|
||||||
dockerCli := command.NewDockerCli(stdin, stdout, stderr)
|
dockerCli := command.NewDockerCli(stdin, stdout, stderr, isContentTrustEnabled())
|
||||||
cmd := newDockerCommand(dockerCli)
|
cmd := newDockerCommand(dockerCli)
|
||||||
|
|
||||||
if err := cmd.Execute(); err != nil {
|
if err := cmd.Execute(); err != nil {
|
||||||
|
@ -175,6 +176,16 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isContentTrustEnabled() bool {
|
||||||
|
if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
|
||||||
|
if t, err := strconv.ParseBool(e); t || err != nil {
|
||||||
|
// treat any other value as true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func showVersion() {
|
func showVersion() {
|
||||||
fmt.Printf("Docker version %s, build %s\n", cli.Version, cli.GitCommit)
|
fmt.Printf("Docker version %s, build %s\n", cli.Version, cli.GitCommit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func TestClientDebugEnabled(t *testing.T) {
|
||||||
|
|
||||||
func TestExitStatusForInvalidSubcommandWithHelpFlag(t *testing.T) {
|
func TestExitStatusForInvalidSubcommandWithHelpFlag(t *testing.T) {
|
||||||
discard := ioutil.Discard
|
discard := ioutil.Discard
|
||||||
cmd := newDockerCommand(command.NewDockerCli(os.Stdin, discard, discard))
|
cmd := newDockerCommand(command.NewDockerCli(os.Stdin, discard, discard, false))
|
||||||
cmd.SetArgs([]string{"help", "invalid"})
|
cmd.SetArgs([]string{"help", "invalid"})
|
||||||
err := cmd.Execute()
|
err := cmd.Execute()
|
||||||
assert.Error(t, err, "unknown help topic: invalid")
|
assert.Error(t, err, "unknown help topic: invalid")
|
||||||
|
|
|
@ -19,7 +19,7 @@ const descriptionSourcePath = "docs/reference/commandline/"
|
||||||
|
|
||||||
func generateCliYaml(opts *options) error {
|
func generateCliYaml(opts *options) error {
|
||||||
stdin, stdout, stderr := term.StdStreams()
|
stdin, stdout, stderr := term.StdStreams()
|
||||||
dockerCli := command.NewDockerCli(stdin, stdout, stderr)
|
dockerCli := command.NewDockerCli(stdin, stdout, stderr, false)
|
||||||
cmd := &cobra.Command{Use: "docker"}
|
cmd := &cobra.Command{Use: "docker"}
|
||||||
commands.AddCommands(cmd, dockerCli)
|
commands.AddCommands(cmd, dockerCli)
|
||||||
source := filepath.Join(opts.source, descriptionSourcePath)
|
source := filepath.Join(opts.source, descriptionSourcePath)
|
||||||
|
|
|
@ -16,7 +16,8 @@ import (
|
||||||
notaryclient "github.com/theupdateframework/notary/client"
|
notaryclient "github.com/theupdateframework/notary/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type notaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
// NotaryClientFuncType defines a function that returns a fake notary client
|
||||||
|
type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
||||||
type clientInfoFuncType func() command.ClientInfo
|
type clientInfoFuncType func() command.ClientInfo
|
||||||
|
|
||||||
// FakeCli emulates the default DockerCli
|
// FakeCli emulates the default DockerCli
|
||||||
|
@ -30,16 +31,17 @@ type FakeCli struct {
|
||||||
in *command.InStream
|
in *command.InStream
|
||||||
server command.ServerInfo
|
server command.ServerInfo
|
||||||
clientInfoFunc clientInfoFuncType
|
clientInfoFunc clientInfoFuncType
|
||||||
notaryClientFunc notaryClientFuncType
|
notaryClientFunc NotaryClientFuncType
|
||||||
manifestStore manifeststore.Store
|
manifestStore manifeststore.Store
|
||||||
registryClient registryclient.RegistryClient
|
registryClient registryclient.RegistryClient
|
||||||
|
contentTrust bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFakeCli returns a fake for the command.Cli interface
|
// NewFakeCli returns a fake for the command.Cli interface
|
||||||
func NewFakeCli(client client.APIClient) *FakeCli {
|
func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli {
|
||||||
outBuffer := new(bytes.Buffer)
|
outBuffer := new(bytes.Buffer)
|
||||||
errBuffer := new(bytes.Buffer)
|
errBuffer := new(bytes.Buffer)
|
||||||
return &FakeCli{
|
c := &FakeCli{
|
||||||
client: client,
|
client: client,
|
||||||
out: command.NewOutStream(outBuffer),
|
out: command.NewOutStream(outBuffer),
|
||||||
outBuffer: outBuffer,
|
outBuffer: outBuffer,
|
||||||
|
@ -49,6 +51,10 @@ func NewFakeCli(client client.APIClient) *FakeCli {
|
||||||
// Set cli.ConfigFile().Filename to a tempfile to support Save.
|
// Set cli.ConfigFile().Filename to a tempfile to support Save.
|
||||||
configfile: configfile.New(""),
|
configfile: configfile.New(""),
|
||||||
}
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(c)
|
||||||
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetIn sets the input of the cli to the specified ReadCloser
|
// SetIn sets the input of the cli to the specified ReadCloser
|
||||||
|
@ -120,7 +126,7 @@ func (c *FakeCli) ErrBuffer() *bytes.Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
// SetNotaryClient sets the internal getter for retrieving a NotaryClient
|
||||||
func (c *FakeCli) SetNotaryClient(notaryClientFunc notaryClientFuncType) {
|
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
|
||||||
c.notaryClientFunc = notaryClientFunc
|
c.notaryClientFunc = notaryClientFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,3 +157,13 @@ func (c *FakeCli) SetManifestStore(store manifeststore.Store) {
|
||||||
func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) {
|
func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) {
|
||||||
c.registryClient = client
|
c.registryClient = client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContentTrustEnabled on the fake cli
|
||||||
|
func (c *FakeCli) ContentTrustEnabled() bool {
|
||||||
|
return c.contentTrust
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableContentTrust on the fake cli
|
||||||
|
func EnableContentTrust(c *FakeCli) {
|
||||||
|
c.contentTrust = true
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package trust
|
package notary
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/cli/cli/trust"
|
"github.com/docker/cli/cli/trust"
|
||||||
|
@ -12,107 +12,142 @@ import (
|
||||||
"github.com/theupdateframework/notary/tuf/signed"
|
"github.com/theupdateframework/notary/tuf/signed"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sample mock CLI interfaces
|
// GetOfflineNotaryRepository returns a OfflineNotaryRepository
|
||||||
|
func GetOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||||
func getOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
|
||||||
return OfflineNotaryRepository{}, nil
|
return OfflineNotaryRepository{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OfflineNotaryRepository is a mock Notary repository that is offline
|
// OfflineNotaryRepository is a mock Notary repository that is offline
|
||||||
type OfflineNotaryRepository struct{}
|
type OfflineNotaryRepository struct{}
|
||||||
|
|
||||||
|
// Initialize creates a new repository by using rootKey as the root Key for the
|
||||||
|
// TUF repository.
|
||||||
func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||||
return storage.ErrOffline{}
|
return storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeWithCertificate initializes the repository with root keys and their corresponding certificates
|
||||||
func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||||
return storage.ErrOffline{}
|
return storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Publish pushes the local changes in signed material to the remote notary-server
|
||||||
|
// Conceptually it performs an operation similar to a `git rebase`
|
||||||
func (o OfflineNotaryRepository) Publish() error {
|
func (o OfflineNotaryRepository) Publish() error {
|
||||||
return storage.ErrOffline{}
|
return storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddTarget creates new changelist entries to add a target to the given roles
|
||||||
|
// in the repository when the changelist gets applied at publish time.
|
||||||
func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error {
|
func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveTarget creates new changelist entries to remove a target from the given
|
||||||
|
// roles in the repository when the changelist gets applied at publish time.
|
||||||
func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error {
|
func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTargets lists all targets for the current repository. The list of
|
||||||
|
// roles should be passed in order from highest to lowest priority.
|
||||||
func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||||
return nil, storage.ErrOffline{}
|
return nil, storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTargetByName returns a target by the given name.
|
||||||
func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||||
return nil, storage.ErrOffline{}
|
return nil, storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||||
|
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||||
func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||||
return nil, storage.ErrOffline{}
|
return nil, storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetChangelist returns the list of the repository's unpublished changes
|
||||||
func (o OfflineNotaryRepository) GetChangelist() (changelist.Changelist, error) {
|
func (o OfflineNotaryRepository) GetChangelist() (changelist.Changelist, error) {
|
||||||
return changelist.NewMemChangelist(), nil
|
return changelist.NewMemChangelist(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||||
func (o OfflineNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
func (o OfflineNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||||
return nil, storage.ErrOffline{}
|
return nil, storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||||
func (o OfflineNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
func (o OfflineNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||||
return nil, storage.ErrOffline{}
|
return nil, storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDelegation creates changelist entries to add provided delegation public keys and paths.
|
||||||
func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error {
|
func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDelegationRoleAndKeys creates a changelist entry to add provided delegation public keys.
|
||||||
func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error {
|
func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddDelegationPaths creates a changelist entry to add provided paths to an existing delegation.
|
||||||
func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error {
|
func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDelegationKeysAndPaths creates changelist entries to remove provided delegation key IDs and paths.
|
||||||
func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
|
func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDelegationRole creates a changelist to remove all paths and keys from a role, and delete the role in its entirety.
|
||||||
func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error {
|
func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDelegationPaths creates a changelist entry to remove provided paths from an existing delegation.
|
||||||
func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error {
|
func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDelegationKeys creates a changelist entry to remove provided keys from an existing delegation.
|
||||||
func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error {
|
func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearDelegationPaths creates a changelist entry to remove all paths from an existing delegation.
|
||||||
func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error {
|
func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Witness creates change objects to witness (i.e. re-sign) the given
|
||||||
|
// roles on the next publish. One change is created per role
|
||||||
func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
|
func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RotateKey rotates a private key and returns the public component from the remote server
|
||||||
func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||||
return storage.ErrOffline{}
|
return storage.ErrOffline{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCryptoService is the getter for the repository's CryptoService
|
||||||
func (o OfflineNotaryRepository) GetCryptoService() signed.CryptoService {
|
func (o OfflineNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLegacyVersions allows the number of legacy versions of the root
|
||||||
|
// to be inspected for old signing keys to be configured.
|
||||||
func (o OfflineNotaryRepository) SetLegacyVersions(version int) {}
|
func (o OfflineNotaryRepository) SetLegacyVersions(version int) {}
|
||||||
|
|
||||||
|
// GetGUN is a getter for the GUN object from a Repository
|
||||||
func (o OfflineNotaryRepository) GetGUN() data.GUN {
|
func (o OfflineNotaryRepository) GetGUN() data.GUN {
|
||||||
return data.GUN("gun")
|
return data.GUN("gun")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
// GetUninitializedNotaryRepository returns an UninitializedNotaryRepository
|
||||||
|
func GetUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||||
return UninitializedNotaryRepository{}, nil
|
return UninitializedNotaryRepository{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,42 +158,57 @@ type UninitializedNotaryRepository struct {
|
||||||
OfflineNotaryRepository
|
OfflineNotaryRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize creates a new repository by using rootKey as the root Key for the
|
||||||
|
// TUF repository.
|
||||||
func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||||
return client.ErrRepositoryNotExist{}
|
return client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeWithCertificate initializes the repository with root keys and their corresponding certificates
|
||||||
func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||||
return client.ErrRepositoryNotExist{}
|
return client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Publish pushes the local changes in signed material to the remote notary-server
|
||||||
|
// Conceptually it performs an operation similar to a `git rebase`
|
||||||
func (u UninitializedNotaryRepository) Publish() error {
|
func (u UninitializedNotaryRepository) Publish() error {
|
||||||
return client.ErrRepositoryNotExist{}
|
return client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTargets lists all targets for the current repository. The list of
|
||||||
|
// roles should be passed in order from highest to lowest priority.
|
||||||
func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||||
return nil, client.ErrRepositoryNotExist{}
|
return nil, client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTargetByName returns a target by the given name.
|
||||||
func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||||
return nil, client.ErrRepositoryNotExist{}
|
return nil, client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||||
|
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||||
func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||||
return nil, client.ErrRepositoryNotExist{}
|
return nil, client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||||
func (u UninitializedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
func (u UninitializedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||||
return nil, client.ErrRepositoryNotExist{}
|
return nil, client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||||
func (u UninitializedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
func (u UninitializedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||||
return nil, client.ErrRepositoryNotExist{}
|
return nil, client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RotateKey rotates a private key and returns the public component from the remote server
|
||||||
func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||||
return client.ErrRepositoryNotExist{}
|
return client.ErrRepositoryNotExist{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
// GetEmptyTargetsNotaryRepository returns an EmptyTargetsNotaryRepository
|
||||||
|
func GetEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||||
return EmptyTargetsNotaryRepository{}, nil
|
return EmptyTargetsNotaryRepository{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,29 +218,41 @@ type EmptyTargetsNotaryRepository struct {
|
||||||
OfflineNotaryRepository
|
OfflineNotaryRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize creates a new repository by using rootKey as the root Key for the
|
||||||
|
// TUF repository.
|
||||||
func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeWithCertificate initializes the repository with root keys and their corresponding certificates
|
||||||
func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Publish pushes the local changes in signed material to the remote notary-server
|
||||||
|
// Conceptually it performs an operation similar to a `git rebase`
|
||||||
func (e EmptyTargetsNotaryRepository) Publish() error {
|
func (e EmptyTargetsNotaryRepository) Publish() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTargets lists all targets for the current repository. The list of
|
||||||
|
// roles should be passed in order from highest to lowest priority.
|
||||||
func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||||
return []*client.TargetWithRole{}, nil
|
return []*client.TargetWithRole{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTargetByName returns a target by the given name.
|
||||||
func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||||
return nil, client.ErrNoSuchTarget(name)
|
return nil, client.ErrNoSuchTarget(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||||
|
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||||
func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||||
return nil, client.ErrNoSuchTarget(name)
|
return nil, client.ErrNoSuchTarget(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||||
func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||||
rootRole := data.Role{
|
rootRole := data.Role{
|
||||||
RootRole: data.RootRole{
|
RootRole: data.RootRole{
|
||||||
|
@ -212,15 +274,18 @@ func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures,
|
||||||
{Role: targetsRole}}, nil
|
{Role: targetsRole}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||||
func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||||
return []data.Role{}, nil
|
return []data.Role{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RotateKey rotates a private key and returns the public component from the remote server
|
||||||
func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
// GetLoadedNotaryRepository returns a LoadedNotaryRepository
|
||||||
|
func GetLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||||
return LoadedNotaryRepository{}, nil
|
return LoadedNotaryRepository{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +381,7 @@ var loadedTargets = []client.TargetSignedStruct{
|
||||||
{Target: loadedGreenTarget, Role: loadedReleasesRole},
|
{Target: loadedGreenTarget, Role: loadedReleasesRole},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||||
func (l LoadedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
func (l LoadedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
|
||||||
rootRole := data.Role{
|
rootRole := data.Role{
|
||||||
RootRole: data.RootRole{
|
RootRole: data.RootRole{
|
||||||
|
@ -368,6 +434,8 @@ func (l LoadedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error)
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTargets lists all targets for the current repository. The list of
|
||||||
|
// roles should be passed in order from highest to lowest priority.
|
||||||
func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||||
filteredTargets := []*client.TargetWithRole{}
|
filteredTargets := []*client.TargetWithRole{}
|
||||||
for _, tgt := range loadedTargets {
|
for _, tgt := range loadedTargets {
|
||||||
|
@ -378,6 +446,7 @@ func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.T
|
||||||
return filteredTargets, nil
|
return filteredTargets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTargetByName returns a target by the given name.
|
||||||
func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||||
for _, tgt := range loadedTargets {
|
for _, tgt := range loadedTargets {
|
||||||
if name == tgt.Target.Name {
|
if name == tgt.Target.Name {
|
||||||
|
@ -389,6 +458,8 @@ func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleN
|
||||||
return nil, client.ErrNoSuchTarget(name)
|
return nil, client.ErrNoSuchTarget(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||||
|
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||||
func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return loadedTargets, nil
|
return loadedTargets, nil
|
||||||
|
@ -405,14 +476,17 @@ func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]clien
|
||||||
return filteredTargets, nil
|
return filteredTargets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetGUN is a getter for the GUN object from a Repository
|
||||||
func (l LoadedNotaryRepository) GetGUN() data.GUN {
|
func (l LoadedNotaryRepository) GetGUN() data.GUN {
|
||||||
return data.GUN("signed-repo")
|
return data.GUN("signed-repo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||||
func (l LoadedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
func (l LoadedNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||||
return loadedDelegationRoles, nil
|
return loadedDelegationRoles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCryptoService is the getter for the repository's CryptoService
|
||||||
func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService {
|
func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||||
if l.statefulCryptoService == nil {
|
if l.statefulCryptoService == nil {
|
||||||
// give it an in-memory cryptoservice with a root key and targets key
|
// give it an in-memory cryptoservice with a root key and targets key
|
||||||
|
@ -423,7 +497,8 @@ func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService {
|
||||||
return l.statefulCryptoService
|
return l.statefulCryptoService
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
// GetLoadedWithNoSignersNotaryRepository returns a LoadedWithNoSignersNotaryRepository
|
||||||
|
func GetLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) {
|
||||||
return LoadedWithNoSignersNotaryRepository{}, nil
|
return LoadedWithNoSignersNotaryRepository{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,6 +508,8 @@ type LoadedWithNoSignersNotaryRepository struct {
|
||||||
LoadedNotaryRepository
|
LoadedNotaryRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTargets lists all targets for the current repository. The list of
|
||||||
|
// roles should be passed in order from highest to lowest priority.
|
||||||
func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) {
|
||||||
filteredTargets := []*client.TargetWithRole{}
|
filteredTargets := []*client.TargetWithRole{}
|
||||||
for _, tgt := range loadedTargets {
|
for _, tgt := range loadedTargets {
|
||||||
|
@ -443,6 +520,7 @@ func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName)
|
||||||
return filteredTargets, nil
|
return filteredTargets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTargetByName returns a target by the given name.
|
||||||
func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) {
|
||||||
if name == "" || name == loadedGreenTarget.Name {
|
if name == "" || name == loadedGreenTarget.Name {
|
||||||
return &client.TargetWithRole{Target: loadedGreenTarget, Role: data.CanonicalTargetsRole}, nil
|
return &client.TargetWithRole{Target: loadedGreenTarget, Role: data.CanonicalTargetsRole}, nil
|
||||||
|
@ -450,6 +528,8 @@ func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles
|
||||||
return nil, client.ErrNoSuchTarget(name)
|
return nil, client.ErrNoSuchTarget(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||||
|
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||||
func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) {
|
||||||
if name == "" || name == loadedGreenTarget.Name {
|
if name == "" || name == loadedGreenTarget.Name {
|
||||||
return []client.TargetSignedStruct{{Target: loadedGreenTarget, Role: loadedTargetsRole}}, nil
|
return []client.TargetSignedStruct{{Target: loadedGreenTarget, Role: loadedTargetsRole}}, nil
|
||||||
|
@ -457,6 +537,7 @@ func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name str
|
||||||
return nil, client.ErrNoSuchTarget(name)
|
return nil, client.ErrNoSuchTarget(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||||
func (l LoadedWithNoSignersNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
func (l LoadedWithNoSignersNotaryRepository) GetDelegationRoles() ([]data.Role, error) {
|
||||||
return []data.Role{}, nil
|
return []data.Role{}, nil
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ func generateManPages(opts *options) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
stdin, stdout, stderr := term.StdStreams()
|
stdin, stdout, stderr := term.StdStreams()
|
||||||
dockerCli := command.NewDockerCli(stdin, stdout, stderr)
|
dockerCli := command.NewDockerCli(stdin, stdout, stderr, false)
|
||||||
cmd := &cobra.Command{Use: "docker"}
|
cmd := &cobra.Command{Use: "docker"}
|
||||||
commands.AddCommands(cmd, dockerCli)
|
commands.AddCommands(cmd, dockerCli)
|
||||||
source := filepath.Join(opts.source, descriptionSourcePath)
|
source := filepath.Join(opts.source, descriptionSourcePath)
|
||||||
|
|
Loading…
Reference in New Issue