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]