From 34c45c80f2bca53a4338f212140a59cbee78983c Mon Sep 17 00:00:00 2001 From: Chris Doherty Date: Sat, 8 Dec 2018 15:31:15 -0500 Subject: [PATCH] SQL Server support for RDS broker (#58) * SQL Server support for RDS broker - Added SqlServerClient - Pushed defaults into the RDS clients * SQL Server support for RDS broker - removing unused variable --- .../aws/ecs/broker/rds/AuroraClient.java | 3 +- .../herman/aws/ecs/broker/rds/RdsBroker.java | 14 ++--- .../herman/aws/ecs/broker/rds/RdsClient.java | 2 + .../aws/ecs/broker/rds/RdsInstance.java | 25 --------- .../aws/ecs/broker/rds/SqlServerClient.java | 52 ++++++++++++++++++ .../aws/ecs/broker/rds/StandardRdsClient.java | 26 +++++++++ .../aws/ecs/broker/rds/RdsBrokerTest.java | 54 +++++++++++++++++++ 7 files changed, 144 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/SqlServerClient.java diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/AuroraClient.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/AuroraClient.java index afa4459..91c9ab4 100644 --- a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/AuroraClient.java +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/AuroraClient.java @@ -62,7 +62,7 @@ import static com.libertymutualgroup.herman.aws.ecs.broker.rds.RdsBroker.pollingIntervalMs; -public class AuroraClient implements RdsClient { +public class AuroraClient extends StandardRdsClient { public static final String AVAILABLE_STATUS = "available"; public static final String INTERRUPTED_DURING_PROCESS = "Interrupted during process"; @@ -76,6 +76,7 @@ public class AuroraClient implements RdsClient { AuroraClient(AmazonRDS client, RdsInstance rds, EcsClusterMetadata clusterMetadata, List tags, HermanLogger buildLogger) { + super(client, rds, clusterMetadata, tags, buildLogger); this.client = client; this.rds = rds; this.clusterMetadata = clusterMetadata; diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBroker.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBroker.java index 1f1ff86..87fe87c 100644 --- a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBroker.java +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBroker.java @@ -48,10 +48,10 @@ public class RdsBroker { - public static final String AURORA_ENGINE = "aurora"; - public static final String POSTGRES_ENGINE = "postgres"; - public static final String MYSQL_ENGINE = "mysql"; - public static final String CIPHER_PREFIX = "{cipher}"; + private static final String AURORA_ENGINE = "aurora"; + private static final String POSTGRES_ENGINE = "postgres"; + private static final String MYSQL_ENGINE = "mysql"; + private static final String CIPHER_PREFIX = "{cipher}"; private static final int MYSQL_MAXLENGTH = 32; static int pollingIntervalMs = 10000; private AmazonRDS client; @@ -82,7 +82,6 @@ public RdsBroker(EcsPushContext pushContext, AmazonRDS client, AWSKMS kmsClient, public RdsInstance brokerDb() { RdsInstance rds = definition.getDatabase(); - rds.setDefaults(targetKeyId); String instanceId = rds.getDBInstanceIdentifier() != null ? rds.getDBInstanceIdentifier() : definition.getAppName(); String masterUserPassword = this.generateRandomPassword(); @@ -102,7 +101,6 @@ public RdsInstance brokerDb() { tags = TagUtil.mergeTags(tags, definition.getTags()); } - String encryptedPassword; RdsClient rdsClient; @@ -110,10 +108,14 @@ public RdsInstance brokerDb() { rdsClient = new AuroraClient(client, rds, clusterMetadata, tags, logger); } else if (rds.getEngine().contains("oracle")) { rdsClient = new OracleClient(client, rds, clusterMetadata, tags, logger); + } else if (rds.getEngine().contains("sqlserver")) { + rdsClient = new SqlServerClient(client, rds, clusterMetadata, tags, logger); } else { rdsClient = new StandardRdsClient(client, rds, clusterMetadata, tags, logger); } + rdsClient.setDefaults(targetKeyId); + boolean newDb = !rdsClient.dbExists(instanceId); if (!newDb) { diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsClient.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsClient.java index c9dacb2..ba8edd8 100644 --- a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsClient.java +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsClient.java @@ -41,4 +41,6 @@ public interface RdsClient { void setOptionGroup(String instanceId, OptionGroup options); void createSnapshot(String instanceId, String snapshotId); + + void setDefaults(String kmsKeyId); } diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsInstance.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsInstance.java index 05442ba..bc7bf35 100644 --- a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsInstance.java +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsInstance.java @@ -39,31 +39,6 @@ public class RdsInstance extends DBInstance { private Boolean preDeployBackup; private List extensions; // Postgres-specific (optional) - public void setDefaults(String kmsKeyId) { - this.setInjectNames(getInjectNames() == null ? new RdsInjectConfiguration() : getInjectNames()); - - injectNames.setDefaults(); - - this.setMasterUsername(getMasterUsername() == null ? "dbAdmin" : getMasterUsername()); - this.setDBName(getDBName() == null ? "appDb" : getDBName()); - this.setDBInstanceClass(getDBInstanceClass() == null ? "db.t2.small" : getDBInstanceClass()); - this.setAllocatedStorage(getAllocatedStorage() == null ? 5 : getAllocatedStorage()); - this.setPubliclyAccessible(getPubliclyAccessible() == null ? false : getPubliclyAccessible()); - this.setAutoMinorVersionUpgrade(getAutoMinorVersionUpgrade() == null ? true : getAutoMinorVersionUpgrade()); - this.setPreferredBackupWindow(getPreferredBackupWindow() == null ? "01:00-02:00" : getPreferredBackupWindow()); - this.setPreferredMaintenanceWindow( - getPreferredMaintenanceWindow() == null ? "sun:20:00-sun:21:00" : getPreferredMaintenanceWindow()); - this.setBackupRetentionPeriod(getBackupRetentionPeriod() == null ? 14 : getBackupRetentionPeriod()); - this.setStorageType(getStorageType() == null ? "gp2" : getStorageType()); - this.setFullUpdate(getFullUpdate() == null ? false : getFullUpdate()); - this.setIAMDatabaseAuthenticationEnabled( - getIAMDatabaseAuthenticationEnabled() == null ? false : getIAMDatabaseAuthenticationEnabled()); - this.setAvailabilityZones(getAvailabilityZones() == null ? new String[]{"us-east-1a"} : getAvailabilityZones()); - this.setPreDeployBackup(getPreDeployBackup() == null ? false : getPreDeployBackup()); - this.setExtensions(getExtensions() == null ? new ArrayList<>() : getExtensions()); - this.setKmsKeyId(getKmsKeyId() == null ? kmsKeyId : getKmsKeyId()); - } - public String getConnectionString() { String instanceType = this.getEngine().toLowerCase(); String connectionType = instanceType.contains("postgres") ? "postgresql" : instanceType; diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/SqlServerClient.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/SqlServerClient.java new file mode 100644 index 0000000..91748ce --- /dev/null +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/SqlServerClient.java @@ -0,0 +1,52 @@ +package com.libertymutualgroup.herman.aws.ecs.broker.rds; + +import com.amazonaws.services.rds.AmazonRDS; +import com.libertymutualgroup.herman.aws.ecs.cluster.EcsClusterMetadata; +import com.libertymutualgroup.herman.aws.tags.HermanTag; +import com.libertymutualgroup.herman.logging.HermanLogger; +import java.util.ArrayList; +import java.util.List; + +public class SqlServerClient extends StandardRdsClient { + + private AmazonRDS client; + private RdsInstance rds; + private EcsClusterMetadata clusterMetadata; + private List tags; + private HermanLogger logger; + + SqlServerClient(AmazonRDS client, RdsInstance rds, EcsClusterMetadata clusterMetadata, List tags, + HermanLogger logger) { + super(client, rds, clusterMetadata, tags, logger); + this.client = client; + this.rds = rds; + this.clusterMetadata = clusterMetadata; + this.tags = tags; + this.logger = logger; + } + + @Override + public void setDefaults(String kmsKeyId) { + rds.setInjectNames(rds.getInjectNames() == null ? new RdsInjectConfiguration() : rds.getInjectNames()); + + rds.getInjectNames().setDefaults(); + + rds.setMasterUsername(rds.getMasterUsername() == null ? "dbAdmin" : rds.getMasterUsername()); + rds.setDBInstanceClass(rds.getDBInstanceClass() == null ? "db.m4.large" : rds.getDBInstanceClass()); + rds.setAllocatedStorage(rds.getAllocatedStorage() == null ? 200 : rds.getAllocatedStorage()); + rds.setPubliclyAccessible(rds.getPubliclyAccessible() == null ? false : rds.getPubliclyAccessible()); + rds.setAutoMinorVersionUpgrade(rds.getAutoMinorVersionUpgrade() == null ? true : rds.getAutoMinorVersionUpgrade()); + rds.setPreferredBackupWindow(rds.getPreferredBackupWindow() == null ? "01:00-02:00" : rds.getPreferredBackupWindow()); + rds.setPreferredMaintenanceWindow( + rds.getPreferredMaintenanceWindow() == null ? "sun:20:00-sun:21:00" : rds.getPreferredMaintenanceWindow()); + rds.setBackupRetentionPeriod(rds.getBackupRetentionPeriod() == null ? 14 : rds.getBackupRetentionPeriod()); + rds.setStorageType(rds.getStorageType() == null ? "gp2" : rds.getStorageType()); + rds.setFullUpdate(rds.getFullUpdate() == null ? false : rds.getFullUpdate()); + rds.setIAMDatabaseAuthenticationEnabled( + rds.getIAMDatabaseAuthenticationEnabled() == null ? false : rds.getIAMDatabaseAuthenticationEnabled()); + rds.setAvailabilityZones(rds.getAvailabilityZones() == null ? new String[]{"us-east-1a"} : rds.getAvailabilityZones()); + rds.setPreDeployBackup(rds.getPreDeployBackup() == null ? false : rds.getPreDeployBackup()); + rds.setExtensions(rds.getExtensions() == null ? new ArrayList<>() : rds.getExtensions()); + rds.setKmsKeyId(rds.getKmsKeyId() == null ? kmsKeyId : rds.getKmsKeyId()); + } +} diff --git a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/StandardRdsClient.java b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/StandardRdsClient.java index 9c8c66e..3d1410b 100644 --- a/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/StandardRdsClient.java +++ b/src/main/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/StandardRdsClient.java @@ -365,6 +365,32 @@ public void createSnapshot(String instanceId, String snapshotId) { } } + @Override + public void setDefaults(String kmsKeyId) { + rds.setInjectNames(rds.getInjectNames() == null ? new RdsInjectConfiguration() : rds.getInjectNames()); + + rds.getInjectNames().setDefaults(); + + rds.setMasterUsername(rds.getMasterUsername() == null ? "dbAdmin" : rds.getMasterUsername()); + rds.setDBName(rds.getDBName() == null ? "appDb" : rds.getDBName()); + rds.setDBInstanceClass(rds.getDBInstanceClass() == null ? "db.t2.small" : rds.getDBInstanceClass()); + rds.setAllocatedStorage(rds.getAllocatedStorage() == null ? 5 : rds.getAllocatedStorage()); + rds.setPubliclyAccessible(rds.getPubliclyAccessible() == null ? false : rds.getPubliclyAccessible()); + rds.setAutoMinorVersionUpgrade(rds.getAutoMinorVersionUpgrade() == null ? true : rds.getAutoMinorVersionUpgrade()); + rds.setPreferredBackupWindow(rds.getPreferredBackupWindow() == null ? "01:00-02:00" : rds.getPreferredBackupWindow()); + rds.setPreferredMaintenanceWindow( + rds.getPreferredMaintenanceWindow() == null ? "sun:20:00-sun:21:00" : rds.getPreferredMaintenanceWindow()); + rds.setBackupRetentionPeriod(rds.getBackupRetentionPeriod() == null ? 14 : rds.getBackupRetentionPeriod()); + rds.setStorageType(rds.getStorageType() == null ? "gp2" : rds.getStorageType()); + rds.setFullUpdate(rds.getFullUpdate() == null ? false : rds.getFullUpdate()); + rds.setIAMDatabaseAuthenticationEnabled( + rds.getIAMDatabaseAuthenticationEnabled() == null ? false : rds.getIAMDatabaseAuthenticationEnabled()); + rds.setAvailabilityZones(rds.getAvailabilityZones() == null ? new String[]{"us-east-1a"} : rds.getAvailabilityZones()); + rds.setPreDeployBackup(rds.getPreDeployBackup() == null ? false : rds.getPreDeployBackup()); + rds.setExtensions(rds.getExtensions() == null ? new ArrayList<>() : rds.getExtensions()); + rds.setKmsKeyId(rds.getKmsKeyId() == null ? kmsKeyId : rds.getKmsKeyId()); + } + private DescribeDBSnapshotsResult getDescribeDBSnapshotsResult(String snapshotId) throws InterruptedException { String status = ""; DescribeDBSnapshotsResult result = null; diff --git a/src/test/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBrokerTest.java b/src/test/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBrokerTest.java index 323babc..4fe2b26 100644 --- a/src/test/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBrokerTest.java +++ b/src/test/java/com/libertymutualgroup/herman/aws/ecs/broker/rds/RdsBrokerTest.java @@ -28,6 +28,7 @@ import static com.libertymutualgroup.herman.aws.ecs.broker.rds.RdsCommonTestObjects.initDbInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.never; @@ -86,6 +87,8 @@ private RdsClient initClient(EcsPushDefinition definition, ArrayList rdsClient = new AuroraClient(client, definition.getDatabase(), clusterMetadata, tags, logger); } else if (definition.getDatabase().getEngine().contains("oracle")) { rdsClient = new OracleClient(client, definition.getDatabase(), clusterMetadata, tags, logger); + } else if (definition.getDatabase().getEngine().contains("sqlserver")) { + rdsClient = new SqlServerClient(client, definition.getDatabase(), clusterMetadata, tags, logger); } else { rdsClient = new StandardRdsClient(client, definition.getDatabase(), clusterMetadata, tags, logger); } @@ -202,4 +205,55 @@ public void shouldUseCredPrefixWhenSpecified() { assertTrue(rdsResult.getAdminEncryptedPassword().startsWith(prefix)); assertTrue(rdsResult.getEncryptedPassword().startsWith(prefix)); } + + @Test + public void dbNameNullForSQLServer() { + EcsPushDefinition definition = new EcsPushDefinition(); + RdsInstance instance = initSqlServerInstanceDefinition(); + definition.setDatabase(instance); + + RdsBroker broker = initBroker(definition); + mockEncryptionResult("123"); + definition.setUseKms(Boolean.TRUE.toString()); + + DescribeDBInstancesResult result = new DescribeDBInstancesResult(); + result.setDBInstances(Arrays.asList(initDbInstance())); + + Mockito.when(client.describeDBInstances(any())) + .thenThrow(new DBInstanceNotFoundException("")) + .thenReturn(result); + + RdsInstance rdsResult = broker.brokerDb(); + assertNull(rdsResult.getDBName()); + } + + @Test + public void dbNameNotNullForMySql() { + EcsPushDefinition definition = new EcsPushDefinition(); + RdsInstance instance = initInstanceDefinition(); + definition.setDatabase(instance); + + RdsBroker broker = initBroker(definition); + mockEncryptionResult("123"); + definition.setUseKms(Boolean.TRUE.toString()); + + DescribeDBInstancesResult result = new DescribeDBInstancesResult(); + result.setDBInstances(Arrays.asList(initDbInstance())); + + Mockito.when(client.describeDBInstances(any())) + .thenThrow(new DBInstanceNotFoundException("")) + .thenReturn(result); + + RdsInstance rdsResult = broker.brokerDb(); + assertNotNull(rdsResult.getDBName()); + assertEquals("appDb", rdsResult.getDBName()); + } + + private RdsInstance initSqlServerInstanceDefinition() { + RdsInstance instance = new RdsInstance(); + instance.setEngine("sqlserver-se"); + instance.setEngineVersion("13.00.4466.4.v1"); + + return instance; + } }