Skip to content

Commit

Permalink
Added name and project_id regex validations (hashicorp#1498)
Browse files Browse the repository at this point in the history
  • Loading branch information
josemanuelt committed May 22, 2018
1 parent 9368945 commit 38f1aea
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
12 changes: 7 additions & 5 deletions google/resource_google_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ func resourceGoogleProject() *schema.Resource {

Schema: map[string]*schema.Schema{
"project_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateProjectID(),
},
"skip_delete": &schema.Schema{
Type: schema.TypeBool,
Expand All @@ -47,8 +48,9 @@ func resourceGoogleProject() *schema.Resource {
Default: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
Type: schema.TypeString,
Required: true,
ValidateFunc: validateProjectName(),
},
"org_id": &schema.Schema{
Type: schema.TypeString,
Expand Down
27 changes: 27 additions & 0 deletions google/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ var (

// Format of default App Engine service accounts created by Google
AppEngineServiceAccountNameRegex = ProjectRegex + "@appspot.gserviceaccount.com"

ProjectIDRegex = "^[a-z][a-z0-9-]{4,28}[a-z0-9]$"
ProjectNameRegex = "^[A-Za-z0-9-'\"\\s!]{4,30}$"
)

var rfc1918Networks = []string{
Expand Down Expand Up @@ -157,3 +160,27 @@ func orEmpty(f schema.SchemaValidateFunc) schema.SchemaValidateFunc {
return f(i, k)
}
}

func validateProjectID() schema.SchemaValidateFunc {
return func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

if !regexp.MustCompile(ProjectIDRegex).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q project_id must be 6 to 30 with lowercase letters, digits, hyphens and start with a letter. Trailing hyphens are prohibited.", value))
}
return
}
}

func validateProjectName() schema.SchemaValidateFunc {
return func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

if !regexp.MustCompile(ProjectNameRegex).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q name must be 4 to 30 characters with lowercase and uppercase letters, numbers, hyphen, single-quote, double-quote, space, and exclamation point.", value))
}
return
}
}
48 changes: 48 additions & 0 deletions google/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,51 @@ func TestOrEmpty(t *testing.T) {
}
}
}

func TestValidateProjectID(t *testing.T) {
x := []StringValidationTestCase{
// No errors
{TestName: "basic", Value: "foobar"},
{TestName: "with numbers", Value: "foobar123"},
{TestName: "short", Value: "foofoo"},
{TestName: "long", Value: "foobarfoobarfoobarfoobarfoobar"},
{TestName: "has a hyphen", Value: "foo-bar"},

// With errors
{TestName: "empty", Value: "", ExpectError: true},
{TestName: "starts with a number", Value: "1foobar", ExpectError: true},
{TestName: "has an slash", Value: "foo/bar", ExpectError: true},
{TestName: "has an upercase letter", Value: "foo-Bar", ExpectError: true},
{TestName: "has a final hyphen", Value: "foo-bar-", ExpectError: true},
{TestName: "too long", Value: strings.Repeat("a", 31), ExpectError: true},
}

es := testStringValidationCases(x, validateProjectID())
if len(es) > 0 {
t.Errorf("Failed to validate project ID's: %v", es)
}
}

func TestValidateProjectName(t *testing.T) {
x := []StringValidationTestCase{
// No errors
{TestName: "basic", Value: "fooBar"},
{TestName: "complex", Value: "project! 'A-1234'"},
{TestName: "with numbers", Value: "foobar123"},
{TestName: "short", Value: "foof"},
{TestName: "long", Value: "foobarfoobarfoobarfoobarfoobar"},
{TestName: "has a hyphen", Value: "foo-bar"},
{TestName: "starts with a number", Value: "1foobar"},
{TestName: "has a final hyphen", Value: "foo-bar-"},

// With errors
{TestName: "empty", Value: "", ExpectError: true},
{TestName: "has an slash", Value: "foo/bar", ExpectError: true},
{TestName: "too long", Value: strings.Repeat("a", 31), ExpectError: true},
}

es := testStringValidationCases(x, validateProjectName())
if len(es) > 0 {
t.Errorf("Failed to validate project ID's: %v", es)
}
}

0 comments on commit 38f1aea

Please sign in to comment.