trust: add Repository client interface

Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Upstream-commit: 7c5b836ca5
Component: cli
This commit is contained in:
Riyaz Faizullabhoy
2017-09-11 14:07:00 -07:00
parent e42a2df102
commit b53048a314
36 changed files with 221 additions and 174 deletions

View File

@ -109,18 +109,19 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository
}
// get the latest repository metadata so we can figure out which roles to sign
err = repo.Update(false)
// TODO(riyazdf): interface change to get back Update
_, err = repo.ListTargets()
switch err.(type) {
case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist:
keys := repo.CryptoService.ListKeys(data.CanonicalRootRole)
keys := repo.GetCryptoService().ListKeys(data.CanonicalRootRole)
var rootKeyID string
// always select the first root key
if len(keys) > 0 {
sort.Strings(keys)
rootKeyID = keys[0]
} else {
rootPublicKey, err := repo.CryptoService.Create(data.CanonicalRootRole, "", data.ECDSAKey)
rootPublicKey, err := repo.GetCryptoService().Create(data.CanonicalRootRole, "", data.ECDSAKey)
if err != nil {
return err
}
@ -157,7 +158,7 @@ func PushTrustedReference(streams command.Streams, repoInfo *registry.Repository
// (based on whether we have the signing key and whether the role's path allows
// us to).
// If there are no delegation roles, we add to the targets role.
func AddTargetToAllSignableRoles(repo *client.NotaryRepository, target *client.Target) error {
func AddTargetToAllSignableRoles(repo client.Repository, target *client.Target) error {
signableRoles, err := trust.GetSignableRoles(repo, target)
if err != nil {
return err

View File

@ -66,7 +66,7 @@ func TestAddTargetToAllSignableRolesError(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
target := client.Target{}
err = AddTargetToAllSignableRoles(notaryRepo, &target)
assert.EqualError(t, err, "client is offline")
@ -77,7 +77,7 @@ func TestGetSignableRolesError(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
target := client.Target{}
_, err = trust.GetSignableRoles(notaryRepo, &target)
assert.EqualError(t, err, "client is offline")

View File

@ -92,7 +92,7 @@ func notaryRoleToSigner(tufRole data.RoleName) string {
return strings.TrimPrefix(tufRole.String(), "targets/")
}
func clearChangeList(notaryRepo *client.NotaryRepository) error {
func clearChangeList(notaryRepo client.Repository) error {
cl, err := notaryRepo.GetChangelist()
if err != nil {
return err

View File

@ -8,7 +8,6 @@ import (
"sort"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
@ -16,6 +15,7 @@ import (
"github.com/docker/notary"
"github.com/docker/notary/client"
"github.com/docker/notary/tuf/data"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

View File

@ -65,7 +65,7 @@ func revokeTrust(cli command.Cli, remote string, options revokeOptions) error {
return nil
}
func revokeSignature(notaryRepo *client.NotaryRepository, tag string) error {
func revokeSignature(notaryRepo client.Repository, tag string) error {
if tag != "" {
// Revoke signature for the specified tag
if err := revokeSingleSig(notaryRepo, tag); err != nil {
@ -82,7 +82,7 @@ func revokeSignature(notaryRepo *client.NotaryRepository, tag string) error {
return notaryRepo.Publish()
}
func revokeSingleSig(notaryRepo *client.NotaryRepository, tag string) error {
func revokeSingleSig(notaryRepo client.Repository, tag string) error {
releasedTargetWithRole, err := notaryRepo.GetTargetByName(tag, trust.ReleasesRole, data.CanonicalTargetsRole)
if err != nil {
return err
@ -91,7 +91,7 @@ func revokeSingleSig(notaryRepo *client.NotaryRepository, tag string) error {
return getSignableRolesForTargetAndRemove(releasedTarget, notaryRepo)
}
func revokeAllSigs(notaryRepo *client.NotaryRepository) error {
func revokeAllSigs(notaryRepo client.Repository) error {
releasedTargetWithRoleList, err := notaryRepo.ListTargets(trust.ReleasesRole, data.CanonicalTargetsRole)
if err != nil {
return err
@ -108,7 +108,7 @@ func revokeAllSigs(notaryRepo *client.NotaryRepository) error {
}
// get all the roles that signed the target and removes it from all roles.
func getSignableRolesForTargetAndRemove(releasedTarget client.Target, notaryRepo *client.NotaryRepository) error {
func getSignableRolesForTargetAndRemove(releasedTarget client.Target, notaryRepo client.Repository) error {
signableRoles, err := trust.GetSignableRoles(notaryRepo, &releasedTarget)
if err != nil {
return err

View File

@ -86,7 +86,7 @@ func TestGetSignableRolesForTargetAndRemoveError(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
target := client.Target{}
err = getSignableRolesForTargetAndRemove(target, notaryRepo)
assert.EqualError(t, err, "client is offline")

View File

@ -50,7 +50,8 @@ func signImage(cli command.Cli, imageName string) error {
defer clearChangeList(notaryRepo)
// get the latest repository metadata so we can figure out which roles to sign
if err = notaryRepo.Update(false); err != nil {
// TODO(riyazdf): interface change to get back Update
if _, err = notaryRepo.ListTargets(); err != nil {
switch err.(type) {
case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist:
// before initializing a new repo, check that the image exists locally:
@ -106,7 +107,7 @@ func checkLocalImageExistence(ctx context.Context, cli command.Cli, imageName st
return err
}
func createTarget(notaryRepo *client.NotaryRepository, tag string) (client.Target, error) {
func createTarget(notaryRepo client.Repository, tag string) (client.Target, error) {
target := &client.Target{}
var err error
if tag == "" {
@ -117,7 +118,7 @@ func createTarget(notaryRepo *client.NotaryRepository, tag string) (client.Targe
return *target, err
}
func getSignedManifestHashAndSize(notaryRepo *client.NotaryRepository, tag string) (data.Hashes, int64, error) {
func getSignedManifestHashAndSize(notaryRepo client.Repository, tag string) (data.Hashes, int64, error) {
targets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil {
return nil, 0, err
@ -134,7 +135,7 @@ func getReleasedTargetHashAndSize(targets []client.TargetSignedStruct, tag strin
return nil, 0, client.ErrNoSuchTarget(tag)
}
func getExistingSignatureInfoForReleasedTag(notaryRepo *client.NotaryRepository, tag string) (trustTagRow, error) {
func getExistingSignatureInfoForReleasedTag(notaryRepo client.Repository, tag string) (trustTagRow, error) {
targets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil {
return trustTagRow{}, err
@ -152,7 +153,7 @@ func prettyPrintExistingSignatureInfo(cli command.Cli, existingSigInfo trustTagR
fmt.Fprintf(cli.Out(), "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.TagName, existingSigInfo.HashHex, joinedSigners)
}
func initNotaryRepoWithSigners(notaryRepo *client.NotaryRepository, newSigner data.RoleName) error {
func initNotaryRepoWithSigners(notaryRepo client.Repository, newSigner data.RoleName) error {
rootKey, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole)
if err != nil {
return err
@ -174,25 +175,25 @@ func initNotaryRepoWithSigners(notaryRepo *client.NotaryRepository, newSigner da
}
// generates an ECDSA key without a GUN for the specified role
func getOrGenerateNotaryKey(notaryRepo *client.NotaryRepository, role data.RoleName) (data.PublicKey, error) {
func getOrGenerateNotaryKey(notaryRepo client.Repository, role data.RoleName) (data.PublicKey, error) {
// use the signer name in the PEM headers if this is a delegation key
if data.IsDelegation(role) {
role = data.RoleName(notaryRoleToSigner(role))
}
keys := notaryRepo.CryptoService.ListKeys(role)
keys := notaryRepo.GetCryptoService().ListKeys(role)
var err error
var key data.PublicKey
// always select the first key by ID
if len(keys) > 0 {
sort.Strings(keys)
keyID := keys[0]
privKey, _, err := notaryRepo.CryptoService.GetPrivateKey(keyID)
privKey, _, err := notaryRepo.GetCryptoService().GetPrivateKey(keyID)
if err != nil {
return nil, err
}
key = data.PublicKeyFromPrivate(privKey)
} else {
key, err = notaryRepo.CryptoService.Create(role, "", data.ECDSAKey)
key, err = notaryRepo.GetCryptoService().Create(role, "", data.ECDSAKey)
if err != nil {
return nil, err
}
@ -201,7 +202,7 @@ func getOrGenerateNotaryKey(notaryRepo *client.NotaryRepository, role data.RoleN
}
// stages changes to add a signer with the specified name and key(s). Adds to targets/<name> and targets/releases
func addStagedSigner(notaryRepo *client.NotaryRepository, newSigner data.RoleName, signerKeys []data.PublicKey) {
func addStagedSigner(notaryRepo client.Repository, newSigner data.RoleName, signerKeys []data.PublicKey) {
// create targets/<username>
notaryRepo.AddDelegationRoleAndKeys(newSigner, signerKeys)
notaryRepo.AddDelegationPaths(newSigner, []string{""})

View File

@ -91,7 +91,7 @@ func TestGetOrGenerateNotaryKey(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
// repo is empty, try making a root key
@ -100,9 +100,9 @@ func TestGetOrGenerateNotaryKey(t *testing.T) {
assert.NotNil(t, rootKeyA)
// we should only have one newly generated key
allKeys := notaryRepo.CryptoService.ListAllKeys()
allKeys := notaryRepo.GetCryptoService().ListAllKeys()
assert.Len(t, allKeys, 1)
assert.NotNil(t, notaryRepo.CryptoService.GetKey(rootKeyA.ID()))
assert.NotNil(t, notaryRepo.GetCryptoService().GetKey(rootKeyA.ID()))
// this time we should get back the same key if we ask for another root key
rootKeyB, err := getOrGenerateNotaryKey(notaryRepo, data.CanonicalRootRole)
@ -110,9 +110,9 @@ func TestGetOrGenerateNotaryKey(t *testing.T) {
assert.NotNil(t, rootKeyB)
// we should only have one newly generated key
allKeys = notaryRepo.CryptoService.ListAllKeys()
allKeys = notaryRepo.GetCryptoService().ListAllKeys()
assert.Len(t, allKeys, 1)
assert.NotNil(t, notaryRepo.CryptoService.GetKey(rootKeyB.ID()))
assert.NotNil(t, notaryRepo.GetCryptoService().GetKey(rootKeyB.ID()))
// The key we retrieved should be identical to the one we generated
assert.Equal(t, rootKeyA, rootKeyB)
@ -123,9 +123,9 @@ func TestGetOrGenerateNotaryKey(t *testing.T) {
assert.NotNil(t, releasesKey)
// we should now have two keys
allKeys = notaryRepo.CryptoService.ListAllKeys()
allKeys = notaryRepo.GetCryptoService().ListAllKeys()
assert.Len(t, allKeys, 2)
assert.NotNil(t, notaryRepo.CryptoService.GetKey(releasesKey.ID()))
assert.NotNil(t, notaryRepo.GetCryptoService().GetKey(releasesKey.ID()))
// The key we retrieved should be identical to the one we generated
assert.NotEqual(t, releasesKey, rootKeyA)
assert.NotEqual(t, releasesKey, rootKeyB)
@ -136,7 +136,7 @@ func TestAddStageSigners(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
// stage targets/user
@ -216,7 +216,7 @@ func TestGetSignedManifestHashAndSize(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
target := &client.Target{}
target.Hashes, target.Length, err = getSignedManifestHashAndSize(notaryRepo, "test")
@ -244,7 +244,7 @@ func TestCreateTarget(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
_, err = createTarget(notaryRepo, "")
assert.EqualError(t, err, "No tag specified")
@ -257,7 +257,7 @@ func TestGetExistingSignatureInfoForReleasedTag(t *testing.T) {
assert.NoError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
_, err = getExistingSignatureInfoForReleasedTag(notaryRepo, "test")
assert.EqualError(t, err, "client is offline")
@ -284,7 +284,7 @@ func TestChangeList(t *testing.T) {
cmd.SetArgs([]string{"ubuntu:latest"})
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
notaryRepo, err := client.NewFileCachedNotaryRepository(tmpDir, "docker.io/library/ubuntu", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "docker.io/library/ubuntu", "https://localhost", nil, passphrase.ConstantRetriever(passwd), trustpinning.TrustPinConfig{})
assert.NoError(t, err)
cl, err := notaryRepo.GetChangelist()
assert.Equal(t, len(cl.List()), 0)