mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Add name validation function, standardise validation functions used (#164)
* Used standard validation functions where possible, added a GCP name validation function. * Add tests for GCP name, factor out a ValidateRegexp function. * make fmt
This commit is contained in:
parent
5882f3145a
commit
4cc6e9939a
@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
compute "google.golang.org/api/compute/v1"
|
compute "google.golang.org/api/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,15 +25,9 @@ func dataSourceGoogleComputeZones() *schema.Resource {
|
|||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, es []error) {
|
ValidateFunc: validation.StringInSlice([]string{"UP", "DOWN"}, false),
|
||||||
value := v.(string)
|
|
||||||
if value != "UP" && value != "DOWN" {
|
|
||||||
es = append(es, fmt.Errorf("%q can only be 'UP' or 'DOWN' (%q given)", k, value))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
"github.com/hashicorp/terraform/helper/pathorcontents"
|
"github.com/hashicorp/terraform/helper/pathorcontents"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
"golang.org/x/oauth2/jwt"
|
"golang.org/x/oauth2/jwt"
|
||||||
)
|
)
|
||||||
@ -68,7 +69,7 @@ func dataSourceGoogleSignedUrl() *schema.Resource {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: "GET",
|
Default: "GET",
|
||||||
ValidateFunc: validateHttpMethod,
|
ValidateFunc: validation.StringInSlice([]string{"GET", "HEAD", "PUT", "DELETE"}, true),
|
||||||
},
|
},
|
||||||
"path": &schema.Schema{
|
"path": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
@ -93,15 +94,6 @@ func validateExtensionHeaders(v interface{}, k string) (ws []string, errors []er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateHttpMethod(v interface{}, k string) (ws []string, errs []error) {
|
|
||||||
value := v.(string)
|
|
||||||
value = strings.ToUpper(value)
|
|
||||||
if value != "GET" && value != "HEAD" && value != "PUT" && value != "DELETE" {
|
|
||||||
errs = append(errs, errors.New("http_method must be one of [GET|HEAD|PUT|DELETE]"))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceGoogleSignedUrlRead(d *schema.ResourceData, meta interface{}) error {
|
func dataSourceGoogleSignedUrlRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package google
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"google.golang.org/api/compute/v1"
|
"google.golang.org/api/compute/v1"
|
||||||
@ -18,18 +17,10 @@ func resourceComputeBackendBucket() *schema.Resource {
|
|||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validateGCPName,
|
||||||
value := v.(string)
|
|
||||||
re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
|
|
||||||
if !regexp.MustCompile(re).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q (%q) doesn't match regexp %q", k, value, re))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"bucket_name": &schema.Schema{
|
"bucket_name": &schema.Schema{
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
@ -23,18 +22,10 @@ func resourceComputeBackendService() *schema.Resource {
|
|||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validateGCPName,
|
||||||
value := v.(string)
|
|
||||||
re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
|
|
||||||
if !regexp.MustCompile(re).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q (%q) doesn't match regexp %q", k, value, re))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"health_checks": &schema.Schema{
|
"health_checks": &schema.Schema{
|
||||||
|
@ -26,15 +26,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||||||
Computed: true,
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ConflictsWith: []string{"name_prefix"},
|
ConflictsWith: []string{"name_prefix"},
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validateGCPName,
|
||||||
// https://cloud.google.com/compute/docs/reference/latest/instanceTemplates#resource
|
|
||||||
value := v.(string)
|
|
||||||
if len(value) > 63 {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot be longer than 63 characters", k))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"name_prefix": &schema.Schema{
|
"name_prefix": &schema.Schema{
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
@ -20,18 +19,10 @@ func resourceComputeRegionBackendService() *schema.Resource {
|
|||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validateGCPName,
|
||||||
value := v.(string)
|
|
||||||
re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
|
|
||||||
if !regexp.MustCompile(re).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q (%q) doesn't match regexp %q", k, value, re))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"health_checks": &schema.Schema{
|
"health_checks": &schema.Schema{
|
||||||
|
@ -28,15 +28,7 @@ func resourceComputeSslCertificate() *schema.Resource {
|
|||||||
Computed: true,
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ConflictsWith: []string{"name_prefix"},
|
ConflictsWith: []string{"name_prefix"},
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validateGCPName,
|
||||||
// https://cloud.google.com/compute/docs/reference/latest/sslCertificates#resource
|
|
||||||
value := v.(string)
|
|
||||||
if len(value) > 63 {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot be longer than 63 characters", k))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"name_prefix": &schema.Schema{
|
"name_prefix": &schema.Schema{
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
|
|
||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
"google.golang.org/api/sqladmin/v1beta4"
|
"google.golang.org/api/sqladmin/v1beta4"
|
||||||
@ -167,18 +168,14 @@ func resourceSqlDatabaseInstance() *schema.Resource {
|
|||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"day": &schema.Schema{
|
"day": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validation.IntBetween(1, 7),
|
||||||
return validateNumericRange(v, k, 1, 7)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"hour": &schema.Schema{
|
"hour": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
ValidateFunc: validation.IntBetween(0, 23),
|
||||||
return validateNumericRange(v, k, 0, 23)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"update_track": &schema.Schema{
|
"update_track": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
@ -1179,15 +1176,6 @@ func resourceSqlDatabaseInstanceDelete(d *schema.ResourceData, meta interface{})
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateNumericRange(v interface{}, k string, min int, max int) (ws []string, errors []error) {
|
|
||||||
value := v.(int)
|
|
||||||
if min > value || value > max {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q outside range %d-%d.", k, min, max))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func instanceMutexKey(project, instance_name string) string {
|
func instanceMutexKey(project, instance_name string) string {
|
||||||
return fmt.Sprintf("google-sql-database-instance-%s-%s", project, instance_name)
|
return fmt.Sprintf("google-sql-database-instance-%s-%s", project, instance_name)
|
||||||
}
|
}
|
||||||
|
24
google/validation.go
Normal file
24
google/validation.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func validateGCPName(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
|
||||||
|
return validateRegexp(re)(v, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateRegexp(re string) schema.SchemaValidateFunc {
|
||||||
|
return func(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(re).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q (%q) doesn't match regexp %q", k, value, re))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
57
google/validation_test.go
Normal file
57
google/validation_test.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidateGCPName(t *testing.T) {
|
||||||
|
x := []GCPNameTestCase{
|
||||||
|
// No errors
|
||||||
|
{TestName: "basic", Value: "foobar"},
|
||||||
|
{TestName: "with numbers", Value: "foobar123"},
|
||||||
|
{TestName: "short", Value: "f"},
|
||||||
|
{TestName: "long", Value: "foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo"},
|
||||||
|
{TestName: "has a hyphen", Value: "foo-bar"},
|
||||||
|
|
||||||
|
// With errors
|
||||||
|
{TestName: "empty", Value: "", ExpectError: true},
|
||||||
|
{TestName: "starts with a capital", Value: "Foobar", ExpectError: true},
|
||||||
|
{TestName: "starts with a number", Value: "1foobar", ExpectError: true},
|
||||||
|
{TestName: "has an underscore", Value: "foo_bar", ExpectError: true},
|
||||||
|
{TestName: "too long", Value: "foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoob", ExpectError: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
es := testGCPNames(x)
|
||||||
|
if len(es) > 0 {
|
||||||
|
t.Errorf("Failed to validate GCP names: %v", es)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GCPNameTestCase struct {
|
||||||
|
TestName string
|
||||||
|
Value string
|
||||||
|
ExpectError bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGCPNames(cases []GCPNameTestCase) []error {
|
||||||
|
es := make([]error, 0)
|
||||||
|
for _, c := range cases {
|
||||||
|
es = append(es, testGCPName(c)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return es
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGCPName(testCase GCPNameTestCase) []error {
|
||||||
|
_, es := validateGCPName(testCase.Value, testCase.TestName)
|
||||||
|
if testCase.ExpectError {
|
||||||
|
if len(es) > 0 {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return []error{fmt.Errorf("Didn't see expected error in case \"%s\" with string \"%s\"", testCase.TestName, testCase.Value)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return es
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user