From d4c5a718a541625fc702dc8f245282a3d0fb0384 Mon Sep 17 00:00:00 2001 From: Vincent Roseberry Date: Mon, 27 Nov 2017 17:58:11 -0800 Subject: [PATCH] Validate account_id length in google_service_account (#793) * Add validation method for RFC1035 names --- google/resource_google_service_account.go | 7 ++-- google/resource_google_service_account_key.go | 7 ++-- google/validation.go | 16 ++++++++++ google/validation_test.go | 32 +++++++++++++++++++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/google/resource_google_service_account.go b/google/resource_google_service_account.go index ecbdcc84..7da0e5d7 100644 --- a/google/resource_google_service_account.go +++ b/google/resource_google_service_account.go @@ -33,9 +33,10 @@ func resourceGoogleServiceAccount() *schema.Resource { Computed: true, }, "account_id": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRFC1035Name(6, 30), }, "display_name": &schema.Schema{ Type: schema.TypeString, diff --git a/google/resource_google_service_account_key.go b/google/resource_google_service_account_key.go index 633ba1f4..bd3f9689 100644 --- a/google/resource_google_service_account_key.go +++ b/google/resource_google_service_account_key.go @@ -17,9 +17,10 @@ func resourceGoogleServiceAccountKey() *schema.Resource { Schema: map[string]*schema.Schema{ // Required "service_account_id": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRFC1035Name(6, 30), }, // Optional "key_algorithm": &schema.Schema{ diff --git a/google/validation.go b/google/validation.go index eacf708a..33f509da 100644 --- a/google/validation.go +++ b/google/validation.go @@ -79,3 +79,19 @@ func validateRFC3339Time(v interface{}, k string) (warnings []string, errors []e } return } + +func validateRFC1035Name(min, max int) schema.SchemaValidateFunc { + if min < 2 || max < min { + return func(i interface{}, k string) (s []string, errors []error) { + if min < 2 { + errors = append(errors, fmt.Errorf("min must be at least 2. Got: %d", min)) + } + if max < min { + errors = append(errors, fmt.Errorf("max must greater than min. Got [%d, %d]", min, max)) + } + return + } + } + + return validateRegexp(fmt.Sprintf(`^[a-z]([-a-z0-9]{%d,%d}[a-z0-9])$`, min-2, max-2)) +} diff --git a/google/validation_test.go b/google/validation_test.go index bc63118f..3ef0d80c 100644 --- a/google/validation_test.go +++ b/google/validation_test.go @@ -74,6 +74,38 @@ func TestValidateRFC3339Time(t *testing.T) { } } +func TestValidateRFC1035Name(t *testing.T) { + cases := []struct { + TestName string + Value string + Min, Max int + ExpectError bool + }{ + {TestName: "valid", Min: 6, Max: 30, Value: "a-valid-name0"}, + {TestName: "valid lower bound", Min: 12, Max: 30, Value: "a-valid-name"}, + {TestName: "valid upper bound", Min: 6, Max: 12, Value: "a-valid-name"}, + {TestName: "valid with numbers", Min: 6, Max: 30, Value: "valid000-name"}, + {TestName: "must start with a letter", Min: 6, Max: 10, Value: "0invalid", ExpectError: true}, + {TestName: "cannot end with a dash", Min: 6, Max: 10, Value: "invalid-", ExpectError: true}, + {TestName: "too short", Min: 6, Max: 10, Value: "short", ExpectError: true}, + {TestName: "too long", Min: 6, Max: 10, Value: "toolooooong", ExpectError: true}, + {TestName: "min too small", Min: 1, Max: 10, Value: "", ExpectError: true}, + {TestName: "min < max", Min: 6, Max: 5, Value: "", ExpectError: true}, + } + + for _, c := range cases { + errors := testStringValidation(StringValidationTestCase{ + TestName: c.TestName, + Value: c.Value, + ExpectError: c.ExpectError, + }, validateRFC1035Name(c.Min, c.Max)) + + if len(errors) > 0 { + t.Errorf("%s failed; %v", c.TestName, errors) + } + } +} + type StringValidationTestCase struct { TestName string Value string