mirror of
https://github.com/google/nomulus
synced 2025-12-23 14:25:44 +00:00
Save Cloud SQL connection names in Keyring (#2622)
This eliminates the need to make a new release after database disaster recovery.
This commit is contained in:
@@ -124,7 +124,9 @@ public abstract class DummyKeyringModule {
|
||||
"not a real login",
|
||||
"not a real credential",
|
||||
"not a real password",
|
||||
"not a real password");
|
||||
"not a real password",
|
||||
"not the real primary connection",
|
||||
"not the real replica connection");
|
||||
}
|
||||
|
||||
private DummyKeyringModule() {}
|
||||
|
||||
@@ -39,6 +39,8 @@ public final class InMemoryKeyring implements Keyring {
|
||||
private final String marksdbLordnPassword;
|
||||
private final String marksdbSmdrlLoginAndPassword;
|
||||
private final String bsaApiKey;
|
||||
private final String sqlPrimaryConnectionName;
|
||||
private final String sqlReplicaConnectionName;
|
||||
|
||||
public InMemoryKeyring(
|
||||
PGPKeyPair rdeStagingKey,
|
||||
@@ -55,7 +57,9 @@ public final class InMemoryKeyring implements Keyring {
|
||||
String marksdbSmdrlLoginAndPassword,
|
||||
String cloudSqlPassword,
|
||||
String toolsCloudSqlPassword,
|
||||
String bsaApiKey) {
|
||||
String bsaApiKey,
|
||||
String sqlPrimaryConnectionName,
|
||||
String sqlReplicaConnectionName) {
|
||||
checkArgument(PgpHelper.isSigningKey(rdeSigningKey.getPublicKey()),
|
||||
"RDE signing key must support signing: %s", rdeSigningKey.getKeyID());
|
||||
checkArgument(rdeStagingKey.getPublicKey().isEncryptionKey(),
|
||||
@@ -81,6 +85,8 @@ public final class InMemoryKeyring implements Keyring {
|
||||
this.marksdbSmdrlLoginAndPassword =
|
||||
checkNotNull(marksdbSmdrlLoginAndPassword, "marksdbSmdrlLoginAndPassword");
|
||||
this.bsaApiKey = checkNotNull(bsaApiKey, "bsaApiKey");
|
||||
this.sqlPrimaryConnectionName = sqlPrimaryConnectionName;
|
||||
this.sqlReplicaConnectionName = sqlReplicaConnectionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +159,16 @@ public final class InMemoryKeyring implements Keyring {
|
||||
return bsaApiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlPrimaryConnectionName() {
|
||||
return sqlPrimaryConnectionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlReplicaConnectionName() {
|
||||
return sqlReplicaConnectionName;
|
||||
}
|
||||
|
||||
/** Does nothing. */
|
||||
@Override
|
||||
public void close() {}
|
||||
|
||||
@@ -148,6 +148,12 @@ public interface Keyring extends AutoCloseable {
|
||||
/** Returns the API_KEY for authentication with the BSA portal. */
|
||||
String getBsaApiKey();
|
||||
|
||||
/** Returns the Cloud SQL connection name of the primary database instance. */
|
||||
String getSqlPrimaryConnectionName();
|
||||
|
||||
/** Returns the Cloud SQL connection name of the replica database instance. */
|
||||
String getSqlReplicaConnectionName();
|
||||
|
||||
// Don't throw so try-with-resources works better.
|
||||
@Override
|
||||
void close();
|
||||
|
||||
@@ -57,14 +57,16 @@ public class SecretManagerKeyring implements Keyring {
|
||||
|
||||
/** Key labels for string secrets. */
|
||||
enum StringKeyLabel {
|
||||
SAFE_BROWSING_API_KEY,
|
||||
BSA_API_KEY_STRING,
|
||||
ICANN_REPORTING_PASSWORD_STRING,
|
||||
MARKSDB_DNL_LOGIN_STRING,
|
||||
MARKSDB_LORDN_PASSWORD_STRING,
|
||||
MARKSDB_SMDRL_LOGIN_STRING,
|
||||
RDE_SSH_CLIENT_PRIVATE_STRING,
|
||||
RDE_SSH_CLIENT_PUBLIC_STRING;
|
||||
RDE_SSH_CLIENT_PUBLIC_STRING,
|
||||
SAFE_BROWSING_API_KEY,
|
||||
SQL_PRIMARY_CONN_NAME,
|
||||
SQL_REPLICA_CONN_NAME;
|
||||
|
||||
String getLabel() {
|
||||
return UPPER_UNDERSCORE.to(LOWER_HYPHEN, name());
|
||||
@@ -148,6 +150,16 @@ public class SecretManagerKeyring implements Keyring {
|
||||
return getString(StringKeyLabel.BSA_API_KEY_STRING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlPrimaryConnectionName() {
|
||||
return getString(StringKeyLabel.SQL_PRIMARY_CONN_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlReplicaConnectionName() {
|
||||
return getString(StringKeyLabel.SQL_REPLICA_CONN_NAME);
|
||||
}
|
||||
|
||||
/** No persistent resources are maintained for this Keyring implementation. */
|
||||
@Override
|
||||
public void close() {}
|
||||
|
||||
@@ -32,6 +32,8 @@ import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringK
|
||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.RDE_SSH_CLIENT_PRIVATE_STRING;
|
||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.RDE_SSH_CLIENT_PUBLIC_STRING;
|
||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.SAFE_BROWSING_API_KEY;
|
||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.SQL_PRIMARY_CONN_NAME;
|
||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.SQL_REPLICA_CONN_NAME;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
@@ -124,6 +126,14 @@ public final class SecretManagerKeyringUpdater {
|
||||
return setString(credential, BSA_API_KEY_STRING);
|
||||
}
|
||||
|
||||
public SecretManagerKeyringUpdater setSqlPrimaryConnectionName(String name) {
|
||||
return setString(name, SQL_PRIMARY_CONN_NAME);
|
||||
}
|
||||
|
||||
public SecretManagerKeyringUpdater setSqlReplicaConnectionName(String name) {
|
||||
return setString(name, SQL_REPLICA_CONN_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the secrets in the Secret Manager.
|
||||
*
|
||||
|
||||
@@ -64,8 +64,6 @@ final class GetKeyringSecretCommand implements Command {
|
||||
case BSA_API_KEY -> out.write(KeySerializer.serializeString(keyring.getBsaApiKey()));
|
||||
case ICANN_REPORTING_PASSWORD ->
|
||||
out.write(KeySerializer.serializeString(keyring.getIcannReportingPassword()));
|
||||
case SAFE_BROWSING_API_KEY ->
|
||||
out.write(KeySerializer.serializeString(keyring.getSafeBrowsingAPIKey()));
|
||||
case MARKSDB_DNL_LOGIN_AND_PASSWORD ->
|
||||
out.write(KeySerializer.serializeString(keyring.getMarksdbDnlLoginAndPassword()));
|
||||
case MARKSDB_LORDN_PASSWORD ->
|
||||
@@ -91,6 +89,12 @@ final class GetKeyringSecretCommand implements Command {
|
||||
keyring.getRdeStagingEncryptionKey(), keyring.getRdeStagingDecryptionKey())));
|
||||
case RDE_STAGING_PUBLIC_KEY ->
|
||||
out.write(KeySerializer.serializePublicKey(keyring.getRdeStagingEncryptionKey()));
|
||||
case SAFE_BROWSING_API_KEY ->
|
||||
out.write(KeySerializer.serializeString(keyring.getSafeBrowsingAPIKey()));
|
||||
case SQL_PRIMARY_CONN_NAME ->
|
||||
out.write(KeySerializer.serializeString(keyring.getSqlPrimaryConnectionName()));
|
||||
case SQL_REPLICA_CONN_NAME ->
|
||||
out.write(KeySerializer.serializeString(keyring.getSqlReplicaConnectionName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,12 +90,16 @@ final class UpdateKeyringSecretCommand implements Command {
|
||||
secretManagerKeyringUpdater.setRdeSshClientPublicKey(deserializeString(input));
|
||||
case RDE_STAGING_KEY_PAIR ->
|
||||
secretManagerKeyringUpdater.setRdeStagingKey(deserializeKeyPair(input));
|
||||
case SAFE_BROWSING_API_KEY ->
|
||||
secretManagerKeyringUpdater.setSafeBrowsingAPIKey(deserializeString(input));
|
||||
case RDE_STAGING_PUBLIC_KEY ->
|
||||
throw new IllegalArgumentException(
|
||||
"Can't update RDE_STAGING_PUBLIC_KEY directly."
|
||||
+ " Must update public and private keys together using RDE_STAGING_KEY_PAIR.");
|
||||
case SAFE_BROWSING_API_KEY ->
|
||||
secretManagerKeyringUpdater.setSafeBrowsingAPIKey(deserializeString(input));
|
||||
case SQL_PRIMARY_CONN_NAME ->
|
||||
secretManagerKeyringUpdater.setSqlPrimaryConnectionName(deserializeString(input));
|
||||
case SQL_REPLICA_CONN_NAME ->
|
||||
secretManagerKeyringUpdater.setSqlReplicaConnectionName(deserializeString(input));
|
||||
}
|
||||
|
||||
secretManagerKeyringUpdater.update();
|
||||
|
||||
@@ -36,5 +36,7 @@ public enum KeyringKeyName {
|
||||
RDE_SSH_CLIENT_PUBLIC_KEY,
|
||||
RDE_STAGING_KEY_PAIR,
|
||||
RDE_STAGING_PUBLIC_KEY,
|
||||
SAFE_BROWSING_API_KEY
|
||||
SAFE_BROWSING_API_KEY,
|
||||
SQL_PRIMARY_CONN_NAME,
|
||||
SQL_REPLICA_CONN_NAME
|
||||
}
|
||||
|
||||
@@ -102,6 +102,24 @@ public class SecretManagerKeyringUpdaterTest {
|
||||
verifyPersistedSecret("bsa-api-key-string", secret);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sqlPrimaryConnectionName() {
|
||||
String name = "name";
|
||||
updater.setSqlPrimaryConnectionName(name).update();
|
||||
|
||||
assertThat(keyring.getSqlPrimaryConnectionName()).isEqualTo(name);
|
||||
verifyPersistedSecret("sql-primary-conn-name", name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sqlReplicaConnectionName() {
|
||||
String name = "name";
|
||||
updater.setSqlReplicaConnectionName(name).update();
|
||||
|
||||
assertThat(keyring.getSqlReplicaConnectionName()).isEqualTo(name);
|
||||
verifyPersistedSecret("sql-replica-conn-name", name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void marksdbDnlLoginAndPassword() {
|
||||
String secret = "marksdbDnlLoginAndPassword";
|
||||
|
||||
@@ -56,6 +56,8 @@ public final class FakeKeyringModule {
|
||||
private static final String MARKSDB_LORDN_PASSWORD = "yolo";
|
||||
private static final String MARKSDB_SMDRL_LOGIN_AND_PASSWORD = "smdrl:yolo";
|
||||
private static final String BSA_API_KEY = "bsaapikey";
|
||||
private static final String SQL_PRIMARY_CONNECTION = "project:primary-region:primary-name";
|
||||
private static final String SQL_REPLICA_CONNECTION = "project:replica-region:replica-name";
|
||||
|
||||
@Provides
|
||||
public Keyring get() {
|
||||
@@ -151,6 +153,16 @@ public final class FakeKeyringModule {
|
||||
return rdeReceiverKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlPrimaryConnectionName() {
|
||||
return SQL_PRIMARY_CONNECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSqlReplicaConnectionName() {
|
||||
return SQL_REPLICA_CONNECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user