1
0
mirror of https://github.com/docker/docs.git synced 2026-11-05 00:14:17 +03:00

Implement AddDelegation for NotaryRepository.

Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
Ying Li
2015-12-16 15:41:14 -08:00
parent 6fb531faee
commit c72934794a
2 changed files with 91 additions and 0 deletions

View File

@@ -296,6 +296,45 @@ func addChange(cl *changelist.FileChangelist, c changelist.Change, roles ...stri
return nil
}
// AddDelegation creates a new changelist entry to add a delegation to the repository
// when the changelist gets applied at publish time. This does not do any validation
// other than checking the name of the delegation to add - all that will happen
// at publish time.
func (r *NotaryRepository) AddDelegation(name string, threshold int,
delegationKeys []data.PublicKey) error {
if !data.IsDelegation(name) {
return data.ErrInvalidRole{Role: name, Reason: "invalid delegation role name"}
}
cl, err := changelist.NewFileChangelist(filepath.Join(r.tufRepoPath, "changelist"))
if err != nil {
return err
}
defer cl.Close()
logrus.Debugf(`Adding delegation "%s" with threshold %d, and %d keys\n`,
name, threshold, len(delegationKeys))
tdJSON, err := json.Marshal(&changelist.TufDelegation{
NewThreshold: threshold,
AddKeys: data.KeyList(delegationKeys),
})
if err != nil {
return err
}
template := changelist.NewTufChange(
changelist.ActionCreate,
name,
changelist.TypeTargetsDelegation,
"", // no path
tdJSON,
)
return addChange(cl, template, name)
}
// AddTarget creates new changelist entries to add a target to the given roles
// in the repository when the changelist gets appied at publish time.
// If roles are unspecified, the default role is "target".

View File

@@ -1475,3 +1475,55 @@ func TestRemoteServerUnavailableNoLocalCache(t *testing.T) {
assert.Error(t, err)
assert.IsType(t, store.ErrServerUnavailable{}, err)
}
// AddDelegation creates a valid changefile (rejects invalid delegation names),
// which when applied, adds a new delegation role with the correct keys.
func TestAddDelegation(t *testing.T) {
// Temporary directory where test files will be created
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
defer os.RemoveAll(tempBaseDir)
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
gun := "docker.com/notary"
ts, _, _ := simpleTestServer(t)
defer ts.Close()
repo, _ := initializeRepo(t, data.ECDSAKey, tempBaseDir, gun, ts.URL, false)
targetKeyIds := repo.CryptoService.ListKeys(data.CanonicalTargetsRole)
assert.NotEmpty(t, targetKeyIds)
targetPubKey := repo.CryptoService.GetKey(targetKeyIds[0])
assert.NotNil(t, targetPubKey)
err = repo.AddDelegation("root", 1, []data.PublicKey{targetPubKey})
assert.Error(t, err)
assert.IsType(t, data.ErrInvalidRole{}, err)
assert.Empty(t, getChanges(t, repo))
err = repo.AddDelegation("targets/a", 1, []data.PublicKey{targetPubKey})
assert.NoError(t, err)
// ensure that the changefile is correct
changes := getChanges(t, repo)
assert.Len(t, changes, 1)
assert.Equal(t, changelist.ActionCreate, changes[0].Action())
assert.Equal(t, "targets/a", changes[0].Scope())
assert.Equal(t, changelist.TypeTargetsDelegation, changes[0].Type())
assert.Equal(t, "", changes[0].Path())
assert.NotEmpty(t, changes[0].Content())
// ensure that it can be applied correctly
err = applyTargetsChange(repo.tufRepo, changes[0])
assert.NoError(t, err)
targetRole := repo.tufRepo.Targets[data.CanonicalTargetsRole]
assert.Len(t, targetRole.Signed.Delegations.Roles, 1)
assert.Len(t, targetRole.Signed.Delegations.Keys, 1)
_, ok := targetRole.Signed.Delegations.Keys[targetPubKey.ID()]
assert.True(t, ok)
newDelegationRole := targetRole.Signed.Delegations.Roles[0]
assert.Len(t, newDelegationRole.KeyIDs, 1)
assert.Equal(t, targetPubKey.ID(), newDelegationRole.KeyIDs[0])
assert.Equal(t, "targets/a", newDelegationRole.Name)
}