From 2cb7ae7f5a7d4570a32b616ef1d65a3155aeac87 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Fri, 30 Oct 2020 18:45:43 -0400 Subject: [PATCH] Add a SQL schema and DAO for KmsSecretRevision (#840) * Add a SQL schema and DAO for KmsSecretRevision The dual-object nature of KmsSecret and KmsSecretRevision will not be necessary once we have moved to SQL. In that world, the only object will be the one now called KmsSecretRevision. KmsSecretRevision already stores its parent so all we need to do is convert that key to the String secretName (or from the secretName to the key, if loading from SQL) and select the max revision ID for a given secret name. In a future PR, we will add a dual-writing DAO to these objects and perform the dual writes, similar to how ReservedList functions. * Regenerate diagram * Rename revisionId and cryptoKeyVersionName * Fix SQL files and diagram --- .../registry/model/server/KmsSecret.java | 10 +- .../model/server/KmsSecretRevision.java | 65 +- .../model/server/KmsSecretRevisionSqlDao.java | 54 + .../main/resources/META-INF/persistence.xml | 1 + .../server/KmsSecretRevisionSqlDaoTest.java | 86 ++ .../integration/SqlIntegrationTestSuite.java | 2 + .../sql/er_diagram/brief_er_diagram.html | 561 ++++---- .../sql/er_diagram/full_er_diagram.html | 1150 +++++++++-------- db/src/main/resources/sql/flyway.txt | 1 + .../sql/flyway/V71__create_kms_secret.sql | 24 + .../sql/schema/db-schema.sql.generated | 10 + .../resources/sql/schema/nomulus.golden.sql | 28 + 12 files changed, 1229 insertions(+), 763 deletions(-) create mode 100644 core/src/main/java/google/registry/model/server/KmsSecretRevisionSqlDao.java create mode 100644 core/src/test/java/google/registry/model/server/KmsSecretRevisionSqlDaoTest.java create mode 100644 db/src/main/resources/sql/flyway/V71__create_kms_secret.sql diff --git a/core/src/main/java/google/registry/model/server/KmsSecret.java b/core/src/main/java/google/registry/model/server/KmsSecret.java index 62dbe6cf4..25ce85c0e 100644 --- a/core/src/main/java/google/registry/model/server/KmsSecret.java +++ b/core/src/main/java/google/registry/model/server/KmsSecret.java @@ -16,6 +16,7 @@ package google.registry.model.server; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -23,11 +24,13 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.ReportedOn; import google.registry.model.common.EntityGroupRoot; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; /** Pointer to the latest {@link KmsSecretRevision}. */ @Entity @ReportedOn -public class KmsSecret extends ImmutableObject { +public class KmsSecret extends ImmutableObject implements DatastoreEntity { /** The unique name of this {@link KmsSecret}. */ @Id String name; @@ -45,6 +48,11 @@ public class KmsSecret extends ImmutableObject { return latestRevision; } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + public static KmsSecret create(String name, KmsSecretRevision latestRevision) { KmsSecret instance = new KmsSecret(); instance.name = name; diff --git a/core/src/main/java/google/registry/model/server/KmsSecretRevision.java b/core/src/main/java/google/registry/model/server/KmsSecretRevision.java index a5da28cba..e55d6c83e 100644 --- a/core/src/main/java/google/registry/model/server/KmsSecretRevision.java +++ b/core/src/main/java/google/registry/model/server/KmsSecretRevision.java @@ -17,14 +17,24 @@ package google.registry.model.server; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; +import com.googlecode.objectify.annotation.Ignore; +import com.googlecode.objectify.annotation.OnLoad; import com.googlecode.objectify.annotation.Parent; import google.registry.model.Buildable; import google.registry.model.CreateAutoTimestamp; import google.registry.model.ImmutableObject; import google.registry.model.annotations.ReportedOn; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; +import javax.persistence.Column; +import javax.persistence.Index; +import javax.persistence.PostLoad; +import javax.persistence.Table; +import javax.persistence.Transient; /** * An encrypted value. @@ -35,13 +45,22 @@ import google.registry.model.annotations.ReportedOn; * *

The value can be encrypted and decrypted using Cloud KMS. * + *

Note that the primary key of this entity is {@link #revisionKey}, which is auto-generated by + * the database. So, if a retry of insertion happens after the previous attempt unexpectedly + * succeeds, we will end up with having two exact same revisions that differ only by revisionKey. + * This is fine though, because we only use the revision with the highest revisionKey. + * + *

TODO: remove Datastore-specific fields post-Registry-3.0-migration and rename to KmsSecret. + * * @see Google Cloud Key Management Service * Documentation * @see google.registry.keyring.kms.KmsKeyring */ @Entity @ReportedOn -public class KmsSecretRevision extends ImmutableObject { +@javax.persistence.Entity(name = "KmsSecret") +@Table(indexes = {@Index(columnList = "secretName")}) +public class KmsSecretRevision extends ImmutableObject implements DatastoreEntity, SqlEntity { /** * The maximum allowable secret size. Although Datastore allows entities up to 1 MB in size, @@ -49,18 +68,31 @@ public class KmsSecretRevision extends ImmutableObject { */ private static final int MAX_SECRET_SIZE_BYTES = 64 * 1024 * 1024; - /** The revision of this secret. */ - @Id long revisionKey; + /** + * The revision of this secret. + * + *

TODO: change name of the variable to revisionId once we're off Datastore + */ + @Id + @javax.persistence.Id + @Column(name = "revisionId") + long revisionKey; /** The parent {@link KmsSecret} which contains metadata about this {@link KmsSecretRevision}. */ - @Parent Key parent; + @Parent @Transient Key parent; + @Column(nullable = false) + @Ignore + String secretName; /** * The name of the {@code cryptoKeyVersion} associated with this {@link KmsSecretRevision}. * + *

TODO: change name of the variable to cryptoKeyVersionName once we're off Datastore + * * @see projects.locations.keyRings.cryptoKeys.cryptoKeyVersions */ + @Column(nullable = false, name = "cryptoKeyVersionName") String kmsCryptoKeyVersionName; /** @@ -70,9 +102,11 @@ public class KmsSecretRevision extends ImmutableObject { * @see projects.locations.keyRings.cryptoKeys.encrypt */ + @Column(nullable = false) String encryptedValue; /** An automatically managed creation timestamp. */ + @Column(nullable = false) CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null); public String getKmsCryptoKeyVersionName() { @@ -83,6 +117,28 @@ public class KmsSecretRevision extends ImmutableObject { return encryptedValue; } + // When loading from SQL, fill out the Datastore-specific field + @PostLoad + void postLoad() { + parent = Key.create(getCrossTldKey(), KmsSecret.class, secretName); + } + + // When loading from Datastore, fill out the SQL-specific field + @OnLoad + void onLoad() { + secretName = parent.getName(); + } + + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // This is dually-written, as we do not care about history + } + + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // This is dually-written, as we do not care about history + } + /** A builder for constructing {@link KmsSecretRevision} entities, since they are immutable. */ public static class Builder extends Buildable.Builder { @@ -108,6 +164,7 @@ public class KmsSecretRevision extends ImmutableObject { */ public Builder setParent(String secretName) { getInstance().parent = Key.create(getCrossTldKey(), KmsSecret.class, secretName); + getInstance().secretName = secretName; return this; } } diff --git a/core/src/main/java/google/registry/model/server/KmsSecretRevisionSqlDao.java b/core/src/main/java/google/registry/model/server/KmsSecretRevisionSqlDao.java new file mode 100644 index 000000000..30cba03b5 --- /dev/null +++ b/core/src/main/java/google/registry/model/server/KmsSecretRevisionSqlDao.java @@ -0,0 +1,54 @@ +// Copyright 2020 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.server; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Strings.isNullOrEmpty; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; +import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; + +import java.util.Optional; + +/** + * A {@link KmsSecretRevision} DAO for Cloud SQL. + * + *

TODO: Rename this class to KmsSecretDao after migrating to Cloud SQL. + */ +public class KmsSecretRevisionSqlDao { + + private KmsSecretRevisionSqlDao() {} + + /** Saves the given KMS secret revision. */ + public static void save(KmsSecretRevision kmsSecretRevision) { + checkArgumentNotNull(kmsSecretRevision, "kmsSecretRevision cannot be null"); + jpaTm().assertInTransaction(); + jpaTm().put(kmsSecretRevision); + } + + /** Returns the latest revision for the secret name given, or absent if nonexistent. */ + public static Optional getLatestRevision(String secretName) { + checkArgument(!isNullOrEmpty(secretName), "secretName cannot be null or empty"); + jpaTm().assertInTransaction(); + return jpaTm() + .getEntityManager() + .createQuery( + "FROM KmsSecret ks WHERE ks.revisionKey IN (SELECT MAX(revisionKey) FROM " + + "KmsSecret subKs WHERE subKs.secretName = :secretName)", + KmsSecretRevision.class) + .setParameter("secretName", secretName) + .getResultStream() + .findFirst(); + } +} diff --git a/core/src/main/resources/META-INF/persistence.xml b/core/src/main/resources/META-INF/persistence.xml index da7007ac4..58ab1ec77 100644 --- a/core/src/main/resources/META-INF/persistence.xml +++ b/core/src/main/resources/META-INF/persistence.xml @@ -62,6 +62,7 @@ google.registry.model.registry.Registry google.registry.model.reporting.DomainTransactionRecord google.registry.model.reporting.Spec11ThreatMatch + google.registry.model.server.KmsSecretRevision google.registry.model.smd.SignedMarkRevocationList google.registry.model.tmch.ClaimsListShard google.registry.persistence.transaction.TransactionEntity diff --git a/core/src/test/java/google/registry/model/server/KmsSecretRevisionSqlDaoTest.java b/core/src/test/java/google/registry/model/server/KmsSecretRevisionSqlDaoTest.java new file mode 100644 index 000000000..7281b8689 --- /dev/null +++ b/core/src/test/java/google/registry/model/server/KmsSecretRevisionSqlDaoTest.java @@ -0,0 +1,86 @@ +// Copyright 2020 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.server; + +import static com.google.common.truth.Truth.assertThat; +import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; +import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; + +import google.registry.persistence.transaction.JpaTestRules; +import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension; +import google.registry.testing.DatastoreEntityExtension; +import google.registry.testing.FakeClock; +import java.util.Optional; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** Tests for {@link google.registry.model.server.KmsSecretRevisionSqlDao}. */ +public class KmsSecretRevisionSqlDaoTest { + + private final FakeClock fakeClock = new FakeClock(); + + @RegisterExtension + @Order(value = 1) + DatastoreEntityExtension datastoreEntityExtension = new DatastoreEntityExtension(); + + @RegisterExtension + JpaIntegrationWithCoverageExtension jpa = + new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension(); + + @Test + void testSaveAndRetrieve() { + KmsSecretRevision revision = createRevision(); + jpaTm().transact(() -> KmsSecretRevisionSqlDao.save(revision)); + Optional fromSql = + jpaTm().transact(() -> KmsSecretRevisionSqlDao.getLatestRevision("secretName")); + assertThat(fromSql.isPresent()).isTrue(); + assertAboutImmutableObjects().that(revision).isEqualExceptFields(fromSql.get(), "creationTime"); + } + + @Test + void testMultipleRevisions() { + KmsSecretRevision revision = createRevision(); + jpaTm().transact(() -> KmsSecretRevisionSqlDao.save(revision)); + + KmsSecretRevision secondRevision = createRevision(); + secondRevision.encryptedValue = "someOtherValue"; + jpaTm().transact(() -> KmsSecretRevisionSqlDao.save(secondRevision)); + + Optional fromSql = + jpaTm().transact(() -> KmsSecretRevisionSqlDao.getLatestRevision("secretName")); + assertThat(fromSql.isPresent()).isTrue(); + assertThat(fromSql.get().getEncryptedValue()).isEqualTo("someOtherValue"); + } + + @Test + void testNonexistent() { + KmsSecretRevision revision = createRevision(); + jpaTm().transact(() -> KmsSecretRevisionSqlDao.save(revision)); + assertThat( + jpaTm() + .transact(() -> KmsSecretRevisionSqlDao.getLatestRevision("someOtherSecretName")) + .isPresent()) + .isFalse(); + } + + private KmsSecretRevision createRevision() { + return new KmsSecretRevision.Builder() + .setEncryptedValue("encrypted") + .setKmsCryptoKeyVersionName("version") + .setParent("secretName") + .build(); + } +} diff --git a/core/src/test/java/google/registry/schema/integration/SqlIntegrationTestSuite.java b/core/src/test/java/google/registry/schema/integration/SqlIntegrationTestSuite.java index 24d1e6ca5..a717bd6f3 100644 --- a/core/src/test/java/google/registry/schema/integration/SqlIntegrationTestSuite.java +++ b/core/src/test/java/google/registry/schema/integration/SqlIntegrationTestSuite.java @@ -29,6 +29,7 @@ import google.registry.model.registry.RegistryLockDaoTest; import google.registry.model.registry.RegistryTest; import google.registry.model.registry.label.ReservedListSqlDaoTest; import google.registry.model.reporting.Spec11ThreatMatchTest; +import google.registry.model.server.KmsSecretRevisionSqlDaoTest; import google.registry.model.smd.SignedMarkRevocationListDaoTest; import google.registry.model.tmch.ClaimsListDaoTest; import google.registry.persistence.transaction.JpaEntityCoverageExtension; @@ -85,6 +86,7 @@ import org.junit.runner.RunWith; DomainBaseSqlTest.class, DomainHistoryTest.class, HostHistoryTest.class, + KmsSecretRevisionSqlDaoTest.class, LockDaoTest.class, PollMessageTest.class, PremiumListDaoTest.class, diff --git a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html index 9ab1fcb7c..d85e83fd1 100644 --- a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html @@ -261,19 +261,19 @@ td.section { generated on - 2020-10-30 20:47:04.047621 + 2020-10-30 21:56:22.867321 last flyway file - V70__signed_mark_revocation_list.sql + V71__create_kms_secret.sql

 

 

- + SchemaCrawler_Diagram - + generated by @@ -284,7 +284,7 @@ td.section { generated on - 2020-10-30 20:47:04.047621 + 2020-10-30 21:56:22.867321 @@ -521,7 +521,7 @@ td.section { fk_billing_cancellation_billing_recurrence_id - + registrar_6e1503e3 @@ -2182,484 +2182,512 @@ td.section { fk3d09knnmxrt6iniwnp8j2ykga - + - lock_f21d4861 - - - public.Lock + kmssecret_f3b28857 + + + public.KmsSecret - - + + [table] - - resource_name - - - - - text not null - - - tld - - - - - text not null - - - - - premiumentry_b0060b91 - - - public.PremiumEntry - - - - [table] - - + revision_id - + - + int8 not null - - domain_label + + secret_name - + - + text not null - - - - premiumlist_7c3ea68b - - - public.PremiumList + + + + lock_f21d4861 + + + public.Lock - - + + [table] - - revision_id + + resource_name - + - - bigserial not null - - - - - auto-incremented - - - name - - - - + text not null - + + tld + + + + + text not null + + + + + premiumentry_b0060b91 + + + public.PremiumEntry + + + + [table] + + + revision_id + + + + + int8 not null + + + domain_label + + + + + text not null + + + + + premiumlist_7c3ea68b + + + public.PremiumList + + + + [table] + + + revision_id + + + + + bigserial not null + + + + + auto-incremented + + + name + + + + + text not null + + premiumentry_b0060b91:w->premiumlist_7c3ea68b:e - - - - - - - - + + + + + + + + fko0gw90lpo1tuee56l0nb6y6g5 - + rderevision_83396864 - - + + public.RdeRevision - - + + [table] - + tld - + - + text not null - + mode - + - + text not null - + "date" - + - + date not null - + - + registrarpoc_ab47054d - - + + public.RegistrarPoc - - + + [table] - + email_address - + - + text not null - + gae_user_id - + - + text - + registrar_id - + - + text not null - + - + registrylock_ac88663e - - + + public.RegistryLock - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + registrar_id - + - + text not null - + repo_id - + - + text not null - + verification_code - + - + text not null - + relock_revision_id - + - + int8 - + registrylock_ac88663e:w->registrylock_ac88663e:e - - - - - - - - + + + + + + + + fk2lhcwpxlnqijr96irylrh1707 - + reservedentry_1a7b8520 - - + + public.ReservedEntry - - + + [table] - + revision_id - + - + int8 not null - + domain_label - + - + text not null - + - + reservedlist_b97c3f1c - - + + public.ReservedList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + name - + - + text not null - + reservedentry_1a7b8520:w->reservedlist_b97c3f1c:e - - - - - - - - + + + + + + + + fkgq03rk0bt1hb915dnyvd3vnfc - + signedmarkrevocationentry_99c39721 - - + + public.SignedMarkRevocationEntry - - + + [table] - + revision_id - + - + int8 not null - + smd_id - + - + text not null - + - + signedmarkrevocationlist_c5d968fb - - + + public.SignedMarkRevocationList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + signedmarkrevocationentry_99c39721:w->signedmarkrevocationlist_c5d968fb:e - - - - - - - - + + + + + + + + fk5ivlhvs3121yx2li5tqh54u4 - + spec11threatmatch_a61228a6 - - + + public.Spec11ThreatMatch - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + check_date - + - + date not null - + registrar_id - + - + text not null - + tld - + - + text not null - + - + tld_f1fa57e2 - - + + public.Tld - - + + [table] - + tld_name - + - + text not null - + - + transaction_d50389d4 - - + + public.Transaction - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + @@ -4673,6 +4701,41 @@ td.section {

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
public.KmsSecret [table] +
revision_idint8 not null
secret_nametext not null
Primary Key
KmsSecret_pkey[primary key]
revision_id
+

 

diff --git a/db/src/main/resources/sql/er_diagram/full_er_diagram.html b/db/src/main/resources/sql/er_diagram/full_er_diagram.html index c6c3878b7..f35101fa3 100644 --- a/db/src/main/resources/sql/er_diagram/full_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/full_er_diagram.html @@ -261,32 +261,32 @@ td.section { - + - +
public.Lock [table]
generated on2020-10-30 20:47:02.4463352020-10-30 21:56:21.17995
last flyway fileV70__signed_mark_revocation_list.sqlV71__create_kms_secret.sql

 

 

- + SchemaCrawler_Diagram - - + + generated by - + SchemaCrawler 16.10.1 - + generated on - - 2020-10-30 20:47:02.446335 + + 2020-10-30 21:56:21.17995 - + allocationtoken_a08ccbef @@ -745,7 +745,7 @@ td.section { fk_billing_cancellation_billing_recurrence_id - + registrar_6e1503e3 @@ -4798,1092 +4798,1144 @@ td.section { fk3d09knnmxrt6iniwnp8j2ykga - + - lock_f21d4861 - - - public.Lock + kmssecret_f3b28857 + + + public.KmsSecret - - + + [table] - - resource_name - - - - - text not null - - - tld - - - - - text not null - - - acquired_time - - - - - timestamptz not null - - - expiration_time - - - - - timestamptz not null - - - request_log_id - - - - - text not null - - - - - premiumentry_b0060b91 - - - public.PremiumEntry - - - - [table] - - + revision_id - + - + int8 not null - - price + + creation_time - + - - numeric(19, 2) not null - - - domain_label - - - - - text not null - - - - - premiumlist_7c3ea68b - - - public.PremiumList - - - - [table] - - - revision_id - - - - - bigserial not null - - - - - auto-incremented - - - creation_timestamp - - - - + timestamptz not null - + + encrypted_value + + + + + text not null + + + crypto_key_version_name + + + + + text not null + + + secret_name + + + + + text not null + + + + + lock_f21d4861 + + + public.Lock + + + + [table] + + + resource_name + + + + + text not null + + + tld + + + + + text not null + + + acquired_time + + + + + timestamptz not null + + + expiration_time + + + + + timestamptz not null + + + request_log_id + + + + + text not null + + + + + premiumentry_b0060b91 + + + public.PremiumEntry + + + + [table] + + + revision_id + + + + + int8 not null + + + price + + + + + numeric(19, 2) not null + + + domain_label + + + + + text not null + + + + + premiumlist_7c3ea68b + + + public.PremiumList + + + + [table] + + + revision_id + + + + + bigserial not null + + + + + auto-incremented + + + creation_timestamp + + + + + timestamptz not null + + name - + - + text not null - + bloom_filter - + - + bytea not null - + currency - + - + text not null - + premiumentry_b0060b91:w->premiumlist_7c3ea68b:e - - - - - - - - + + + + + + + + fko0gw90lpo1tuee56l0nb6y6g5 - + rderevision_83396864 - - + + public.RdeRevision - - + + [table] - + tld - + - + text not null - + mode - + - + text not null - + "date" - + - + date not null - + update_timestamp - + - + timestamptz - + revision - + - + int4 not null - + - + registrarpoc_ab47054d - - + + public.RegistrarPoc - - + + [table] - + email_address - + - + text not null - + allowed_to_set_registry_lock_password - + - + bool not null - + fax_number - + - + text - + gae_user_id - + - + text - + name - + - + text - + phone_number - + - + text - + registry_lock_password_hash - + - + text - + registry_lock_password_salt - + - + text - + types - + - + _text - + visible_in_domain_whois_as_abuse - + - + bool not null - + visible_in_whois_as_admin - + - + bool not null - + visible_in_whois_as_tech - + - + bool not null - + registry_lock_email_address - + - + text - + registrar_id - + - + text not null - + - + registrylock_ac88663e - - + + public.RegistryLock - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + lock_completion_timestamp - + - + timestamptz - + lock_request_timestamp - + - + timestamptz not null - + domain_name - + - + text not null - + is_superuser - + - + bool not null - + registrar_id - + - + text not null - + registrar_poc_id - + - + text - + repo_id - + - + text not null - + verification_code - + - + text not null - + unlock_request_timestamp - + - + timestamptz - + unlock_completion_timestamp - + - + timestamptz - + last_update_timestamp - + - + timestamptz - + relock_revision_id - + - + int8 - + relock_duration - + - + interval - + registrylock_ac88663e:w->registrylock_ac88663e:e - - - - - - - - + + + + + + + + fk2lhcwpxlnqijr96irylrh1707 - + reservedentry_1a7b8520 - - + + public.ReservedEntry - - + + [table] - + revision_id - + - + int8 not null - + comment - + - + text - + reservation_type - + - + int4 not null - + domain_label - + - + text not null - + - + reservedlist_b97c3f1c - - + + public.ReservedList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + creation_timestamp - + - + timestamptz not null - + name - + - + text not null - + should_publish - + - + bool not null - + reservedentry_1a7b8520:w->reservedlist_b97c3f1c:e - - - - - - - - + + + + + + + + fkgq03rk0bt1hb915dnyvd3vnfc - + signedmarkrevocationentry_99c39721 - - + + public.SignedMarkRevocationEntry - - + + [table] - + revision_id - + - + int8 not null - + revocation_time - + - + timestamptz not null - + smd_id - + - + text not null - + - + signedmarkrevocationlist_c5d968fb - - + + public.SignedMarkRevocationList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + creation_time - + - + timestamptz - + signedmarkrevocationentry_99c39721:w->signedmarkrevocationlist_c5d968fb:e - - - - - - - - + + + + + + + + fk5ivlhvs3121yx2li5tqh54u4 - + spec11threatmatch_a61228a6 - - + + public.Spec11ThreatMatch - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + check_date - + - + date not null - + domain_name - + - + text not null - + domain_repo_id - + - + text not null - + registrar_id - + - + text not null - + threat_types - + - + _text not null - + tld - + - + text not null - + - + tld_f1fa57e2 - - + + public.Tld - - + + [table] - + tld_name - + - + text not null - + add_grace_period_length - + - + interval not null - + allowed_fully_qualified_host_names - + - + _text - + allowed_registrant_contact_ids - + - + _text - + anchor_tenant_add_grace_period_length - + - + interval not null - + auto_renew_grace_period_length - + - + interval not null - + automatic_transfer_length - + - + interval not null - + claims_period_end - + - + timestamptz not null - + create_billing_cost_amount - + - + numeric(19, 2) - + create_billing_cost_currency - + - + text - + creation_time - + - + timestamptz not null - + currency - + - + text not null - + dns_paused - + - + bool not null - + dns_writers - + - + _text not null - + drive_folder_id - + - + text - + eap_fee_schedule - + - + "hstore" not null - + escrow_enabled - + - + bool not null - + invoicing_enabled - + - + bool not null - + lordn_username - + - + text - + num_dns_publish_locks - + - + int4 not null - + pending_delete_length - + - + interval not null - + premium_list_name - + - + text - + pricing_engine_class_name - + - + text - + redemption_grace_period_length - + - + interval not null - + registry_lock_or_unlock_cost_amount - + - + numeric(19, 2) - + registry_lock_or_unlock_cost_currency - + - + text - + renew_billing_cost_transitions - + - + "hstore" not null - + renew_grace_period_length - + - + interval not null - + reserved_list_names - + - + _text - + restore_billing_cost_amount - + - + numeric(19, 2) - + restore_billing_cost_currency - + - + text - + roid_suffix - + - + text - + server_status_change_billing_cost_amount - + - + numeric(19, 2) - + server_status_change_billing_cost_currency - + - + text - + tld_state_transitions - + - + "hstore" not null - + tld_type - + - + text not null - + tld_unicode - + - + text not null - + transfer_grace_period_length - + - + interval not null - + - + transaction_d50389d4 - - + + public.Transaction - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + contents - + - + bytea - + @@ -10066,6 +10118,86 @@ td.section {

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
public.KmsSecret [table] +
revision_idint8 not null
creation_timetimestamptz not null
encrypted_valuetext not null
crypto_key_version_nametext not null
secret_nametext not null
Primary Key
KmsSecret_pkey[primary key]
revision_id
Indexes
KmsSecret_pkey[unique index]
revision_idascending
idxli9nil3s4t4p21i3xluvvilb7[non-unique index]
secret_nameascending
+

 

diff --git a/db/src/main/resources/sql/flyway.txt b/db/src/main/resources/sql/flyway.txt index 8786dedf6..fa017182b 100644 --- a/db/src/main/resources/sql/flyway.txt +++ b/db/src/main/resources/sql/flyway.txt @@ -68,3 +68,4 @@ V67__grace_period_history_ids.sql V68__make_reserved_list_nullable_in_registry.sql V69__change_primary_key_and_add_history_table_for_delegation_signer.sql V70__signed_mark_revocation_list.sql +V71__create_kms_secret.sql diff --git a/db/src/main/resources/sql/flyway/V71__create_kms_secret.sql b/db/src/main/resources/sql/flyway/V71__create_kms_secret.sql new file mode 100644 index 000000000..cf8f3578f --- /dev/null +++ b/db/src/main/resources/sql/flyway/V71__create_kms_secret.sql @@ -0,0 +1,24 @@ +-- Copyright 2020 The Nomulus Authors. All Rights Reserved. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +CREATE TABLE "KmsSecret" ( + revision_id int8 NOT NULL, + creation_time timestamptz NOT NULL, + encrypted_value text NOT NULL, + crypto_key_version_name text NOT NULL, + secret_name text NOT NULL, + PRIMARY KEY (revision_id) +); + +CREATE INDEX IDXli9nil3s4t4p21i3xluvvilb7 ON "KmsSecret" (secret_name); diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index 4ab776dbc..d58973af7 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -452,6 +452,15 @@ primary key (host_repo_id, history_revision_id) ); + create table "KmsSecret" ( + revision_id int8 not null, + creation_time timestamptz not null, + encrypted_value text not null, + crypto_key_version_name text not null, + secret_name text not null, + primary key (revision_id) + ); + create table "Lock" ( resource_name text not null, tld text not null, @@ -727,6 +736,7 @@ create index IDX1iy7njgb7wjmj9piml4l2g0qi on "HostHistory" (history_registrar_id create index IDXkkwbwcwvrdkkqothkiye4jiff on "HostHistory" (host_name); create index IDXknk8gmj7s47q56cwpa6rmpt5l on "HostHistory" (history_type); create index IDX67qwkjtlq5q8dv6egtrtnhqi7 on "HostHistory" (history_modification_time); +create index IDXli9nil3s4t4p21i3xluvvilb7 on "KmsSecret" (secret_name); create index IDXe7wu46c7wpvfmfnj4565abibp on "PollMessage" (registrar_id); create index IDXaydgox62uno9qx8cjlj5lauye on "PollMessage" (event_time); create index premiumlist_name_idx on "PremiumList" (name); diff --git a/db/src/main/resources/sql/schema/nomulus.golden.sql b/db/src/main/resources/sql/schema/nomulus.golden.sql index 3d6f5495b..5f1667a9f 100644 --- a/db/src/main/resources/sql/schema/nomulus.golden.sql +++ b/db/src/main/resources/sql/schema/nomulus.golden.sql @@ -590,6 +590,19 @@ CREATE TABLE public."HostHistory" ( ); +-- +-- Name: KmsSecret; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."KmsSecret" ( + revision_id bigint NOT NULL, + creation_time timestamp with time zone NOT NULL, + encrypted_value text NOT NULL, + crypto_key_version_name text NOT NULL, + secret_name text NOT NULL +); + + -- -- Name: Lock; Type: TABLE; Schema: public; Owner: - -- @@ -1193,6 +1206,14 @@ ALTER TABLE ONLY public."Host" ADD CONSTRAINT "Host_pkey" PRIMARY KEY (repo_id); +-- +-- Name: KmsSecret KmsSecret_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."KmsSecret" + ADD CONSTRAINT "KmsSecret_pkey" PRIMARY KEY (revision_id); + + -- -- Name: Lock Lock_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -1538,6 +1559,13 @@ CREATE INDEX idxkjt9yaq92876dstimd93hwckh ON public."Domain" USING btree (curren CREATE INDEX idxknk8gmj7s47q56cwpa6rmpt5l ON public."HostHistory" USING btree (history_type); +-- +-- Name: idxli9nil3s4t4p21i3xluvvilb7; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idxli9nil3s4t4p21i3xluvvilb7 ON public."KmsSecret" USING btree (secret_name); + + -- -- Name: idxlrq7v63pc21uoh3auq6eybyhl; Type: INDEX; Schema: public; Owner: - --
public.Lock [table]