// Method takes in a string and parses it into a DeveloperOptions class. public static DeveloperOptions Parse(string developerOptions) { DeveloperOptions options = new DeveloperOptions(); if (!string.IsNullOrWhiteSpace(developerOptions)) { var optionPairs = developerOptions.Split(new [] { '&' }, StringSplitOptions.RemoveEmptyEntries); foreach (var optionPair in optionPairs) { var optionPairParts = optionPair.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (optionPairParts.Length == 2) { MapToOption(options, optionPairParts[0].Trim().ToLowerInvariant(), optionPairParts[1].Trim()); } else { throw new ArgumentException( string.Format( "Unable to parse developer options which should be in the form of 'option=value&nextOption=nextValue'. The option '{0}' was not properly constructed", optionPair)); } } } return(options); }
// Deprovision RDS Instance // Input: AddonDeprovisionRequest request // Output: OperationResult public override OperationResult Deprovision(AddonDeprovisionRequest request) { string connectionData = request.ConnectionData; // changing to overloaded constructor - 5/22/14 var deprovisionResult = new ProvisionAddOnResult(connectionData); AddonManifest manifest = request.Manifest; string devOptions = request.DeveloperOptions; try { AmazonRDSClient client; var conInfo = ConnectionInfo.Parse(connectionData); var developerOptions = DeveloperOptions.Parse(devOptions); var establishClientResult = EstablishClient(manifest, developerOptions, out client); if (!establishClientResult.IsSuccess) { deprovisionResult.EndUserMessage = establishClientResult.EndUserMessage; return(deprovisionResult); } var response = client.DeleteDBInstance(new DeleteDBInstanceRequest() { DBInstanceIdentifier = conInfo.DbInstanceIdentifier, SkipFinalSnapshot = true }); // 5/22/14 fixing amazon aws deprecation if (response.DBInstance != null) { do { var verificationResponse = client.DescribeDBInstances(new DescribeDBInstancesRequest() { DBInstanceIdentifier = conInfo.DbInstanceIdentifier }); // 5/22/14 fixing amazaon aws deprecration if (!verificationResponse.DBInstances.Any()) { deprovisionResult.IsSuccess = true; break; } Thread.Sleep(TimeSpan.FromSeconds(10d)); } while (true); } } catch (DBInstanceNotFoundException) { deprovisionResult.IsSuccess = true; } catch (Exception e) { deprovisionResult.EndUserMessage = e.Message; } return(deprovisionResult); }
private CreateDBInstanceRequest CreateDbInstanceRequest(DeveloperOptions devOptions) { var request = new CreateDBInstanceRequest() { // TODO - need to determine where defaults are used, and then not create the constructor where value is null (to use default) // These are required values. BackupRetentionPeriod = devOptions.BackupRetentionPeriod, DBParameterGroupName = devOptions.DBParameterGroupName, DBSecurityGroups = devOptions.DBSecurityGroups, DBSubnetGroupName = devOptions.SubnetGroupName, DBInstanceClass = devOptions.DbInstanceClass, DBInstanceIdentifier = devOptions.DbInstanceIdentifier, DBName = devOptions.DbName, Engine = devOptions.Engine, EngineVersion = devOptions.EngineVersion, LicenseModel = devOptions.LicenseModel, MasterUsername = devOptions.DBAUsername, MasterUserPassword = devOptions.DBAPassword, Iops = devOptions.ProvisionedIOPs, MultiAZ = devOptions.MultiAZ, OptionGroupName = devOptions.OptionGroup, Port = devOptions.Port, PreferredBackupWindow = devOptions.PreferredBackupWindow, PreferredMaintenanceWindow = devOptions.PreferredMXWindow, PubliclyAccessible = devOptions.PubliclyAccessible, Tags = devOptions.Tags, VpcSecurityGroupIds = devOptions.VPCSecurityGroupIds }; if (!devOptions.MultiAZ) { request.AvailabilityZone = devOptions.AvailabilityZone; } // Oracle DB only parameter if (request.Engine.Equals("Oracle") && devOptions.CharacterSet != null) { request.CharacterSetName = devOptions.CharacterSet; } if (devOptions.AllocatedStorage != null) { request.AllocatedStorage = devOptions.AllocatedStorage; } if (devOptions.AutoMinorVersionUpgrade != null) { request.AutoMinorVersionUpgrade = devOptions.AutoMinorVersionUpgrade; } return(request); }
private OperationResult EstablishClient(AddonManifest manifest, DeveloperOptions devOptions, out AmazonRDSClient client) { OperationResult result; bool requireCreds; var manifestProps = manifest.GetProperties().ToDictionary(x => x.Key, x => x.Value); var accessKey = manifestProps["AWSClientKey"]; var secretAccessKey = manifestProps["AWSSecretKey"]; var regionEndpoint = manifestProps["AWSRegionEndpoint"]; var prop = manifest.Properties.First( p => p.Key.Equals("requireDevCredentials", StringComparison.InvariantCultureIgnoreCase)); if (bool.TryParse(prop.Value, out requireCreds) && requireCreds) { if (!ValidateDevCreds(devOptions)) { client = null; result = new OperationResult() { IsSuccess = false, EndUserMessage = "The add on requires that developer credentials are specified but none were provided." }; return(result); } accessKey = devOptions.AccessKey; secretAccessKey = devOptions.SecretAccessKey; } AmazonRDSConfig config = new AmazonRDSConfig() { RegionEndpoint = RegionEndpoint.USEast1 }; client = new AmazonRDSClient(accessKey, secretAccessKey, config); result = new OperationResult { IsSuccess = true }; return(result); }
private OperationResult ParseDevOptions(string developerOptions, out DeveloperOptions devOptions) { devOptions = null; var result = new OperationResult() { IsSuccess = false }; var progress = ""; try { progress += "Parsing developer options...\n"; devOptions = DeveloperOptions.Parse(developerOptions); } catch (ArgumentException e) { result.EndUserMessage = e.Message; return(result); } result.IsSuccess = true; result.EndUserMessage = progress; return(result); }
// TODO: We might be able to extend this. private bool ValidateDevCreds(DeveloperOptions devOptions) { return !(string.IsNullOrWhiteSpace(devOptions.AccessKey) || string.IsNullOrWhiteSpace(devOptions.SecretAccessKey)); }
private OperationResult ParseDevOptions(string developerOptions, out DeveloperOptions devOptions) { devOptions = null; var result = new OperationResult() { IsSuccess = false }; var progress = ""; try { progress += "Parsing developer options...\n"; devOptions = DeveloperOptions.Parse(developerOptions); } catch (ArgumentException e) { result.EndUserMessage = e.Message; return result; } result.IsSuccess = true; result.EndUserMessage = progress; return result; }
private OperationResult EstablishClient(AddonManifest manifest, DeveloperOptions devOptions, out AmazonRDSClient client) { OperationResult result; bool requireCreds; var manifestProps = manifest.GetProperties().ToDictionary(x => x.Key, x => x.Value); var accessKey = manifestProps["AWSClientKey"]; var secretAccessKey = manifestProps["AWSSecretKey"]; var regionEndpoint = manifestProps["AWSRegionEndpoint"]; var prop = manifest.Properties.First( p => p.Key.Equals("requireDevCredentials", StringComparison.InvariantCultureIgnoreCase)); if (bool.TryParse(prop.Value, out requireCreds) && requireCreds) { if (!ValidateDevCreds(devOptions)) { client = null; result = new OperationResult() { IsSuccess = false, EndUserMessage = "The add on requires that developer credentials are specified but none were provided." }; return result; } accessKey = devOptions.AccessKey; secretAccessKey = devOptions.SecretAccessKey; } AmazonRDSConfig config = new AmazonRDSConfig() { RegionEndpoint = RegionEndpoint.USEast1 }; client = new AmazonRDSClient(accessKey, secretAccessKey, config); result = new OperationResult { IsSuccess = true }; return result; }
private CreateDBInstanceRequest CreateDbInstanceRequest(DeveloperOptions devOptions) { var request = new CreateDBInstanceRequest() { // TODO - need to determine where defaults are used, and then not create the constructor where value is null (to use default) // These are required values. BackupRetentionPeriod = devOptions.BackupRetentionPeriod, DBParameterGroupName = devOptions.DBParameterGroupName, DBSecurityGroups = devOptions.DBSecurityGroups, DBSubnetGroupName = devOptions.SubnetGroupName, DBInstanceClass = devOptions.DbInstanceClass, DBInstanceIdentifier = devOptions.DbInstanceIdentifier, DBName = devOptions.DbName, Engine = devOptions.Engine, EngineVersion = devOptions.EngineVersion, LicenseModel = devOptions.LicenseModel, MasterUsername = devOptions.DBAUsername, MasterUserPassword = devOptions.DBAPassword, Iops = devOptions.ProvisionedIOPs, MultiAZ = devOptions.MultiAZ, OptionGroupName = devOptions.OptionGroup, Port = devOptions.Port, PreferredBackupWindow = devOptions.PreferredBackupWindow, PreferredMaintenanceWindow = devOptions.PreferredMXWindow, PubliclyAccessible = devOptions.PubliclyAccessible, Tags = devOptions.Tags, VpcSecurityGroupIds = devOptions.VPCSecurityGroupIds }; if (!devOptions.MultiAZ) { request.AvailabilityZone = devOptions.AvailabilityZone; } // Oracle DB only parameter if (request.Engine.Equals("Oracle") && devOptions.CharacterSet != null) { request.CharacterSetName = devOptions.CharacterSet; } if (devOptions.AllocatedStorage != null) { request.AllocatedStorage = devOptions.AllocatedStorage; } if (devOptions.AutoMinorVersionUpgrade != null) { request.AutoMinorVersionUpgrade = devOptions.AutoMinorVersionUpgrade; } return request; }
// Interior method takes in instance of DeveloperOptions (aptly named existingOptions) and maps them to the proper value. In essence, a setter method. private static void MapToOption(DeveloperOptions existingOptions, string key, string value) { if ("accesskey".Equals(key)) { existingOptions.AccessKey = value; return; } if ("secretkey".Equals(key)) { existingOptions.SecretAccessKey = value; return; } if ("availabilityzone".Equals(key)) { existingOptions.AvailabilityZone = value; return; } if ("dbinstanceclass".Equals(key)) { existingOptions.DbInstanceClass = value; return; } if ("dbinstanceidentifier".Equals(key)) { existingOptions.DbInstanceIdentifier = value; return; } if ("dbname".Equals(key)) { existingOptions.DbName = value; return; } if ("engine".Equals(key)) { existingOptions.Engine = value; return; } if ("engineversion".Equals(key)) { existingOptions.EngineVersion = value; } if ("licensemodel".Equals(key)) { existingOptions.LicenseModel = value; return; } if ("dbausername".Equals(key)) { existingOptions.DBAUsername = value; return; } if ("dbapassword".Equals(key)) { existingOptions.DBAPassword = value; return; } if ("allocatedstorage".Equals(key)) { int result; if (!int.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' can only have an integer value but '{1}' was used instead.", key, value)); } existingOptions.AllocatedStorage = result; return; } if ("autominorversionupgrade".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' can only have a value of true|false but '{1}' was used instead.", key, value)); } existingOptions.AutoMinorVersionUpgrade = result; return; } throw new ArgumentException(string.Format("The developer option '{0}' was not expected and is not understood.", key)); }
// Method takes in a string and parses it into a DeveloperOptions class. public static DeveloperOptions Parse(string developerOptions) { DeveloperOptions options = new DeveloperOptions(); if (!string.IsNullOrWhiteSpace(developerOptions)) { var optionPairs = developerOptions.Split(new []{'&'}, StringSplitOptions.RemoveEmptyEntries); foreach (var optionPair in optionPairs) { var optionPairParts = optionPair.Split(new[]{'='}, StringSplitOptions.RemoveEmptyEntries); if (optionPairParts.Length == 2) { MapToOption(options, optionPairParts[0].Trim().ToLowerInvariant(), optionPairParts[1].Trim()); } else { throw new ArgumentException( string.Format( "Unable to parse developer options which should be in the form of 'option=value&nextOption=nextValue'. The option '{0}' was not properly constructed", optionPair)); } } } return options; }
// Provision RDS Instance // Input: AddonDeprovisionRequest request // Output: ProvisionAddOnResult public override ProvisionAddOnResult Provision(AddonProvisionRequest request) { // i think this is a bug. but I'm going to throw an empty string to it to clear the warning. var provisionResult = new ProvisionAddOnResult(""); AddonManifest manifest = request.Manifest; string developerOptions = request.DeveloperOptions; try { AmazonRDSClient client; DeveloperOptions devOptions; var parseOptionsResult = ParseDevOptions(developerOptions, out devOptions); if (!parseOptionsResult.IsSuccess) { provisionResult.EndUserMessage = parseOptionsResult.EndUserMessage; return(provisionResult); } var establishClientResult = EstablishClient(manifest, DeveloperOptions.Parse(developerOptions), out client); if (!establishClientResult.IsSuccess) { provisionResult.EndUserMessage = establishClientResult.EndUserMessage; return(provisionResult); } var response = client.CreateDBInstance(CreateDbInstanceRequest(devOptions)); // fix 5/22/14 resolves amazon aws deprecation if (response.DBInstance != null) { //var conInfo = new ConnectionInfo() //{ // DbInstanceIdentifier = devOptions.DbInstanceIndentifier //}; //provisionResult.IsSuccess = true; //provisionResult.ConnectionData = conInfo.ToString(); //Thread.Sleep(TimeSpan.FromMinutes(6)); do { var verificationResponse = client.DescribeDBInstances(new DescribeDBInstancesRequest() { DBInstanceIdentifier = devOptions.DbInstanceIdentifier }); // fix on next few lines 5/22/14 resolve amazon aws deprecation. if (verificationResponse.DBInstances.Any() && verificationResponse.DBInstances[0].DBInstanceStatus == "available") { var dbInstance = verificationResponse.DBInstances[0]; var conInfo = new ConnectionInfo() { DbInstanceIdentifier = devOptions.DbInstanceIdentifier, EndpointAddress = dbInstance.Endpoint.Address, EndpointPort = dbInstance.Endpoint.Port }; provisionResult.IsSuccess = true; provisionResult.ConnectionData = conInfo.ToString(); break; } Thread.Sleep(TimeSpan.FromSeconds(10d)); } while (true); } } catch (Exception e) { provisionResult.EndUserMessage = e.Message; } return(provisionResult); }
// TODO: We might be able to extend this. private bool ValidateDevCreds(DeveloperOptions devOptions) { return(!(string.IsNullOrWhiteSpace(devOptions.AccessKey) || string.IsNullOrWhiteSpace(devOptions.SecretAccessKey))); }