AWS redshift low security documentation change
Summary
Added comprehensive .NET code examples for Redshift cluster management including creation, modification, deletion, and query operations
Security assessment
The code example shows hardcoded default credentials (userPassword = 'AwsUser1000') which could encourage insecure practices. While not fixing an existing vulnerability, demonstrating default credentials in documentation might lead to security misconfigurations if followed without modification.
Diff
diff --git a/redshift/latest/mgmt/example_redshift_Scenario_section.md b/redshift/latest/mgmt/example_redshift_Scenario_section.md index ba62f8b05..0de1bdf5a 100644 --- a//redshift/latest/mgmt/example_redshift_Scenario_section.md +++ b//redshift/latest/mgmt/example_redshift_Scenario_section.md @@ -27,0 +28,775 @@ The following code examples show how to: +.NET + + +**SDK for .NET (v4)** + + +###### Note + +There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv4/Redshift#code-examples). + +Create a Redshift wrapper class to manage operations. + + + /// <summary> + /// Wrapper class for Amazon Redshift operations. + /// </summary> + public class RedshiftWrapper + { + private readonly IAmazonRedshift _redshiftClient; + private readonly IAmazonRedshiftDataAPIService _redshiftDataClient; + + /// <summary> + /// Constructor for RedshiftWrapper. + /// </summary> + /// <param name="redshiftClient">Amazon Redshift client.</param> + /// <param name="redshiftDataClient">Amazon Redshift Data API client.</param> + public RedshiftWrapper(IAmazonRedshift redshiftClient, IAmazonRedshiftDataAPIService redshiftDataClient) + { + _redshiftClient = redshiftClient; + _redshiftDataClient = redshiftDataClient; + } + + /// <summary> + /// Create a new Amazon Redshift cluster. + /// </summary> + /// <param name="clusterIdentifier">The identifier for the cluster.</param> + /// <param name="databaseName">The name of the database.</param> + /// <param name="masterUsername">The master username.</param> + /// <param name="masterUserPassword">The master user password.</param> + /// <param name="nodeType">The node type for the cluster.</param> + /// <returns>The cluster that was created.</returns> + public async Task<Cluster> CreateClusterAsync(string clusterIdentifier, string databaseName, + string masterUsername, string masterUserPassword, string nodeType = "ra3.large") + { + try + { + var request = new CreateClusterRequest + { + ClusterIdentifier = clusterIdentifier, + DBName = databaseName, + MasterUsername = masterUsername, + MasterUserPassword = masterUserPassword, + NodeType = nodeType, + NumberOfNodes = 1, + ClusterType = "single-node" + }; + + var response = await _redshiftClient.CreateClusterAsync(request); + Console.WriteLine($"Created cluster {clusterIdentifier}"); + return response.Cluster; + } + catch (ClusterAlreadyExistsException ex) + { + Console.WriteLine($"Cluster already exists: {ex.Message}"); + throw; + } + catch (Exception ex) + { + Console.WriteLine($"Couldn't create cluster. Here's why: {ex.Message}"); + throw; + } + } + + /// <summary> + /// Describe Amazon Redshift clusters. + /// </summary> + /// <param name="clusterIdentifier">Optional cluster identifier to describe a specific cluster.</param> + /// <returns>A list of clusters.</returns> + public async Task<List<Cluster>> DescribeClustersAsync(string? clusterIdentifier = null) + { + try + { + var clusters = new List<Cluster>(); + var request = new DescribeClustersRequest(); + if (!string.IsNullOrEmpty(clusterIdentifier)) + { + request.ClusterIdentifier = clusterIdentifier; + } + + var clustersPaginator = _redshiftClient.Paginators.DescribeClusters(request); + await foreach (var response in clustersPaginator.Responses) + { + if (response.Clusters != null) + clusters.AddRange(response.Clusters); + } + + Console.WriteLine($"{clusters.Count} cluster(s) retrieved."); + foreach (var cluster in clusters) + { + Console.WriteLine($"\t{cluster.ClusterIdentifier} (Status: {cluster.ClusterStatus})"); + } + + return clusters; + } + catch (ClusterNotFoundException ex) + { + Console.WriteLine($"Cluster {clusterIdentifier} not found: {ex.Message}"); + throw; + } + catch (Exception ex) + { + Console.WriteLine($"Couldn't describe clusters. Here's why: {ex.Message}"); + throw; + } + } + + /// <summary> + /// Modify an Amazon Redshift cluster. + /// </summary> + /// <param name="clusterIdentifier">The identifier for the cluster.</param> + /// <param name="preferredMaintenanceWindow">The preferred maintenance window.</param> + /// <returns>True if successful.</returns> + public async Task<bool> ModifyClusterAsync(string clusterIdentifier, string preferredMaintenanceWindow) + { + try + { + var request = new ModifyClusterRequest + { + ClusterIdentifier = clusterIdentifier, + PreferredMaintenanceWindow = preferredMaintenanceWindow + }; + + var response = await _redshiftClient.ModifyClusterAsync(request); + Console.WriteLine($"The modified cluster was successfully modified and has {response.Cluster.PreferredMaintenanceWindow} as the maintenance window"); + return true; + } + catch (ClusterNotFoundException ex) + { + Console.WriteLine($"Cluster {clusterIdentifier} not found: {ex.Message}"); + return false; + } + catch (Exception ex) + { + Console.WriteLine($"Couldn't modify cluster. Here's why: {ex.Message}"); + return false; + } + } + + /// <summary> + /// Delete an Amazon Redshift cluster without a final snapshot. + /// </summary> + /// <param name="clusterIdentifier">The identifier for the cluster.</param> + /// <returns>True if successful.</returns> + public async Task<bool> DeleteClusterWithoutSnapshotAsync(string clusterIdentifier) + { + try + { + var request = new DeleteClusterRequest + { + ClusterIdentifier = clusterIdentifier, + SkipFinalClusterSnapshot = true + }; + + var response = await _redshiftClient.DeleteClusterAsync(request); + Console.WriteLine($"The {clusterIdentifier} was deleted"); + return true; + } + catch (ClusterNotFoundException ex) + { + Console.WriteLine($"Cluster not found: {ex.Message}"); + return false; + } + catch (Exception ex) + { + Console.WriteLine($"Couldn't delete cluster. Here's why: {ex.Message}"); + return false; + } + } + + /// <summary> + /// List databases in a Redshift cluster. + /// </summary> + /// <param name="clusterIdentifier">The cluster identifier.</param> + /// <param name="dbUser">The database user.</param> + /// <param name="dbUser">The database name for authentication.</param> + /// <returns>A list of database names.</returns> + public async Task<List<string>> ListDatabasesAsync(string clusterIdentifier, string dbUser, string databaseName) + { + try + { + var request = new ListDatabasesRequest + { + ClusterIdentifier = clusterIdentifier, + DbUser = dbUser, + Database = databaseName