private OperationResult EstablishClient(AddonManifest manifest, RedshiftDeveloperOptions devOptions, out AmazonRedshiftClient 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); } } AmazonRedshiftConfig config = new AmazonRedshiftConfig() { RegionEndpoint = RegionEndpoint.USEast1 }; client = new AmazonRedshiftClient(AccessKey, SecretAccessKey, config); result = new OperationResult { IsSuccess = true }; return(result); }
private OperationResult ParseDevOptions(string developerOptions, out RedshiftDeveloperOptions devOptions) { devOptions = null; var result = new OperationResult() { IsSuccess = false }; var progress = ""; try { progress += "Parsing developer options...\n"; devOptions = RedshiftDeveloperOptions.Parse(developerOptions); } catch (ArgumentException e) { result.EndUserMessage = e.Message; return(result); } result.IsSuccess = true; result.EndUserMessage = progress; return(result); }
// Interior method takes in instance of DeveloperOptions (aptly named existingOptions) and maps them to the proper value. In essence, a setter method. public static void MapToOption(RedshiftDeveloperOptions existingOptions, string key, string value) { if ("accesskey".Equals(key)) { existingOptions.AccessKey = value; return; } if ("secretkey".Equals(key)) { existingOptions.SecretAccessKey = value; return; } if ("regionendpoint".Equals(key)) { existingOptions.RegionEndpoint = value; } if ("availabilityzone".Equals(key)) { existingOptions.AvailabilityZone = 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 ("allowversionupgrade".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.AllowVersionUpgrade = result; return; } if ("automatedsnapshotretentionperiod".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.AutomatedSnapshotRetentionPeriod = result; return; } if ("clusteridentifier".Equals(key)) { existingOptions.ClusterIdentifier = value; return; } if ("clusterparametergroupname".Equals(key)) { existingOptions.ClusterParameterGroupName = value; return; } if ("clustersecuritygroups".Equals(key)) { if (true) { existingOptions.ClusterSecurityGroups.Add(value); } return; } if ("clustersubnetgroupname".Equals(key)) { existingOptions.ClusterSubnetGroupName = value; return; } if ("clustertype".Equals(key)) { existingOptions.ClusterType = value; return; } if ("clusterversion".Equals(key)) { existingOptions.ClusterVersion = value; return; } if ("dbname".Equals(key)) { existingOptions.DBName = value; return; } if ("elasticip".Equals(key)) { existingOptions.ElasticIp = value; return; } if ("encrypted".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.Encrypted = result; return; } if ("hsmclientcertificateidentifier".Equals(key)) { existingOptions.HSMClientCertificateIdentifier = value; return; } if ("hsmclientconfigurationidentifier".Equals(key)) { existingOptions.HSMClientConfigurationIdentifier = value; return; } if ("masterpassword".Equals(key)) { existingOptions.MasterPassword = value; return; } if ("masterusername".Equals(key)) { existingOptions.MasterUserName = value; return; } if ("nodetype".Equals(key)) { existingOptions.NodeType = value; return; } if ("numberofnodes".Equals(key)) { int result; if (!int.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.NumberOfNodes = result; return; } if ("port".Equals(key)) { int result; if (!int.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.Port = result; return; } if ("preferredmaintenancewindow".Equals(key)) { existingOptions.PreferredMaintenanceWindow = value; return; } if ("publiclyaccessible".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.PubliclyAccessible = result; return; } if ("secretaccesskey".Equals(key)) { existingOptions.SecretAccessKey = value; return; } if ("vpcsecuritygroupids".Equals(key)) { existingOptions.VpcSecurityGroupIds.Add(value); return; } throw new ArgumentException(string.Format("The developer option '{0}' was not expected and is not understood.", key)); }
// Provision Redshift Instance // Input: AddonDeprovisionRequest request // Output: ProvisionAddOnResult public override ProvisionAddOnResult Provision(AddonProvisionRequest request) { var provisionResult = new ProvisionAddOnResult("") { IsSuccess = false }; AddonManifest manifest = request.Manifest; string developerOptions = request.DeveloperOptions; try { AmazonRedshiftClient client; RedshiftDeveloperOptions devOptions; var parseOptionsResult = ParseDevOptions(developerOptions, out devOptions); if (!parseOptionsResult.IsSuccess) { provisionResult.EndUserMessage = parseOptionsResult.EndUserMessage; return(provisionResult); } var establishClientResult = EstablishClient(manifest, RedshiftDeveloperOptions.Parse(developerOptions), out client); if (!establishClientResult.IsSuccess) { provisionResult.EndUserMessage = establishClientResult.EndUserMessage; return(provisionResult); } var response = client.CreateCluster(CreateClusterRequest(devOptions)); // modified 5/22/14 to fix amazon aws deprecation if (response.Cluster != null) { //var conInfo = new ConnectionInfo() //{ // DbInstanceIdentifier = devOptions.DbInstanceIndentifier //}; //provisionResult.IsSuccess = true; //provisionResult.ConnectionData = conInfo.ToString(); //Thread.Sleep(TimeSpan.FromMinutes(6)); do { var verificationResponse = client.DescribeClusters(new DescribeClustersRequest() { ClusterIdentifier = devOptions.ClusterIdentifier }); // next few lines fixed 5/22/14 to resolve amazon aws deprecation if (verificationResponse.Clusters.Any() && verificationResponse.Clusters[0].ClusterStatus == "available") { var dbInstance = verificationResponse.Clusters[0]; var conInfo = new ConnectionInfo() { ClusterIdentifier = devOptions.ClusterIdentifier, 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); }
/* Begin private methods */ // TODO: We might be able to extend this. private bool ValidateDevCreds(RedshiftDeveloperOptions devOptions) { return(!(string.IsNullOrWhiteSpace(devOptions.AccessKey) || string.IsNullOrWhiteSpace(devOptions.SecretAccessKey))); }
private OperationResult ParseDevOptions(string developerOptions, out RedshiftDeveloperOptions devOptions) { devOptions = null; var result = new OperationResult() { IsSuccess = false }; var progress = ""; try { progress += "Parsing developer options...\n"; devOptions = RedshiftDeveloperOptions.Parse(developerOptions); } catch (ArgumentException e) { result.EndUserMessage = e.Message; return result; } result.IsSuccess = true; result.EndUserMessage = progress; return result; }
/* Begin private methods */ // TODO: We might be able to extend this. private bool ValidateDevCreds(RedshiftDeveloperOptions devOptions) { return !(string.IsNullOrWhiteSpace(devOptions.AccessKey) || string.IsNullOrWhiteSpace(devOptions.SecretAccessKey)); }
private OperationResult EstablishClient(AddonManifest manifest, RedshiftDeveloperOptions devOptions, out AmazonRedshiftClient 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; } } AmazonRedshiftConfig config = new AmazonRedshiftConfig() { RegionEndpoint = RegionEndpoint.USEast1 }; client = new AmazonRedshiftClient(AccessKey, SecretAccessKey, config); result = new OperationResult { IsSuccess = true }; return result; }
private CreateClusterRequest CreateClusterRequest(RedshiftDeveloperOptions devOptions) { var request = new CreateClusterRequest() { AllowVersionUpgrade = devOptions.AllowVersionUpgrade, AutomatedSnapshotRetentionPeriod = devOptions.AutomatedSnapshotRetentionPeriod, AvailabilityZone = devOptions.AvailabilityZone, ClusterIdentifier = devOptions.ClusterIdentifier, ClusterParameterGroupName = devOptions.ClusterParameterGroupName, ClusterSecurityGroups = devOptions.ClusterSecurityGroups, ClusterSubnetGroupName = devOptions.ClusterSubnetGroupName, ClusterType = devOptions.ClusterType, ClusterVersion = devOptions.ClusterVersion, DBName = devOptions.DBName, ElasticIp = devOptions.ElasticIp, Encrypted = devOptions.Encrypted, HsmClientCertificateIdentifier = devOptions.HSMClientCertificateIdentifier, HsmConfigurationIdentifier = devOptions.HSMClientConfigurationIdentifier, MasterUsername = devOptions.MasterUserName, MasterUserPassword = devOptions.MasterPassword, NodeType = devOptions.NodeType, NumberOfNodes = devOptions.NumberOfNodes, Port = devOptions.Port, PreferredMaintenanceWindow = devOptions.PreferredMaintenanceWindow, PubliclyAccessible = devOptions.PubliclyAccessible, VpcSecurityGroupIds = devOptions.VpcSecurityGroupIds }; return request; }
// Method takes in a string and parses it into a DeveloperOptions class. public static RedshiftDeveloperOptions Parse(string developerOptions) { // modified to include a list representaiton from parameter arguments // so! how it works is as follows: // http://<url>/path/to/rest/call?list=item1&list=item2&list=item3 RedshiftDeveloperOptions options = new RedshiftDeveloperOptions(); String lastKey = ""; if (!string.IsNullOrWhiteSpace(developerOptions)) { // splitting all entries into arrays of optionPairs var optionPairs = developerOptions.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries); foreach (var optionPair in optionPairs) { // splitting all optionPairs into arrays of key/value denominations var optionPairParts = optionPair.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (optionPairParts.Length == 2) { if (lastKey.Equals(optionPairParts[0].Trim().ToLowerInvariant())) { MapToOptionWithCollection(options, optionPairParts[0].Trim().ToLowerInvariant(), optionPairParts[1].Trim(), lastKey); } else { MapToOption(options, optionPairParts[0].Trim().ToLowerInvariant(), optionPairParts[1].Trim()); lastKey = optionPairParts[0].Trim().ToLowerInvariant(); } } 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; }
// Use this method to map all collections to their proper places. // Usage here is to confirm that the subsequent key is the same as the preceding key. // This forces that the REST call ensure all collection parameters are grouped together. // Ex. This is good: (key1=value&key1=value2) // Ex. This is bad: (key1=value&key2=value2) // Ex. This is bad: (key1=value&key2=value2&key1=value3) public static void MapToOptionWithCollection(RedshiftDeveloperOptions existingOptions, string key, string value, string lastKey) { if (key.Equals(lastKey)) { if ("clustersecuritygroups".Equals(key)) { existingOptions.ClusterSecurityGroups.Add(value); return; } if ("vpcsecuritygroupids".Equals(key)) { existingOptions.VpcSecurityGroupIds.Add(value); return; } throw new ArgumentException(string.Format("The developer option '{0}' was not expected and is not understood.", key)); } throw new ArgumentException(string.Format("The developer option '{0}' is grouped out of order in the REST call. Group collection parameters together in the request.", key)); }
// Interior method takes in instance of DeveloperOptions (aptly named existingOptions) and maps them to the proper value. In essence, a setter method. public static void MapToOption(RedshiftDeveloperOptions existingOptions, string key, string value) { if ("accesskey".Equals(key)) { existingOptions.AccessKey = value; return; } if ("secretkey".Equals(key)) { existingOptions.SecretAccessKey = value; return; } if("regionendpoint".Equals(key)) { existingOptions.RegionEndpoint = value; } if ("availabilityzone".Equals(key)) { existingOptions.AvailabilityZone = 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 ("allowversionupgrade".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.AllowVersionUpgrade = result; return; } if ("automatedsnapshotretentionperiod".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.AutomatedSnapshotRetentionPeriod = result; return; } if ("clusteridentifier".Equals(key)) { existingOptions.ClusterIdentifier = value; return; } if ("clusterparametergroupname".Equals(key)) { existingOptions.ClusterParameterGroupName = value; return; } if ("clustersecuritygroups".Equals(key)) { if(true) { existingOptions.ClusterSecurityGroups.Add(value); } return; } if ("clustersubnetgroupname".Equals(key)) { existingOptions.ClusterSubnetGroupName = value; return; } if ("clustertype".Equals(key)) { existingOptions.ClusterType = value; return; } if ("clusterversion".Equals(key)) { existingOptions.ClusterVersion = value; return; } if ("dbname".Equals(key)) { existingOptions.DBName = value; return; } if ("elasticip".Equals(key)) { existingOptions.ElasticIp = value; return; } if ("encrypted".Equals(key)) { bool result; if(!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.Encrypted = result; return; } if ("hsmclientcertificateidentifier".Equals(key)) { existingOptions.HSMClientCertificateIdentifier = value; return; } if ("hsmclientconfigurationidentifier".Equals(key)) { existingOptions.HSMClientConfigurationIdentifier = value; return; } if ("masterpassword".Equals(key)) { existingOptions.MasterPassword = value; return; } if ("masterusername".Equals(key)) { existingOptions.MasterUserName = value; return; } if ("nodetype".Equals(key)) { existingOptions.NodeType = value; return; } if ("numberofnodes".Equals(key)) { int result; if (!int.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.NumberOfNodes = result; return; } if ("port".Equals(key)) { int result; if (!int.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.Port = result; return; } if ("preferredmaintenancewindow".Equals(key)) { existingOptions.PreferredMaintenanceWindow = value; return; } if ("publiclyaccessible".Equals(key)) { bool result; if (!bool.TryParse(value, out result)) { throw new ArgumentException(string.Format("The developer option '{0}' must be a boolean value.", key)); } existingOptions.PubliclyAccessible = result; return; } if ("secretaccesskey".Equals(key)) { existingOptions.SecretAccessKey = value; return; } if ("vpcsecuritygroupids".Equals(key)) { existingOptions.VpcSecurityGroupIds.Add(value); return; } throw new ArgumentException(string.Format("The developer option '{0}' was not expected and is not understood.", key)); }