From c560c72e58f96603873f54570511c4f58251d1fb Mon Sep 17 00:00:00 2001 From: Kazuma Watanabe Date: Mon, 9 Jan 2017 22:12:07 +0900 Subject: [PATCH] provider/aws: Validate window time format (#11089) * create window format validate function * apply ValidateFunc for window time format --- .../providers/aws/resource_aws_db_instance.go | 8 +- .../aws/resource_aws_elasticache_cluster.go | 8 +- .../providers/aws/resource_aws_rds_cluster.go | 8 +- .../aws/resource_aws_redshift_cluster.go | 1 + builtin/providers/aws/validators.go | 24 ++++++ builtin/providers/aws/validators_test.go | 82 +++++++++++++++++++ 6 files changed, 122 insertions(+), 9 deletions(-) diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index ecacd399a..576c2e286 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -120,9 +120,10 @@ func resourceAwsDbInstance() *schema.Resource { }, "backup_window": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateOnceADayWindowFormat, }, "iops": { @@ -147,6 +148,7 @@ func resourceAwsDbInstance() *schema.Resource { } return "" }, + ValidateFunc: validateOnceAWeekWindowFormat, }, "multi_az": { diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster.go b/builtin/providers/aws/resource_aws_elasticache_cluster.go index 3ff71c5a3..2811e9306 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster.go @@ -77,9 +77,10 @@ func resourceAwsElastiCacheCommonSchema() map[string]*schema.Schema { Set: schema.HashString, }, "snapshot_window": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateOnceADayWindowFormat, }, "snapshot_name": &schema.Schema{ Type: schema.TypeString, @@ -96,6 +97,7 @@ func resourceAwsElastiCacheCommonSchema() map[string]*schema.Schema { // to lowercase return strings.ToLower(val.(string)) }, + ValidateFunc: validateOnceAWeekWindowFormat, }, "port": &schema.Schema{ Type: schema.TypeInt, diff --git a/builtin/providers/aws/resource_aws_rds_cluster.go b/builtin/providers/aws/resource_aws_rds_cluster.go index 89b2a35ea..b81af34ca 100644 --- a/builtin/providers/aws/resource_aws_rds_cluster.go +++ b/builtin/providers/aws/resource_aws_rds_cluster.go @@ -160,9 +160,10 @@ func resourceAwsRDSCluster() *schema.Resource { }, "preferred_backup_window": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateOnceADayWindowFormat, }, "preferred_maintenance_window": { @@ -175,6 +176,7 @@ func resourceAwsRDSCluster() *schema.Resource { } return strings.ToLower(val.(string)) }, + ValidateFunc: validateOnceAWeekWindowFormat, }, "backup_retention_period": { diff --git a/builtin/providers/aws/resource_aws_redshift_cluster.go b/builtin/providers/aws/resource_aws_redshift_cluster.go index c72b69070..3d8eec1c1 100644 --- a/builtin/providers/aws/resource_aws_redshift_cluster.go +++ b/builtin/providers/aws/resource_aws_redshift_cluster.go @@ -101,6 +101,7 @@ func resourceAwsRedshiftCluster() *schema.Resource { } return strings.ToLower(val.(string)) }, + ValidateFunc: validateOnceAWeekWindowFormat, }, "cluster_parameter_group_name": { diff --git a/builtin/providers/aws/validators.go b/builtin/providers/aws/validators.go index ed9f2d0b7..bb57d9395 100644 --- a/builtin/providers/aws/validators.go +++ b/builtin/providers/aws/validators.go @@ -624,3 +624,27 @@ func validateSecurityRuleType(v interface{}, k string) (ws []string, errors []er } return } + +func validateOnceAWeekWindowFormat(v interface{}, k string) (ws []string, errors []error) { + // valid time format is "ddd:hh24:mi" + validTimeFormat := "(sun|mon|tue|wed|thu|fri|sat):([0-1][0-9]|2[0-3]):([0-5][0-9])" + + value := strings.ToLower(v.(string)) + if !regexp.MustCompile(validTimeFormat + "-" + validTimeFormat).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must satisfy the format of \"ddd:hh24:mi-ddd:hh24:mi\".", k)) + } + return +} + +func validateOnceADayWindowFormat(v interface{}, k string) (ws []string, errors []error) { + // valid time format is "hh24:mi" + validTimeFormat := "([0-1][0-9]|2[0-3]):([0-5][0-9])" + + value := v.(string) + if !regexp.MustCompile(validTimeFormat + "-" + validTimeFormat).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must satisfy the format of \"hh24:mi-hh24:mi\".", k)) + } + return +} diff --git a/builtin/providers/aws/validators_test.go b/builtin/providers/aws/validators_test.go index f7de51645..6b59a69b7 100644 --- a/builtin/providers/aws/validators_test.go +++ b/builtin/providers/aws/validators_test.go @@ -923,3 +923,85 @@ func TestValidateSecurityRuleType(t *testing.T) { } } } + +func TestValidateOnceAWeekWindowFormat(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + // once a day window format + Value: "04:00-05:00", + ErrCount: 1, + }, + { + // invalid day of week + Value: "san:04:00-san:05:00", + ErrCount: 1, + }, + { + // invalid hour + Value: "sun:24:00-san:25:00", + ErrCount: 1, + }, + { + // invalid min + Value: "sun:04:00-sun:04:60", + ErrCount: 1, + }, + { + // valid format + Value: "sun:04:00-sun:05:00", + ErrCount: 0, + }, + { + // "Sun" can also be used + Value: "Sun:04:00-Sun:05:00", + ErrCount: 0, + }, + } + + for _, tc := range cases { + _, errors := validateOnceAWeekWindowFormat(tc.Value, "maintenance_window") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) + } + } +} + +func TestValidateOnceADayWindowFormat(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + // once a week window format + Value: "sun:04:00-sun:05:00", + ErrCount: 1, + }, + { + // invalid hour + Value: "24:00-25:00", + ErrCount: 1, + }, + { + // invalid min + Value: "04:00-04:60", + ErrCount: 1, + }, + { + // valid format + Value: "04:00-05:00", + ErrCount: 0, + }, + } + + for _, tc := range cases { + _, errors := validateOnceADayWindowFormat(tc.Value, "backup_window") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) + } + } +}