Add configurations for Cloud SQL secrets (#266)

This commit is contained in:
Shicong Huang 2019-09-11 12:20:08 -04:00 committed by GitHub
parent 401653ad4a
commit 48d8b1274f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 95 additions and 8 deletions

View file

@ -392,6 +392,24 @@ public final class RegistryConfig {
return config.datastore.eppResourceIndexBucketsNum; return config.datastore.eppResourceIndexBucketsNum;
} }
@Provides
@Config("cloudSqlJdbcUrl")
public static String providesCloudSqlJdbcUrl(RegistryConfigSettings config) {
return config.cloudSql.jdbcUrl;
}
@Provides
@Config("cloudSqlUsername")
public static String providesCloudSqlUsername(RegistryConfigSettings config) {
return config.cloudSql.username;
}
@Provides
@Config("cloudSqlInstanceConnectionName")
public static String providesCloudSqlInstanceConnectionName(RegistryConfigSettings config) {
return config.cloudSql.instanceConnectionName;
}
@Provides @Provides
@Config("cloudDnsRootUrl") @Config("cloudDnsRootUrl")
public static Optional<String> getCloudDnsRootUrl(RegistryConfigSettings config) { public static Optional<String> getCloudDnsRootUrl(RegistryConfigSettings config) {
@ -1469,11 +1487,6 @@ public final class RegistryConfig {
return CONFIG_SETTINGS.get().hibernate.logSqlQueries; return CONFIG_SETTINGS.get().hibernate.logSqlQueries;
} }
/** Returns true if schema modification is allowed. */
public static String getHibernateHbm2ddlAuto() {
return CONFIG_SETTINGS.get().hibernate.hbm2ddlAuto;
}
/** Returns the connection timeout for HikariCP. */ /** Returns the connection timeout for HikariCP. */
public static String getHibernateHikariConnectionTimeout() { public static String getHibernateHikariConnectionTimeout() {
return CONFIG_SETTINGS.get().hibernate.hikariConnectionTimeout; return CONFIG_SETTINGS.get().hibernate.hikariConnectionTimeout;

View file

@ -26,6 +26,7 @@ public class RegistryConfigSettings {
public RegistryPolicy registryPolicy; public RegistryPolicy registryPolicy;
public Datastore datastore; public Datastore datastore;
public Hibernate hibernate; public Hibernate hibernate;
public CloudSql cloudSql;
public CloudDns cloudDns; public CloudDns cloudDns;
public Caching caching; public Caching caching;
public IcannReporting icannReporting; public IcannReporting icannReporting;
@ -110,13 +111,19 @@ public class RegistryConfigSettings {
public static class Hibernate { public static class Hibernate {
public String connectionIsolation; public String connectionIsolation;
public String logSqlQueries; public String logSqlQueries;
public String hbm2ddlAuto;
public String hikariConnectionTimeout; public String hikariConnectionTimeout;
public String hikariMinimumIdle; public String hikariMinimumIdle;
public String hikariMaximumPoolSize; public String hikariMaximumPoolSize;
public String hikariIdleTimeout; public String hikariIdleTimeout;
} }
/** Configuration for Cloud SQL. */
public static class CloudSql {
public String jdbcUrl;
public String username;
public String instanceConnectionName;
}
/** Configuration for Apache Beam (Cloud Dataflow). */ /** Configuration for Apache Beam (Cloud Dataflow). */
public static class Beam { public static class Beam {
public String defaultJobZone; public String defaultJobZone;

View file

@ -211,6 +211,14 @@ hibernate:
hikariMaximumPoolSize: 20 hikariMaximumPoolSize: 20
hikariIdleTimeout: 300000 hikariIdleTimeout: 300000
cloudSql:
# jdbc url for the Cloud SQL database.
jdbcUrl: jdbc:postgresql://localhost
# Username for the database user.
username: username
# This name is used by Cloud SQL when connecting to the database.
instanceConnectionName: project-id:region:instance-id
cloudDns: cloudDns:
# Set both properties to null in Production. # Set both properties to null in Production.
# The root url for the Cloud DNS API. Set this to a non-null value to # The root url for the Cloud DNS API. Set this to a non-null value to

View file

@ -122,7 +122,8 @@ public abstract class DummyKeyringModule {
"not a real login", "not a real login",
"not a real password", "not a real password",
"not a real login", "not a real login",
"not a real credential"); "not a real credential",
"not a real password");
} }
private DummyKeyringModule() {} private DummyKeyringModule() {}

View file

@ -39,6 +39,7 @@ public final class InMemoryKeyring implements Keyring {
private final String marksdbLordnPassword; private final String marksdbLordnPassword;
private final String marksdbSmdrlLoginAndPassword; private final String marksdbSmdrlLoginAndPassword;
private final String jsonCredential; private final String jsonCredential;
private final String cloudSqlPassword;
public InMemoryKeyring( public InMemoryKeyring(
PGPKeyPair rdeStagingKey, PGPKeyPair rdeStagingKey,
@ -53,7 +54,8 @@ public final class InMemoryKeyring implements Keyring {
String marksdbDnlLoginAndPassword, String marksdbDnlLoginAndPassword,
String marksdbLordnPassword, String marksdbLordnPassword,
String marksdbSmdrlLoginAndPassword, String marksdbSmdrlLoginAndPassword,
String jsonCredential) { String jsonCredential,
String cloudSqlPassword) {
checkArgument(PgpHelper.isSigningKey(rdeSigningKey.getPublicKey()), checkArgument(PgpHelper.isSigningKey(rdeSigningKey.getPublicKey()),
"RDE signing key must support signing: %s", rdeSigningKey.getKeyID()); "RDE signing key must support signing: %s", rdeSigningKey.getKeyID());
checkArgument(rdeStagingKey.getPublicKey().isEncryptionKey(), checkArgument(rdeStagingKey.getPublicKey().isEncryptionKey(),
@ -79,6 +81,7 @@ public final class InMemoryKeyring implements Keyring {
this.marksdbSmdrlLoginAndPassword = this.marksdbSmdrlLoginAndPassword =
checkNotNull(marksdbSmdrlLoginAndPassword, "marksdbSmdrlLoginAndPassword"); checkNotNull(marksdbSmdrlLoginAndPassword, "marksdbSmdrlLoginAndPassword");
this.jsonCredential = checkNotNull(jsonCredential, "jsonCredential"); this.jsonCredential = checkNotNull(jsonCredential, "jsonCredential");
this.cloudSqlPassword = checkNotNull(cloudSqlPassword, "cloudSqlPassword");
} }
@Override @Override
@ -151,6 +154,11 @@ public final class InMemoryKeyring implements Keyring {
return jsonCredential; return jsonCredential;
} }
@Override
public String getCloudSqlPassword() {
return cloudSqlPassword;
}
/** Does nothing. */ /** Does nothing. */
@Override @Override
public void close() {} public void close() {}

View file

@ -36,6 +36,12 @@ public final class KeyModule {
String value(); String value();
} }
@Provides
@Key("cloudSqlPassword")
static String providesCloudSqlPassword(Keyring keyring) {
return keyring.getCloudSqlPassword();
}
@Provides @Provides
@Key("brdaReceiverKey") @Key("brdaReceiverKey")
static PGPPublicKey provideBrdaReceiverKey(Keyring keyring) { static PGPPublicKey provideBrdaReceiverKey(Keyring keyring) {

View file

@ -28,6 +28,9 @@ import org.bouncycastle.openpgp.PGPPublicKey;
@ThreadSafe @ThreadSafe
public interface Keyring extends AutoCloseable { public interface Keyring extends AutoCloseable {
/** Returns the password which is used to connect to the Cloud SQL database. */
String getCloudSqlPassword();
/** /**
* Returns the key which should be used to sign RDE deposits being uploaded to a third-party. * Returns the key which should be used to sign RDE deposits being uploaded to a third-party.
* *

View file

@ -67,6 +67,7 @@ public class KmsKeyring implements Keyring {
/** Key labels for string secrets. */ /** Key labels for string secrets. */
enum StringKeyLabel { enum StringKeyLabel {
CLOUD_SQL_PASSWORD_STRING,
SAFE_BROWSING_API_KEY, SAFE_BROWSING_API_KEY,
ICANN_REPORTING_PASSWORD_STRING, ICANN_REPORTING_PASSWORD_STRING,
JSON_CREDENTIAL_STRING, JSON_CREDENTIAL_STRING,
@ -88,6 +89,11 @@ public class KmsKeyring implements Keyring {
this.kmsConnection = kmsConnection; this.kmsConnection = kmsConnection;
} }
@Override
public String getCloudSqlPassword() {
return getString(StringKeyLabel.CLOUD_SQL_PASSWORD_STRING);
}
@Override @Override
public PGPKeyPair getRdeSigningKey() { public PGPKeyPair getRdeSigningKey() {
return getKeyPair(PrivateKeyLabel.RDE_SIGNING_PRIVATE); return getKeyPair(PrivateKeyLabel.RDE_SIGNING_PRIVATE);

View file

@ -24,6 +24,7 @@ import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.BRDA_SIGNING
import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_RECEIVER_PUBLIC; import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_RECEIVER_PUBLIC;
import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_SIGNING_PUBLIC; import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_SIGNING_PUBLIC;
import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_STAGING_PUBLIC; import static google.registry.keyring.kms.KmsKeyring.PublicKeyLabel.RDE_STAGING_PUBLIC;
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.CLOUD_SQL_PASSWORD_STRING;
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.ICANN_REPORTING_PASSWORD_STRING; import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.ICANN_REPORTING_PASSWORD_STRING;
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.JSON_CREDENTIAL_STRING; import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.JSON_CREDENTIAL_STRING;
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.MARKSDB_DNL_LOGIN_STRING; import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.MARKSDB_DNL_LOGIN_STRING;
@ -69,6 +70,10 @@ public final class KmsUpdater {
this.secretValues = new LinkedHashMap<>(); this.secretValues = new LinkedHashMap<>();
} }
public KmsUpdater setCloudSqlPassword(String password) {
return setString(password, CLOUD_SQL_PASSWORD_STRING);
}
public KmsUpdater setRdeSigningKey(PGPKeyPair keyPair) throws IOException, PGPException { public KmsUpdater setRdeSigningKey(PGPKeyPair keyPair) throws IOException, PGPException {
return setKeyPair(keyPair, RDE_SIGNING_PRIVATE, RDE_SIGNING_PUBLIC); return setKeyPair(keyPair, RDE_SIGNING_PRIVATE, RDE_SIGNING_PUBLIC);
} }

View file

@ -65,6 +65,9 @@ final class GetKeyringSecretCommand implements CommandWithRemoteApi {
case BRDA_SIGNING_PUBLIC_KEY: case BRDA_SIGNING_PUBLIC_KEY:
out.write(KeySerializer.serializePublicKey(keyring.getBrdaSigningKey().getPublicKey())); out.write(KeySerializer.serializePublicKey(keyring.getBrdaSigningKey().getPublicKey()));
break; break;
case CLOUD_SQL_PASSWORD:
out.write(KeySerializer.serializeString(keyring.getCloudSqlPassword()));
break;
case ICANN_REPORTING_PASSWORD: case ICANN_REPORTING_PASSWORD:
out.write(KeySerializer.serializeString(keyring.getIcannReportingPassword())); out.write(KeySerializer.serializeString(keyring.getIcannReportingPassword()));
break; break;

View file

@ -65,6 +65,9 @@ final class UpdateKmsKeyringCommand implements CommandWithRemoteApi {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't update BRDA_SIGNING_PUBLIC_KEY directly." "Can't update BRDA_SIGNING_PUBLIC_KEY directly."
+ " Must update public and private keys together using BRDA_SIGNING_KEY_PAIR."); + " Must update public and private keys together using BRDA_SIGNING_KEY_PAIR.");
case CLOUD_SQL_PASSWORD:
kmsUpdater.setCloudSqlPassword(deserializeString(input));
break;
case ICANN_REPORTING_PASSWORD: case ICANN_REPORTING_PASSWORD:
kmsUpdater.setIcannReportingPassword(deserializeString(input)); kmsUpdater.setIcannReportingPassword(deserializeString(input));
break; break;

View file

@ -24,6 +24,7 @@ public enum KeyringKeyName {
BRDA_RECEIVER_PUBLIC_KEY, BRDA_RECEIVER_PUBLIC_KEY,
BRDA_SIGNING_KEY_PAIR, BRDA_SIGNING_KEY_PAIR,
BRDA_SIGNING_PUBLIC_KEY, BRDA_SIGNING_PUBLIC_KEY,
CLOUD_SQL_PASSWORD,
ICANN_REPORTING_PASSWORD, ICANN_REPORTING_PASSWORD,
JSON_CREDENTIAL, JSON_CREDENTIAL,
MARKSDB_DNL_LOGIN_AND_PASSWORD, MARKSDB_DNL_LOGIN_AND_PASSWORD,

View file

@ -46,6 +46,15 @@ public class KmsKeyringTest {
keyring = new KmsKeyring(new FakeKmsConnection()); keyring = new KmsKeyring(new FakeKmsConnection());
} }
@Test
public void test_getCloudSqlPassword() throws Exception {
saveCleartextSecret("cloud-sql-password-string");
String cloudSqlPassword = keyring.getCloudSqlPassword();
assertThat(cloudSqlPassword).isEqualTo("cloud-sql-password-stringmoo");
}
@Test @Test
public void test_getRdeSigningKey() throws Exception { public void test_getRdeSigningKey() throws Exception {
saveKeyPairSecret("rde-signing-public", "rde-signing-private"); saveKeyPairSecret("rde-signing-public", "rde-signing-private");

View file

@ -91,6 +91,14 @@ public class KmsUpdaterTest {
getCiphertext(KmsTestHelper.getPublicKey())); getCiphertext(KmsTestHelper.getPublicKey()));
} }
@Test
public void test_setCloudSqlPassword() {
updater.setCloudSqlPassword("value1").update();
verifySecretAndSecretRevisionWritten(
"cloud-sql-password-string", "cloud-sql-password-string/foo", getCiphertext("value1"));
}
@Test @Test
public void test_setIcannReportingPassword() { public void test_setIcannReportingPassword() {
updater.setIcannReportingPassword("value1").update(); updater.setIcannReportingPassword("value1").update();

View file

@ -56,6 +56,7 @@ public final class FakeKeyringModule {
private static final String MARKSDB_LORDN_PASSWORD = "yolo"; private static final String MARKSDB_LORDN_PASSWORD = "yolo";
private static final String MARKSDB_SMDRL_LOGIN_AND_PASSWORD = "smdrl:yolo"; private static final String MARKSDB_SMDRL_LOGIN_AND_PASSWORD = "smdrl:yolo";
private static final String JSON_CREDENTIAL = "json123"; private static final String JSON_CREDENTIAL = "json123";
private static final String CLOUD_SQL_PASSWORD = "cloudsqlpw";
@Provides @Provides
public Keyring get() { public Keyring get() {
@ -80,6 +81,11 @@ public final class FakeKeyringModule {
final String sshPrivate = loadFile(FakeKeyringModule.class, "registry-unittest.id_rsa"); final String sshPrivate = loadFile(FakeKeyringModule.class, "registry-unittest.id_rsa");
return new Keyring() { return new Keyring() {
@Override
public String getCloudSqlPassword() {
return CLOUD_SQL_PASSWORD;
}
@Override @Override
public PGPPublicKey getRdeStagingEncryptionKey() { public PGPPublicKey getRdeStagingEncryptionKey() {
return rdeStagingKey.getPublicKey(); return rdeStagingKey.getPublicKey();