Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fb1cbae
vendor: upgrade notary version for docker trust
riyazdf Aug 24, 2017
5846e6e
trust: update existing code for new vendoring, refactor for docker tr…
riyazdf Aug 24, 2017
ec6bc94
trust inspect: add docker trust inspect command with formatting print
riyazdf Aug 24, 2017
809ef0f
trust inspect: docs for docker trust inspect
riyazdf Aug 24, 2017
fab6bb6
trust sign: add docker trust sign command
riyazdf Aug 24, 2017
bc665ed
trust sign: docs for docker trust sign
riyazdf Aug 24, 2017
609f8b4
trust revoke: add docker trust revoke command
riyazdf Aug 24, 2017
43717a8
trust revoke: docs for docker trust revoke
riyazdf Aug 24, 2017
007aff7
docs: update docker trust docs with correct tense and formatting
riyazdf Aug 25, 2017
45c102a
trust: address review feedback, refactor to align with existing cli/c…
riyazdf Aug 25, 2017
7c5b836
trust: add Repository client interface
riyazdf Sep 11, 2017
e5c35ab
cli: introduce NotaryClient getter
riyazdf Sep 12, 2017
f667bd7
trust: use mock CLI for testing offline
riyazdf Sep 13, 2017
6fca400
tests: address review feedback
riyazdf Sep 14, 2017
4e89dc8
trust: update reference type and use golden output
riyazdf Sep 14, 2017
67cf09c
tests: move trust test to proper package
riyazdf Sep 15, 2017
4e95fcd
trust: update remove to error on empty references for consistency
riyazdf Sep 18, 2017
46a879e
tests: use alice/bob/claire conventional names for signers
riyazdf Sep 19, 2017
c6db0cd
trust: rename inspect to view, add repo name to signer table header
riyazdf Sep 19, 2017
e07f345
mark command as experimental in docs and cli
riyazdf Sep 19, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cli/command/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import (
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/cli/cli/trust"
dopts "github.com/docker/cli/opts"
"github.com/docker/docker/api"
"github.com/docker/docker/client"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
"github.com/docker/notary"
notaryclient "github.com/docker/notary/client"
"github.com/docker/notary/passphrase"
"github.com/pkg/errors"
"github.com/spf13/cobra"
Expand All @@ -40,6 +42,7 @@ type Cli interface {
SetIn(in *InStream)
ConfigFile() *configfile.ConfigFile
ServerInfo() ServerInfo
NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
}

// DockerCli is an instance the docker command line client.
Expand Down Expand Up @@ -161,6 +164,11 @@ func getClientWithPassword(passRetriever notary.PassRetriever, newClient func(pa
}
}

// NotaryClient provides a Notary Repository to interact with signed metadata for an image
func (cli *DockerCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
return trust.GetNotaryRepository(cli.In(), cli.Out(), UserAgent(), imgRefAndAuth.RepoInfo(), imgRefAndAuth.AuthConfig(), actions...)
}

// ServerInfo stores details about the supported features and platform of the
// server
type ServerInfo struct {
Expand Down
4 changes: 4 additions & 0 deletions cli/command/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/docker/cli/cli/command/stack"
"github.com/docker/cli/cli/command/swarm"
"github.com/docker/cli/cli/command/system"
"github.com/docker/cli/cli/command/trust"
"github.com/docker/cli/cli/command/volume"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -69,6 +70,9 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
// swarm
swarm.NewSwarmCommand(dockerCli),

// trust
trust.NewTrustCommand(dockerCli),

// volume
volume.NewVolumeCommand(dockerCli),

Expand Down
150 changes: 150 additions & 0 deletions cli/command/formatter/trust.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package formatter

import (
"sort"
"strings"

"github.com/docker/docker/pkg/stringid"
)

const (
defaultTrustTagTableFormat = "table {{.SignedTag}}\t{{.Digest}}\t{{.Signers}}"
signedTagNameHeader = "SIGNED TAG"
trustedDigestHeader = "DIGEST"
signersHeader = "SIGNERS"
defaultSignerInfoTableFormat = "table {{.Signer}}\t{{.Keys}}"
signerNameHeader = "SIGNER"
keysHeader = "KEYS"
)

// SignedTagInfo represents all formatted information needed to describe a signed tag:
// Name: name of the signed tag
// Digest: hex encoded digest of the contents
// Signers: list of entities who signed the tag
type SignedTagInfo struct {
Name string
Digest string
Signers []string
}

// SignerInfo represents all formatted information needed to describe a signer:
// Name: name of the signer role
// Keys: the keys associated with the signer
type SignerInfo struct {
Name string
Keys []string
}

// NewTrustTagFormat returns a Format for rendering using a trusted tag Context
func NewTrustTagFormat() Format {
return defaultTrustTagTableFormat
}

// NewSignerInfoFormat returns a Format for rendering a signer role info Context
func NewSignerInfoFormat() Format {
return defaultSignerInfoTableFormat
}

// TrustTagWrite writes the context
func TrustTagWrite(ctx Context, signedTagInfoList []SignedTagInfo) error {
render := func(format func(subContext subContext) error) error {
for _, signedTag := range signedTagInfoList {
if err := format(&trustTagContext{s: signedTag}); err != nil {
return err
}
}
return nil
}
trustTagCtx := trustTagContext{}
trustTagCtx.header = trustTagHeaderContext{
"SignedTag": signedTagNameHeader,
"Digest": trustedDigestHeader,
"Signers": signersHeader,
}
return ctx.Write(&trustTagCtx, render)
}

type trustTagHeaderContext map[string]string

type trustTagContext struct {
HeaderContext
s SignedTagInfo
}

// SignedTag returns the name of the signed tag
func (c *trustTagContext) SignedTag() string {
return c.s.Name
}

// Digest returns the hex encoded digest associated with this signed tag
func (c *trustTagContext) Digest() string {
return c.s.Digest
}

// Signers returns the sorted list of entities who signed this tag
func (c *trustTagContext) Signers() string {
sort.Strings(c.s.Signers)
return strings.Join(c.s.Signers, ", ")
}

// SignerInfoWrite writes the context
func SignerInfoWrite(ctx Context, signerInfoList []SignerInfo) error {
render := func(format func(subContext subContext) error) error {
for _, signerInfo := range signerInfoList {
if err := format(&signerInfoContext{
trunc: ctx.Trunc,
s: signerInfo,
}); err != nil {
return err
}
}
return nil
}
signerInfoCtx := signerInfoContext{}
signerInfoCtx.header = signerInfoHeaderContext{
"Signer": signerNameHeader,
"Keys": keysHeader,
}
return ctx.Write(&signerInfoCtx, render)
}

type signerInfoHeaderContext map[string]string

type signerInfoContext struct {
HeaderContext
trunc bool
s SignerInfo
}

// Keys returns the sorted list of keys associated with the signer
func (c *signerInfoContext) Keys() string {
sort.Strings(c.s.Keys)
truncatedKeys := []string{}
if c.trunc {
for _, keyID := range c.s.Keys {
truncatedKeys = append(truncatedKeys, stringid.TruncateID(keyID))
}
return strings.Join(truncatedKeys, ", ")
}
return strings.Join(c.s.Keys, ", ")
}

// Signer returns the name of the signer
func (c *signerInfoContext) Signer() string {
return c.s.Name
}

// SignerInfoList helps sort []SignerInfo by signer names
type SignerInfoList []SignerInfo

func (signerInfoComp SignerInfoList) Len() int {
return len(signerInfoComp)
}

func (signerInfoComp SignerInfoList) Less(i, j int) bool {
return signerInfoComp[i].Name < signerInfoComp[j].Name
}

func (signerInfoComp SignerInfoList) Swap(i, j int) {
signerInfoComp[i], signerInfoComp[j] = signerInfoComp[j], signerInfoComp[i]
}
Loading