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:
parent
d05db51f7e
commit
44614c6765
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue