mirror of
https://github.com/google/nomulus
synced 2025-12-23 06:15:42 +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 login",
|
||||||
"not a real credential",
|
"not a real credential",
|
||||||
"not a real password",
|
"not a real password",
|
||||||
"not a real password");
|
"not a real password",
|
||||||
|
"not the real primary connection",
|
||||||
|
"not the real replica connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
private DummyKeyringModule() {}
|
private DummyKeyringModule() {}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ 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 bsaApiKey;
|
private final String bsaApiKey;
|
||||||
|
private final String sqlPrimaryConnectionName;
|
||||||
|
private final String sqlReplicaConnectionName;
|
||||||
|
|
||||||
public InMemoryKeyring(
|
public InMemoryKeyring(
|
||||||
PGPKeyPair rdeStagingKey,
|
PGPKeyPair rdeStagingKey,
|
||||||
@@ -55,7 +57,9 @@ public final class InMemoryKeyring implements Keyring {
|
|||||||
String marksdbSmdrlLoginAndPassword,
|
String marksdbSmdrlLoginAndPassword,
|
||||||
String cloudSqlPassword,
|
String cloudSqlPassword,
|
||||||
String toolsCloudSqlPassword,
|
String toolsCloudSqlPassword,
|
||||||
String bsaApiKey) {
|
String bsaApiKey,
|
||||||
|
String sqlPrimaryConnectionName,
|
||||||
|
String sqlReplicaConnectionName) {
|
||||||
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(),
|
||||||
@@ -81,6 +85,8 @@ public final class InMemoryKeyring implements Keyring {
|
|||||||
this.marksdbSmdrlLoginAndPassword =
|
this.marksdbSmdrlLoginAndPassword =
|
||||||
checkNotNull(marksdbSmdrlLoginAndPassword, "marksdbSmdrlLoginAndPassword");
|
checkNotNull(marksdbSmdrlLoginAndPassword, "marksdbSmdrlLoginAndPassword");
|
||||||
this.bsaApiKey = checkNotNull(bsaApiKey, "bsaApiKey");
|
this.bsaApiKey = checkNotNull(bsaApiKey, "bsaApiKey");
|
||||||
|
this.sqlPrimaryConnectionName = sqlPrimaryConnectionName;
|
||||||
|
this.sqlReplicaConnectionName = sqlReplicaConnectionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -153,6 +159,16 @@ public final class InMemoryKeyring implements Keyring {
|
|||||||
return bsaApiKey;
|
return bsaApiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlPrimaryConnectionName() {
|
||||||
|
return sqlPrimaryConnectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlReplicaConnectionName() {
|
||||||
|
return sqlReplicaConnectionName;
|
||||||
|
}
|
||||||
|
|
||||||
/** Does nothing. */
|
/** Does nothing. */
|
||||||
@Override
|
@Override
|
||||||
public void close() {}
|
public void close() {}
|
||||||
|
|||||||
@@ -148,6 +148,12 @@ public interface Keyring extends AutoCloseable {
|
|||||||
/** Returns the API_KEY for authentication with the BSA portal. */
|
/** Returns the API_KEY for authentication with the BSA portal. */
|
||||||
String getBsaApiKey();
|
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.
|
// Don't throw so try-with-resources works better.
|
||||||
@Override
|
@Override
|
||||||
void close();
|
void close();
|
||||||
|
|||||||
@@ -57,14 +57,16 @@ public class SecretManagerKeyring implements Keyring {
|
|||||||
|
|
||||||
/** Key labels for string secrets. */
|
/** Key labels for string secrets. */
|
||||||
enum StringKeyLabel {
|
enum StringKeyLabel {
|
||||||
SAFE_BROWSING_API_KEY,
|
|
||||||
BSA_API_KEY_STRING,
|
BSA_API_KEY_STRING,
|
||||||
ICANN_REPORTING_PASSWORD_STRING,
|
ICANN_REPORTING_PASSWORD_STRING,
|
||||||
MARKSDB_DNL_LOGIN_STRING,
|
MARKSDB_DNL_LOGIN_STRING,
|
||||||
MARKSDB_LORDN_PASSWORD_STRING,
|
MARKSDB_LORDN_PASSWORD_STRING,
|
||||||
MARKSDB_SMDRL_LOGIN_STRING,
|
MARKSDB_SMDRL_LOGIN_STRING,
|
||||||
RDE_SSH_CLIENT_PRIVATE_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() {
|
String getLabel() {
|
||||||
return UPPER_UNDERSCORE.to(LOWER_HYPHEN, name());
|
return UPPER_UNDERSCORE.to(LOWER_HYPHEN, name());
|
||||||
@@ -148,6 +150,16 @@ public class SecretManagerKeyring implements Keyring {
|
|||||||
return getString(StringKeyLabel.BSA_API_KEY_STRING);
|
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. */
|
/** No persistent resources are maintained for this Keyring implementation. */
|
||||||
@Override
|
@Override
|
||||||
public void close() {}
|
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_PRIVATE_STRING;
|
||||||
import static google.registry.keyring.secretmanager.SecretManagerKeyring.StringKeyLabel.RDE_SSH_CLIENT_PUBLIC_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.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 static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||||
|
|
||||||
import com.google.common.flogger.FluentLogger;
|
import com.google.common.flogger.FluentLogger;
|
||||||
@@ -124,6 +126,14 @@ public final class SecretManagerKeyringUpdater {
|
|||||||
return setString(credential, BSA_API_KEY_STRING);
|
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.
|
* 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 BSA_API_KEY -> out.write(KeySerializer.serializeString(keyring.getBsaApiKey()));
|
||||||
case ICANN_REPORTING_PASSWORD ->
|
case ICANN_REPORTING_PASSWORD ->
|
||||||
out.write(KeySerializer.serializeString(keyring.getIcannReportingPassword()));
|
out.write(KeySerializer.serializeString(keyring.getIcannReportingPassword()));
|
||||||
case SAFE_BROWSING_API_KEY ->
|
|
||||||
out.write(KeySerializer.serializeString(keyring.getSafeBrowsingAPIKey()));
|
|
||||||
case MARKSDB_DNL_LOGIN_AND_PASSWORD ->
|
case MARKSDB_DNL_LOGIN_AND_PASSWORD ->
|
||||||
out.write(KeySerializer.serializeString(keyring.getMarksdbDnlLoginAndPassword()));
|
out.write(KeySerializer.serializeString(keyring.getMarksdbDnlLoginAndPassword()));
|
||||||
case MARKSDB_LORDN_PASSWORD ->
|
case MARKSDB_LORDN_PASSWORD ->
|
||||||
@@ -91,6 +89,12 @@ final class GetKeyringSecretCommand implements Command {
|
|||||||
keyring.getRdeStagingEncryptionKey(), keyring.getRdeStagingDecryptionKey())));
|
keyring.getRdeStagingEncryptionKey(), keyring.getRdeStagingDecryptionKey())));
|
||||||
case RDE_STAGING_PUBLIC_KEY ->
|
case RDE_STAGING_PUBLIC_KEY ->
|
||||||
out.write(KeySerializer.serializePublicKey(keyring.getRdeStagingEncryptionKey()));
|
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));
|
secretManagerKeyringUpdater.setRdeSshClientPublicKey(deserializeString(input));
|
||||||
case RDE_STAGING_KEY_PAIR ->
|
case RDE_STAGING_KEY_PAIR ->
|
||||||
secretManagerKeyringUpdater.setRdeStagingKey(deserializeKeyPair(input));
|
secretManagerKeyringUpdater.setRdeStagingKey(deserializeKeyPair(input));
|
||||||
case SAFE_BROWSING_API_KEY ->
|
|
||||||
secretManagerKeyringUpdater.setSafeBrowsingAPIKey(deserializeString(input));
|
|
||||||
case RDE_STAGING_PUBLIC_KEY ->
|
case RDE_STAGING_PUBLIC_KEY ->
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't update RDE_STAGING_PUBLIC_KEY directly."
|
"Can't update RDE_STAGING_PUBLIC_KEY directly."
|
||||||
+ " Must update public and private keys together using RDE_STAGING_KEY_PAIR.");
|
+ " 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();
|
secretManagerKeyringUpdater.update();
|
||||||
|
|||||||
@@ -36,5 +36,7 @@ public enum KeyringKeyName {
|
|||||||
RDE_SSH_CLIENT_PUBLIC_KEY,
|
RDE_SSH_CLIENT_PUBLIC_KEY,
|
||||||
RDE_STAGING_KEY_PAIR,
|
RDE_STAGING_KEY_PAIR,
|
||||||
RDE_STAGING_PUBLIC_KEY,
|
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);
|
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
|
@Test
|
||||||
void marksdbDnlLoginAndPassword() {
|
void marksdbDnlLoginAndPassword() {
|
||||||
String secret = "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_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 BSA_API_KEY = "bsaapikey";
|
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
|
@Provides
|
||||||
public Keyring get() {
|
public Keyring get() {
|
||||||
@@ -151,6 +153,16 @@ public final class FakeKeyringModule {
|
|||||||
return rdeReceiverKey;
|
return rdeReceiverKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlPrimaryConnectionName() {
|
||||||
|
return SQL_PRIMARY_CONNECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSqlReplicaConnectionName() {
|
||||||
|
return SQL_REPLICA_CONNECTION;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {}
|
public void close() {}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user