diff --git a/builtin/providers/aws/resource_aws_redshift_cluster.go b/builtin/providers/aws/resource_aws_redshift_cluster.go index b8fc2b874..4dba95777 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster.go @@ -56,8 +56,9 @@ func resourceAwsRedshiftCluster() *schema.Resource { }, "master_password": &schema.Schema{ - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validateRedshiftClusterMasterPassword, }, "cluster_security_groups": &schema.Schema{ @@ -800,6 +801,26 @@ func validateRedshiftClusterMasterUsername(v interface{}, k string) (ws []string return } +func validateRedshiftClusterMasterPassword(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if !regexp.MustCompile(`^.*[a-z].*`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must contain at least one lowercase letter", k)) + } + if !regexp.MustCompile(`^.*[A-Z].*`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must contain at least one uppercase letter", k)) + } + if !regexp.MustCompile(`^.*[0-9].*`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must contain at least one number", k)) + } + if len(value) < 8 { + errors = append(errors, fmt.Errorf("%q must be more than 8 characters", k)) + } + return +} + func buildRedshiftARN(identifier, accountid, region string) (string, error) { if accountid == "" { return "", fmt.Errorf("Unable to construct cluster ARN because of missing AWS Account ID") diff --git a/builtin/providers/aws/resource_aws_redshift_cluster_test.go b/builtin/providers/aws/resource_aws_redshift_cluster_test.go index 903278c88..2e30cccc2 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster_test.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster_test.go @@ -408,6 +408,44 @@ func TestResourceAWSRedshiftClusterMasterUsernameValidation(t *testing.T) { } } +func TestResourceAWSRedshiftClusterMasterPasswordValidation(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "1TESTING", + ErrCount: 1, + }, + { + Value: "1testing", + ErrCount: 1, + }, + { + Value: "TestTest", + ErrCount: 1, + }, + { + Value: "T3st", + ErrCount: 1, + }, + { + Value: "1Testing", + ErrCount: 0, + }, + } + + for _, tc := range cases { + fmt.Printf("Test Case Value: %s\n", tc.Value) + _, errors := validateRedshiftClusterMasterPassword(tc.Value, "aws_redshift_cluster_master_password") + fmt.Printf("Expected: %d and found %d\n", tc.ErrCount, len(errors)) + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected the Redshift Cluster master_password to trigger a validation error") + } + } +} + var testAccAWSRedshiftClusterConfig_updateNodeCount = ` resource "aws_redshift_cluster" "default" { cluster_identifier = "tf-redshift-cluster-%d"