Skip to content

Commit

Permalink
Add a namespace field to tuf metadata storage
Browse files Browse the repository at this point in the history
Signed-off-by: Evan Cordell <cordell.evan@gmail.com>
  • Loading branch information
ecordell committed Mar 1, 2017
1 parent b5a20a3 commit 823d196
Show file tree
Hide file tree
Showing 27 changed files with 422 additions and 303 deletions.
16 changes: 8 additions & 8 deletions cmd/notary/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,16 @@ type recordingMetaStore struct {

// GetCurrent gets the metadata from the underlying MetaStore, but also records
// that the metadata was requested
func (r *recordingMetaStore) GetCurrent(gun data.GUN, role data.RoleName) (*time.Time, []byte, error) {
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s", gun.String(), role.String()))
return r.MemStorage.GetCurrent(gun, role)
func (r *recordingMetaStore) GetCurrent(gun data.GUN, namespace storage.Namespace, role data.RoleName) (*time.Time, []byte, error) {
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s.%s", gun.String(), role.String(), namespace.String()))
return r.MemStorage.GetCurrent(gun, storage.DefaultNamespace, role)
}

// GetChecksum gets the metadata from the underlying MetaStore, but also records
// that the metadata was requested
func (r *recordingMetaStore) GetChecksum(gun data.GUN, role data.RoleName, checksum string) (*time.Time, []byte, error) {
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s", gun.String(), role.String()))
return r.MemStorage.GetChecksum(gun, role, checksum)
func (r *recordingMetaStore) GetChecksum(gun data.GUN, namepsace storage.Namespace, role data.RoleName, checksum string) (*time.Time, []byte, error) {
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s.%s", gun.String(), role.String(), namepsace.String()))
return r.MemStorage.GetChecksum(gun, storage.DefaultNamespace, role, checksum)
}

// the config can provide all the TLS information necessary - the root ca file,
Expand Down Expand Up @@ -368,7 +368,7 @@ func TestConfigFileTLSCanBeRelativeToConfigOrAbsolute(t *testing.T) {

// validate that we actually managed to connect and attempted to download the root though
require.Len(t, m.gotten, 1)
require.Equal(t, m.gotten[0], "repo.root")
require.Equal(t, m.gotten[0], "repo.root.default")
}

// Whatever TLS config is in the config file can be overridden by the command line
Expand Down Expand Up @@ -418,7 +418,7 @@ func TestConfigFileOverridenByCmdLineFlags(t *testing.T) {

// validate that we actually managed to connect and attempted to download the root though
require.Len(t, m.gotten, 1)
require.Equal(t, m.gotten[0], "repo.root")
require.Equal(t, m.gotten[0], "repo.root.default")
}

// the config can specify trust pinning settings for TOFUs, as well as pinned Certs or CA
Expand Down
18 changes: 18 additions & 0 deletions migrations/server/mysql/0006_namespaces.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE TABLE `namespaces` (
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `namespaces` VALUES ("default");

ALTER TABLE `tuf_files`
ADD COLUMN `namespace` VARCHAR(255) DEFAULT "default",
ADD FOREIGN KEY (`namespace`) REFERENCES `namespaces`(`name`),
DROP INDEX `gun`,
ADD UNIQUE KEY `gun` (`gun`,`role`,`version`, `namespace`);

ALTER TABLE `changefeed`
ADD COLUMN `namespace` VARCHAR(255) DEFAULT "default",
ADD FOREIGN KEY (`namespace`) REFERENCES `namespaces`(`name`),
DROP INDEX `idx_changefeed_gun`,
ADD INDEX `idx_changefeed_gun` (`gun`, `namespace`);
16 changes: 16 additions & 0 deletions migrations/server/postgresql/0003_namespaces.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CREATE TABLE "namespaces" (
"name" VARCHAR(255) NOT NULL PRIMARY KEY
);
INSERT INTO namespaces (name) VALUES ('default');

ALTER TABLE "tuf_files"
ADD COLUMN "namespace" VARCHAR(255) NOT NULL DEFAULT ('default') REFERENCES "namespaces"("name"),
DROP CONSTRAINT "tuf_files_gun_role_version_key",
ADD UNIQUE ("gun","role","version", "namespace");


ALTER TABLE "changefeed"
ADD COLUMN "namespace" VARCHAR(255) NOT NULL DEFAULT ('default') REFERENCES "namespaces"("name");

DROP INDEX "idx_changefeed_gun";
CREATE INDEX "idx_changefeed_gun_ns" ON "changefeed" ("gun", "namespace");
4 changes: 2 additions & 2 deletions server/handlers/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func atomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Req
}
return errors.ErrInvalidUpdate.WithDetail(serializable)
}
err = store.UpdateMany(gun, updates)
err = store.UpdateMany(gun, storage.DefaultNamespace, updates)
if err != nil {
// If we have an old version error, surface to user with error code
if _, ok := err.(storage.ErrOldVersion); ok {
Expand Down Expand Up @@ -169,7 +169,7 @@ func DeleteHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
logger.Error("500 DELETE repository: no storage exists")
return errors.ErrNoStorage.WithDetail(nil)
}
err := store.Delete(gun)
err := store.Delete(gun, storage.DefaultNamespace)
if err != nil {
logger.Error("500 DELETE repository")
return errors.ErrUnknown.WithDetail(err)
Expand Down
16 changes: 8 additions & 8 deletions server/handlers/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func TestGetHandlerRoot(t *testing.T) {
require.NoError(t, err)
rootJSON, err := json.Marshal(root)
require.NoError(t, err)
metaStore.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 1, Data: rootJSON})
metaStore.UpdateCurrent("gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "root", Version: 1, Data: rootJSON})

req := &http.Request{
Body: ioutil.NopCloser(bytes.NewBuffer(nil)),
Expand Down Expand Up @@ -261,14 +261,14 @@ func TestGetHandlerTimestamp(t *testing.T) {
snJSON, err := json.Marshal(sn)
require.NoError(t, err)
metaStore.UpdateCurrent(
"gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})
"gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})

ts, err := repo.SignTimestamp(data.DefaultExpires("timestamp"))
require.NoError(t, err)
tsJSON, err := json.Marshal(ts)
require.NoError(t, err)
metaStore.UpdateCurrent(
"gun", storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})
"gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})

req := &http.Request{
Body: ioutil.NopCloser(bytes.NewBuffer(nil)),
Expand Down Expand Up @@ -298,14 +298,14 @@ func TestGetHandlerSnapshot(t *testing.T) {
snJSON, err := json.Marshal(sn)
require.NoError(t, err)
metaStore.UpdateCurrent(
"gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})
"gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})

ts, err := repo.SignTimestamp(data.DefaultExpires("timestamp"))
require.NoError(t, err)
tsJSON, err := json.Marshal(ts)
require.NoError(t, err)
metaStore.UpdateCurrent(
"gun", storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})
"gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})

req := &http.Request{
Body: ioutil.NopCloser(bytes.NewBuffer(nil)),
Expand Down Expand Up @@ -345,7 +345,7 @@ func TestGetHandler404(t *testing.T) {

func TestGetHandlerNilData(t *testing.T) {
metaStore := storage.NewMemStorage()
metaStore.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 1, Data: nil})
metaStore.UpdateCurrent("gun", storage.DefaultNamespace, storage.MetaUpdate{Role: "root", Version: 1, Data: nil})

ctx := context.Background()
ctx = context.WithValue(ctx, notary.CtxKeyMetaStore, metaStore)
Expand Down Expand Up @@ -416,7 +416,7 @@ type failStore struct {
storage.MemStorage
}

func (s *failStore) GetCurrent(_ data.GUN, _ data.RoleName) (*time.Time, []byte, error) {
func (s *failStore) GetCurrent(_ data.GUN, _ storage.Namespace, _ data.RoleName) (*time.Time, []byte, error) {
return nil, nil, fmt.Errorf("oh no! storage has failed")
}

Expand Down Expand Up @@ -458,7 +458,7 @@ type invalidVersionStore struct {
storage.MemStorage
}

func (s *invalidVersionStore) UpdateMany(_ data.GUN, _ []storage.MetaUpdate) error {
func (s *invalidVersionStore) UpdateMany(_ data.GUN, _ storage.Namespace, _ []storage.MetaUpdate) error {
return storage.ErrOldVersion{}
}

Expand Down
8 changes: 4 additions & 4 deletions server/handlers/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ func getRole(ctx context.Context, store storage.MetaStore, gun data.GUN, role da
err error
)
if checksum != "" {
lastModified, out, err = store.GetChecksum(gun, role, checksum)
lastModified, out, err = store.GetChecksum(gun, storage.DefaultNamespace, role, checksum)
} else if version != "" {
v, vErr := strconv.Atoi(version)
if vErr != nil {
return nil, nil, errors.ErrMetadataNotFound.WithDetail(vErr)
}
lastModified, out, err = store.GetVersion(gun, role, v)
lastModified, out, err = store.GetVersion(gun, storage.DefaultNamespace, role, v)
} else {
// the timestamp and snapshot might be server signed so are
// handled specially
switch role {
case data.CanonicalTimestampRole, data.CanonicalSnapshotRole:
return getMaybeServerSigned(ctx, store, gun, role)
}
lastModified, out, err = store.GetCurrent(gun, role)
lastModified, out, err = store.GetCurrent(gun, storage.DefaultNamespace, role)

}

Expand Down Expand Up @@ -98,7 +98,7 @@ func getMaybeServerSigned(ctx context.Context, store storage.MetaStore, gun data
}
if snapshotSHA256Bytes, ok := snapshotChecksums.Hashes[notary.SHA256]; ok {
snapshotSHA256Hex := hex.EncodeToString(snapshotSHA256Bytes[:])
return store.GetChecksum(gun, role, snapshotSHA256Hex)
return store.GetChecksum(gun, storage.DefaultNamespace, role, snapshotSHA256Hex)
}
return nil, nil, fmt.Errorf("could not retrieve sha256 snapshot checksum")
}
Expand Down
6 changes: 3 additions & 3 deletions server/handlers/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func loadAndValidateTargets(gun data.GUN, builder tuf.RepoBuilder, roles map[dat
// snapshot on the repo as well
func generateSnapshot(gun data.GUN, builder tuf.RepoBuilder, store storage.MetaStore) (*storage.MetaUpdate, error) {
var prev *data.SignedSnapshot
_, currentJSON, err := store.GetCurrent(gun, data.CanonicalSnapshotRole)
_, currentJSON, err := store.GetCurrent(gun, storage.DefaultNamespace, data.CanonicalSnapshotRole)
if err == nil {
prev = new(data.SignedSnapshot)
if err = json.Unmarshal(currentJSON, prev); err != nil {
Expand Down Expand Up @@ -188,7 +188,7 @@ func generateSnapshot(gun data.GUN, builder tuf.RepoBuilder, store storage.MetaS
// the other roles have already been set on the repo, and will set the generated timestamp on the repo as well
func generateTimestamp(gun data.GUN, builder tuf.RepoBuilder, store storage.MetaStore) (*storage.MetaUpdate, error) {
var prev *data.SignedTimestamp
_, currentJSON, err := store.GetCurrent(gun, data.CanonicalTimestampRole)
_, currentJSON, err := store.GetCurrent(gun, storage.DefaultNamespace, data.CanonicalTimestampRole)

switch err.(type) {
case nil:
Expand Down Expand Up @@ -224,7 +224,7 @@ func generateTimestamp(gun data.GUN, builder tuf.RepoBuilder, store storage.Meta
}

func loadFromStore(gun data.GUN, roleName data.RoleName, builder tuf.RepoBuilder, store storage.MetaStore) error {
_, metaJSON, err := store.GetCurrent(gun, roleName)
_, metaJSON, err := store.GetCurrent(gun, storage.DefaultNamespace, roleName)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 823d196

Please sign in to comment.