From dfd275ea1bcc00bda1880c993e47228e3a9e7811 Mon Sep 17 00:00:00 2001 From: Alex Munda Date: Wed, 3 Feb 2021 11:39:33 -0600 Subject: [PATCH] Validate Consul datacenter and lowercase the default --- internal/provider/resource_consul_cluster.go | 13 ++-- internal/provider/validators.go | 23 ++++-- internal/provider/validators_test.go | 76 ++++++++++++++++++++ 3 files changed, 102 insertions(+), 10 deletions(-) diff --git a/internal/provider/resource_consul_cluster.go b/internal/provider/resource_consul_cluster.go index d7990fbe5..d797a3a1f 100644 --- a/internal/provider/resource_consul_cluster.go +++ b/internal/provider/resource_consul_cluster.go @@ -115,11 +115,12 @@ func resourceConsulCluster() *schema.Resource { }, }, "datacenter": { - Description: "The Consul data center name of the cluster. If not specified, it is defaulted to the value of `cluster_id`.", - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, + Description: "The Consul data center name of the cluster. If not specified, it is defaulted to the value of `cluster_id`.", + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ValidateDiagFunc: validateDatacenter, }, "connect_enabled": { Description: "Denotes the Consul connect feature should be enabled for this cluster. Default to true.", @@ -260,7 +261,7 @@ func resourceConsulClusterCreate(ctx context.Context, d *schema.ResourceData, me return diag.Errorf("specified Consul version (%s) is unavailable; must be one of: %v", consulVersion, availableConsulVersions) } - datacenter := clusterID + datacenter := strings.ToLower(clusterID) v, ok = d.GetOk("datacenter") if ok { datacenter = v.(string) diff --git a/internal/provider/validators.go b/internal/provider/validators.go index 520e35f9d..30cca2fc6 100644 --- a/internal/provider/validators.go +++ b/internal/provider/validators.go @@ -72,13 +72,10 @@ func validateSemVer(v interface{}, path cty.Path) diag.Diagnostics { } // validateSlugID validates that the string value matches the HCP requirements for -// a user-settable slug, as well as the Azure requirements for a Managed Application name. +// a user-settable slug. func validateSlugID(v interface{}, path cty.Path) diag.Diagnostics { var diagnostics diag.Diagnostics - // HCP supports a max of 36 chars for the cluster name which is defaulted to - // the value of of the Managed App name so we must enforce a max of 36 even though - // Azure supports a max of 64 chars for the Managed App name if !regexp.MustCompile(`^[-\da-zA-Z]{3,36}$`).MatchString(v.(string)) { msg := "must be between 3 and 36 characters in length and contains only letters, numbers or hyphens" diagnostics = append(diagnostics, diag.Diagnostic{ @@ -91,3 +88,21 @@ func validateSlugID(v interface{}, path cty.Path) diag.Diagnostics { return diagnostics } + +// validateDatacenter validates that the string value matches the HCP requirements for +// a Consul datacenter name. +func validateDatacenter(v interface{}, path cty.Path) diag.Diagnostics { + var diagnostics diag.Diagnostics + + if !regexp.MustCompile(`^[-_\da-z]{3,36}$`).MatchString(v.(string)) { + msg := "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores" + diagnostics = append(diagnostics, diag.Diagnostic{ + Severity: diag.Error, + Summary: msg, + Detail: msg, + AttributePath: path, + }) + } + + return diagnostics +} diff --git a/internal/provider/validators_test.go b/internal/provider/validators_test.go index b77a47a66..7dd156dd3 100644 --- a/internal/provider/validators_test.go +++ b/internal/provider/validators_test.go @@ -185,3 +185,79 @@ func Test_validateSlugID(t *testing.T) { }) } } + +func Test_validateDatacenter(t *testing.T) { + tcs := map[string]struct { + expected diag.Diagnostics + input string + }{ + "valid datacenter": { + input: "hello-123_456", + expected: nil, + }, + "empty string": { + input: "", + expected: diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + Detail: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + AttributePath: nil, + }, + }, + }, + "invalid characters": { + input: "test@123", + expected: diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + Detail: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + AttributePath: nil, + }, + }, + }, + "uppercase characters": { + input: "Test123", + expected: diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + Detail: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + AttributePath: nil, + }, + }, + }, + "too short": { + input: "ab", + expected: diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + Detail: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + AttributePath: nil, + }, + }, + }, + "too long": { + input: "abcdefghi1abcdefghi1abcdefghi12345678", + expected: diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + Detail: "must be between 3 and 36 characters in length and contains only lowercase letters, numbers, hyphens, or underscores", + AttributePath: nil, + }, + }, + }, + } + + for n, tc := range tcs { + t.Run(n, func(t *testing.T) { + r := require.New(t) + + result := validateDatacenter(tc.input, nil) + r.Equal(tc.expected, result) + }) + } +}