provider/aws: Validate regular expression passed via the `name_regex` attribute. (#9622)

* Clean-up for Go 1.7+ version.

Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>

* Validate regular expression passed via the `name_regex` attribute.

This commit adds a simple ValidateFunc to check whether the regular
expression that was passed down via the `name_regex` attribute is valid.

Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
This commit is contained in:
Krzysztof Wilczynski 2016-10-26 12:09:14 +01:00 committed by Paul Stack
parent d05db51f7e
commit 44614c6765
2 changed files with 104 additions and 41 deletions

View File

@ -19,24 +19,24 @@ func dataSourceAwsAmi() *schema.Resource {
Read: dataSourceAwsAmiRead,
Schema: map[string]*schema.Schema{
"executable_users": &schema.Schema{
"executable_users": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"filter": &schema.Schema{
"filter": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"values": &schema.Schema{
"values": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
@ -44,158 +44,159 @@ func dataSourceAwsAmi() *schema.Resource {
},
},
},
"name_regex": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
"name_regex": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validateNameRegex,
},
"most_recent": &schema.Schema{
"most_recent": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},
"owners": &schema.Schema{
"owners": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
// Computed values.
"architecture": &schema.Schema{
"architecture": {
Type: schema.TypeString,
Computed: true,
},
"creation_date": &schema.Schema{
"creation_date": {
Type: schema.TypeString,
Computed: true,
},
"description": &schema.Schema{
"description": {
Type: schema.TypeString,
Computed: true,
},
"hypervisor": &schema.Schema{
"hypervisor": {
Type: schema.TypeString,
Computed: true,
},
"image_id": &schema.Schema{
"image_id": {
Type: schema.TypeString,
Computed: true,
},
"image_location": &schema.Schema{
"image_location": {
Type: schema.TypeString,
Computed: true,
},
"image_owner_alias": &schema.Schema{
"image_owner_alias": {
Type: schema.TypeString,
Computed: true,
},
"image_type": &schema.Schema{
"image_type": {
Type: schema.TypeString,
Computed: true,
},
"kernel_id": &schema.Schema{
"kernel_id": {
Type: schema.TypeString,
Computed: true,
},
"name": &schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"owner_id": &schema.Schema{
"owner_id": {
Type: schema.TypeString,
Computed: true,
},
"platform": &schema.Schema{
"platform": {
Type: schema.TypeString,
Computed: true,
},
"public": &schema.Schema{
"public": {
Type: schema.TypeBool,
Computed: true,
},
"ramdisk_id": &schema.Schema{
"ramdisk_id": {
Type: schema.TypeString,
Computed: true,
},
"root_device_name": &schema.Schema{
"root_device_name": {
Type: schema.TypeString,
Computed: true,
},
"root_device_type": &schema.Schema{
"root_device_type": {
Type: schema.TypeString,
Computed: true,
},
"sriov_net_support": &schema.Schema{
"sriov_net_support": {
Type: schema.TypeString,
Computed: true,
},
"state": &schema.Schema{
"state": {
Type: schema.TypeString,
Computed: true,
},
"virtualization_type": &schema.Schema{
"virtualization_type": {
Type: schema.TypeString,
Computed: true,
},
// Complex computed values
"block_device_mappings": &schema.Schema{
"block_device_mappings": {
Type: schema.TypeSet,
Computed: true,
Set: amiBlockDeviceMappingHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"device_name": &schema.Schema{
"device_name": {
Type: schema.TypeString,
Computed: true,
},
"no_device": &schema.Schema{
"no_device": {
Type: schema.TypeString,
Computed: true,
},
"virtual_name": &schema.Schema{
"virtual_name": {
Type: schema.TypeString,
Computed: true,
},
"ebs": &schema.Schema{
"ebs": {
Type: schema.TypeMap,
Computed: true,
},
},
},
},
"product_codes": &schema.Schema{
"product_codes": {
Type: schema.TypeSet,
Computed: true,
Set: amiProductCodesHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"product_code_id": &schema.Schema{
"product_code_id": {
Type: schema.TypeString,
Computed: true,
},
"product_code_type": &schema.Schema{
"product_code_type": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"state_reason": &schema.Schema{
"state_reason": {
Type: schema.TypeMap,
Computed: true,
},
"tags": &schema.Schema{
"tags": {
Type: schema.TypeSet,
Computed: true,
Set: amiTagsHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key": &schema.Schema{
"key": {
Type: schema.TypeString,
Computed: true,
},
"value": &schema.Schema{
"value": {
Type: schema.TypeString,
Computed: true,
},
@ -497,3 +498,14 @@ func amiTagsHash(v interface{}) int {
buf.WriteString(fmt.Sprintf("%s-", m["value"].(string)))
return hashcode.String(buf.String())
}
func validateNameRegex(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if _, err := regexp.Compile(value); err != nil {
errors = append(errors, fmt.Errorf(
"%q contains an invalid regular expression: %s",
k, err))
}
return
}

View File

@ -155,6 +155,57 @@ func TestAccAWSAmiDataSource_localNameFilter(t *testing.T) {
})
}
func TestResourceValidateNameRegex(t *testing.T) {
type testCases struct {
Value string
ErrCount int
}
invalidCases := []testCases{
{
Value: `\`,
ErrCount: 1,
},
{
Value: `**`,
ErrCount: 1,
},
{
Value: `(.+`,
ErrCount: 1,
},
}
for _, tc := range invalidCases {
_, errors := validateNameRegex(tc.Value, "name_regex")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
}
}
validCases := []testCases{
{
Value: `\/`,
ErrCount: 0,
},
{
Value: `.*`,
ErrCount: 0,
},
{
Value: `\b(?:\d{1,3}\.){3}\d{1,3}\b`,
ErrCount: 0,
},
}
for _, tc := range validCases {
_, errors := validateNameRegex(tc.Value, "name_regex")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
}
}
}
func testAccCheckAwsAmiDataSourceDestroy(s *terraform.State) error {
return nil
}