From ba9430aa6495999a3704dabbe77a11d84e1b5f22 Mon Sep 17 00:00:00 2001 From: Ninir Date: Thu, 3 Nov 2016 15:03:45 +0100 Subject: [PATCH] Force the master username & password to be defined when not in a restore mode --- .../aws/resource_aws_redshift_cluster.go | 66 +++++++++++-------- .../aws/resource_aws_redshift_cluster_test.go | 27 ++++---- .../aws/r/redshift_cluster.html.markdown | 7 +- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/builtin/providers/aws/resource_aws_redshift_cluster.go b/builtin/providers/aws/resource_aws_redshift_cluster.go index 587b38e5f318..def7deb7f772 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster.go @@ -25,44 +25,44 @@ func resourceAwsRedshiftCluster() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "database_name": &schema.Schema{ + "database_name": { Type: schema.TypeString, Optional: true, Computed: true, ValidateFunc: validateRedshiftClusterDbName, }, - "cluster_identifier": &schema.Schema{ + "cluster_identifier": { Type: schema.TypeString, Required: true, ForceNew: true, ValidateFunc: validateRedshiftClusterIdentifier, }, - "cluster_type": &schema.Schema{ + "cluster_type": { Type: schema.TypeString, Optional: true, Computed: true, }, - "node_type": &schema.Schema{ + "node_type": { Type: schema.TypeString, Required: true, }, - "master_username": &schema.Schema{ + "master_username": { Type: schema.TypeString, Optional: true, ValidateFunc: validateRedshiftClusterMasterUsername, }, - "master_password": &schema.Schema{ + "master_password": { Type: schema.TypeString, Optional: true, Sensitive: true, ValidateFunc: validateRedshiftClusterMasterPassword, }, - "cluster_security_groups": &schema.Schema{ + "cluster_security_groups": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -70,7 +70,7 @@ func resourceAwsRedshiftCluster() *schema.Resource { Set: schema.HashString, }, - "vpc_security_group_ids": &schema.Schema{ + "vpc_security_group_ids": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -78,20 +78,20 @@ func resourceAwsRedshiftCluster() *schema.Resource { Set: schema.HashString, }, - "cluster_subnet_group_name": &schema.Schema{ + "cluster_subnet_group_name": { Type: schema.TypeString, Optional: true, ForceNew: true, Computed: true, }, - "availability_zone": &schema.Schema{ + "availability_zone": { Type: schema.TypeString, Optional: true, Computed: true, }, - "preferred_maintenance_window": &schema.Schema{ + "preferred_maintenance_window": { Type: schema.TypeString, Optional: true, Computed: true, @@ -103,13 +103,13 @@ func resourceAwsRedshiftCluster() *schema.Resource { }, }, - "cluster_parameter_group_name": &schema.Schema{ + "cluster_parameter_group_name": { Type: schema.TypeString, Optional: true, Computed: true, }, - "automated_snapshot_retention_period": &schema.Schema{ + "automated_snapshot_retention_period": { Type: schema.TypeInt, Optional: true, Default: 1, @@ -123,85 +123,85 @@ func resourceAwsRedshiftCluster() *schema.Resource { }, }, - "port": &schema.Schema{ + "port": { Type: schema.TypeInt, Optional: true, Default: 5439, }, - "cluster_version": &schema.Schema{ + "cluster_version": { Type: schema.TypeString, Optional: true, Default: "1.0", }, - "allow_version_upgrade": &schema.Schema{ + "allow_version_upgrade": { Type: schema.TypeBool, Optional: true, Default: true, }, - "number_of_nodes": &schema.Schema{ + "number_of_nodes": { Type: schema.TypeInt, Optional: true, Default: 1, }, - "publicly_accessible": &schema.Schema{ + "publicly_accessible": { Type: schema.TypeBool, Optional: true, Default: true, }, - "encrypted": &schema.Schema{ + "encrypted": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "kms_key_id": &schema.Schema{ + "kms_key_id": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, - "elastic_ip": &schema.Schema{ + "elastic_ip": { Type: schema.TypeString, Optional: true, }, - "final_snapshot_identifier": &schema.Schema{ + "final_snapshot_identifier": { Type: schema.TypeString, Optional: true, ValidateFunc: validateRedshiftClusterFinalSnapshotIdentifier, }, - "skip_final_snapshot": &schema.Schema{ + "skip_final_snapshot": { Type: schema.TypeBool, Optional: true, Default: true, }, - "endpoint": &schema.Schema{ + "endpoint": { Type: schema.TypeString, Optional: true, Computed: true, }, - "cluster_public_key": &schema.Schema{ + "cluster_public_key": { Type: schema.TypeString, Optional: true, Computed: true, }, - "cluster_revision_number": &schema.Schema{ + "cluster_revision_number": { Type: schema.TypeString, Optional: true, Computed: true, }, - "iam_roles": &schema.Schema{ + "iam_roles": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -227,12 +227,12 @@ func resourceAwsRedshiftCluster() *schema.Resource { Computed: true, }, - "snapshot_identifier": &schema.Schema{ + "snapshot_identifier": { Type: schema.TypeString, Optional: true, }, - "snapshot_cluster_identifier": &schema.Schema{ + "snapshot_cluster_identifier": { Type: schema.TypeString, Optional: true, }, @@ -317,6 +317,14 @@ func resourceAwsRedshiftClusterCreate(d *schema.ResourceData, meta interface{}) d.SetId(*resp.Cluster.ClusterIdentifier) } else { + if _, ok := d.GetOk("master_password"); !ok { + return fmt.Errorf(`provider.aws: aws_redshift_cluster: %s: "master_password": required field is not set`, d.Get("cluster_identifier").(string)) + } + + if _, ok := d.GetOk("master_username"); !ok { + return fmt.Errorf(`provider.aws: aws_redshift_cluster: %s: "master_username": required field is not set`, d.Get("cluster_identifier").(string)) + } + createOpts := &redshift.CreateClusterInput{ ClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)), Port: aws.Int64(int64(d.Get("port").(int))), diff --git a/builtin/providers/aws/resource_aws_redshift_cluster_test.go b/builtin/providers/aws/resource_aws_redshift_cluster_test.go index 5cdbb5749aab..16f8e5b5aa71 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster_test.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster_test.go @@ -24,7 +24,7 @@ func TestAccAWSRedshiftCluster_basic(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: config, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -50,7 +50,7 @@ func TestAccAWSRedshiftCluster_loggingEnabled(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -60,8 +60,7 @@ func TestAccAWSRedshiftCluster_loggingEnabled(t *testing.T) { "aws_redshift_cluster.default", "bucket_name", "tf-redshift-logging-test-bucket"), ), }, - - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -85,7 +84,7 @@ func TestAccAWSRedshiftCluster_iamRoles(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -93,8 +92,7 @@ func TestAccAWSRedshiftCluster_iamRoles(t *testing.T) { "aws_redshift_cluster.default", "iam_roles.#", "2"), ), }, - - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -118,7 +116,7 @@ func TestAccAWSRedshiftCluster_publiclyAccessible(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -126,8 +124,7 @@ func TestAccAWSRedshiftCluster_publiclyAccessible(t *testing.T) { "aws_redshift_cluster.default", "publicly_accessible", "false"), ), }, - - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -151,7 +148,7 @@ func TestAccAWSRedshiftCluster_updateNodeCount(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -159,8 +156,7 @@ func TestAccAWSRedshiftCluster_updateNodeCount(t *testing.T) { "aws_redshift_cluster.default", "number_of_nodes", "1"), ), }, - - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -184,7 +180,7 @@ func TestAccAWSRedshiftCluster_tags(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAWSRedshiftClusterDestroy, Steps: []resource.TestStep{ - resource.TestStep{ + { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), @@ -193,8 +189,7 @@ func TestAccAWSRedshiftCluster_tags(t *testing.T) { resource.TestCheckResourceAttr("aws_redshift_cluster.default", "tags.environment", "Production"), ), }, - - resource.TestStep{ + { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v), diff --git a/website/source/docs/providers/aws/r/redshift_cluster.html.markdown b/website/source/docs/providers/aws/r/redshift_cluster.html.markdown index 966a5c3d1da2..06a2ebc13805 100644 --- a/website/source/docs/providers/aws/r/redshift_cluster.html.markdown +++ b/website/source/docs/providers/aws/r/redshift_cluster.html.markdown @@ -33,10 +33,11 @@ string. * `database_name` - (Optional) The name of the first database to be created when the cluster is created. If you do not provide a name, Amazon Redshift will create a default database called `dev`. * `node_type` - (Required) The node type to be provisioned for the cluster. -* `master_password` - (Optional) Password for the master DB user. Note that this may - show up in logs, and it will be stored in the state file. Password must contain at least 8 chars and +* `master_password` - (Required unless a `snapshot_identifier` is provided) Password for the master DB user. + Note that this may show up in logs, and it will be stored in the state file. Password must contain at least 8 chars and contain at least one uppercase letter, one lowercase letter, and one number. -* `master_username` - (Required) Username for the master DB user +* `master_username` - (Required unless a `snapshot_identifier` is provided) Username for the master DB user. + * `cluster_security_groups` - (Optional) A list of security groups to be associated with this cluster. * `vpc_security_group_ids` - (Optional) A list of Virtual Private Cloud (VPC) security groups to be associated with the cluster. * `cluster_subnet_group_name` - (Optional) The name of a cluster subnet group to be associated with this cluster. If this parameter is not provided the resulting cluster will be deployed outside virtual private cloud (VPC).