From f8a22927f9141128f942709dcbf849cb67126469 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 c95127ea372d..a60630c8d22e 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,37 +123,37 @@ 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, @@ -165,49 +165,49 @@ func resourceAwsRedshiftCluster() *schema.Resource { 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, @@ -233,12 +233,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, }, @@ -327,6 +327,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 54df6422f55c..30f67ed9c997 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster_test.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster_test.go @@ -60,7 +60,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), @@ -118,7 +118,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), @@ -128,8 +128,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), @@ -153,7 +152,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), @@ -161,8 +160,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), @@ -186,7 +184,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), @@ -194,8 +192,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), @@ -219,7 +216,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), @@ -227,8 +224,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), @@ -252,7 +248,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), @@ -261,8 +257,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 33504d9295ac..8373097094bb 100644 --- a/website/source/docs/providers/aws/r/redshift_cluster.html.markdown +++ b/website/source/docs/providers/aws/r/redshift_cluster.html.markdown @@ -34,10 +34,11 @@ string. 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. * `cluster_type` - (Optional) The cluster type to use. Either `single-node` or `multi-node`. -* `master_password` - (Required) 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).