Skip to content

Commit

Permalink
Change Namespaces to Channels, many-to-many with TUFFiles
Browse files Browse the repository at this point in the history
  • Loading branch information
ecordell committed Mar 14, 2017
1 parent 0fe2d5b commit 042eb07
Show file tree
Hide file tree
Showing 32 changed files with 642 additions and 419 deletions.
2 changes: 1 addition & 1 deletion cmd/notary-server/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func TestGetGUNPRefixes(t *testing.T) {
// For sanity, make sure we can always parse the sample config
func TestSampleConfig(t *testing.T) {
var registerCalled = 0
_, _, err := parseServerConfig("../../fixtures/server-config.json", fakeRegisterer(&registerCalled), false)
_, _, err := parseServerConfig("../../fixtures/server-config.sqlite.json", fakeRegisterer(&registerCalled), false)
require.NoError(t, err)

// once for the DB, once for the trust service
Expand Down
27 changes: 21 additions & 6 deletions cmd/notary/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,31 @@ 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, 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.PublishedState, role)
func (r *recordingMetaStore) GetCurrent(gun data.GUN, role data.RoleName, channels ...storage.Channel) (*time.Time, []byte, error) {
var channelBuf bytes.Buffer

if len(channels) == 0 {
channels = []storage.Channel{storage.Published}
}
for _, channel := range channels {
channelBuf.WriteString(channel.Name)
}
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s.%s", gun.String(), role.String(), channelBuf.String()))
return r.MemStorage.GetCurrent(gun, role)
}

// GetChecksum gets the metadata from the underlying MetaStore, but also records
// that the metadata was requested
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.PublishedState, role, checksum)
func (r *recordingMetaStore) GetChecksum(gun data.GUN, role data.RoleName, checksum string, channels ...storage.Channel) (*time.Time, []byte, error) {
var channelBuf bytes.Buffer
if len(channels) == 0 {
channels = []storage.Channel{storage.Published}
}
for _, channel := range channels {
channelBuf.WriteString(channel.Name)
}
r.gotten = append(r.gotten, fmt.Sprintf("%s.%s.%s", gun.String(), role.String(), channelBuf.String()))
return r.MemStorage.GetChecksum(gun, role, checksum)
}

// the config can provide all the TLS information necessary - the root ca file,
Expand Down
23 changes: 23 additions & 0 deletions fixtures/server-config.sqlite.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"server": {
"http_addr": ":4443",
"tls_key_file": "./notary-server.key",
"tls_cert_file": "./notary-server.crt"
},
"trust_service": {
"type": "remote",
"hostname": "notarysigner",
"port": "7899",
"tls_ca_file": "./root-ca.crt",
"key_algorithm": "ecdsa",
"tls_client_cert": "./notary-server.crt",
"tls_client_key": "./notary-server.key"
},
"logging": {
"level": "debug"
},
"storage": {
"backend": "sqlite3",
"db_url": "/tmp/notary-server.db"
}
}
27 changes: 27 additions & 0 deletions migrations/server/mysql/0006_channels.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ALTER TABLE `tuf_files`
DROP INDEX `gun`;

CREATE TABLE `channels` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `channels` (id, name) VALUES (1, "published"), (2, "staged");

CREATE TABLE `channels_tuf_files` (
`channel_id` INT(11) NOT NULL,
`tuf_file_id` INT(11) NOT NULL,
FOREIGN KEY (channel_id) REFERENCES channels(`id`) ON DELETE CASCADE,
FOREIGN KEY (tuf_file_id) REFERENCES tuf_files(`id`) ON DELETE CASCADE,
PRIMARY KEY (tuf_file_id, channel_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `channels_tuf_files` (channel_id, tuf_file_id) (
SELECT 1, `id` FROM `tuf_files`
);


9 changes: 0 additions & 9 deletions migrations/server/mysql/0006_namespaces.up.sql

This file was deleted.

30 changes: 22 additions & 8 deletions migrations/server/postgresql/0003_namespaces.up.sql
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
ALTER TABLE "tuf_files"
ADD COLUMN "namespace" VARCHAR(255) NOT NULL DEFAULT ('published'),
DROP CONSTRAINT "tuf_files_gun_role_version_key",
ADD UNIQUE ("gun","role","version", "namespace");
ALTER TABLE "tuf_files" DROP CONSTRAINT "tuf_files_gun_role_version_key";

CREATE TABLE "channels" (
"id" serial PRIMARY KEY,
"name" VARCHAR(255) NOT NULL,
"created_at" timestamp NULL DEFAULT NULL,
"updated_at" timestamp NULL DEFAULT NULL,
"deleted_at" timestamp NULL DEFAULT NULL
);

INSERT INTO "channels" (id, name) VALUES (1, 'published'), (2, 'staged');

CREATE TABLE "channels_tuf_files" (
"channel_id" integer NOT NULL,
"tuf_file_id" integer NOT NULL,
FOREIGN KEY (channel_id) REFERENCES channels("id") ON DELETE CASCADE,
FOREIGN KEY (tuf_file_id) REFERENCES tuf_files("id") ON DELETE CASCADE,
PRIMARY KEY (tuf_file_id, channel_id)
);

INSERT INTO "channels_tuf_files" (channel_id, tuf_file_id) (
SELECT 1, "id" FROM "tuf_files"
);

ALTER TABLE "changefeed"
ADD COLUMN "namespace" VARCHAR(255) NOT NULL DEFAULT ('published');

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, storage.PublishedState, updates)
err = store.UpdateMany(gun, 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, storage.PublishedState)
err := store.Delete(gun)
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.PublishedState, storage.MetaUpdate{Role: "root", Version: 1, Data: rootJSON})
metaStore.UpdateCurrent("gun", 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.PublishedState, storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})
"gun", 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.PublishedState, storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})
"gun", 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.PublishedState, storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON})
"gun", 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.PublishedState, storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON})
"gun", 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.PublishedState, storage.MetaUpdate{Role: "root", Version: 1, Data: nil})
metaStore.UpdateCurrent("gun", 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, _ storage.Namespace, _ data.RoleName) (*time.Time, []byte, error) {
func (s *failStore) GetCurrent(_ data.GUN, _ data.RoleName, channels ...storage.Channel) (*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.Namespace, _ []storage.MetaUpdate) error {
func (s *invalidVersionStore) UpdateMany(_ data.GUN, _ []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, storage.PublishedState, role, checksum)
lastModified, out, err = store.GetChecksum(gun, 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, storage.PublishedState, role, v)
lastModified, out, err = store.GetVersion(gun, 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, storage.PublishedState, role)
lastModified, out, err = store.GetCurrent(gun, 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, storage.PublishedState, role, snapshotSHA256Hex)
return store.GetChecksum(gun, 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, storage.PublishedState, data.CanonicalSnapshotRole)
_, currentJSON, err := store.GetCurrent(gun, 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, storage.PublishedState, data.CanonicalTimestampRole)
_, currentJSON, err := store.GetCurrent(gun, 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, storage.PublishedState, roleName)
_, metaJSON, err := store.GetCurrent(gun, roleName)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 042eb07

Please sign in to comment.