Merge pull request #11197 from hashicorp/f-add-cloudflare-record-validation

provider/cloudflare: Add validation for record types and record content
This commit is contained in:
Jake Champlin 2017-01-13 18:20:03 -05:00 committed by GitHub
commit fd20f16a06
3 changed files with 121 additions and 3 deletions

View File

@ -34,9 +34,10 @@ func resourceCloudFlareRecord() *schema.Resource {
}, },
"type": &schema.Schema{ "type": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
ValidateFunc: validateRecordType,
}, },
"value": &schema.Schema{ "value": &schema.Schema{
@ -88,6 +89,11 @@ func resourceCloudFlareRecordCreate(d *schema.ResourceData, meta interface{}) er
newRecord.TTL = ttl.(int) newRecord.TTL = ttl.(int)
} }
// Validate value based on type
if err := validateRecordName(newRecord.Type, newRecord.Content); err != nil {
return fmt.Errorf("Error validating record name %q: %s", newRecord.Name, err)
}
zoneId, err := client.ZoneIDByName(newRecord.ZoneName) zoneId, err := client.ZoneIDByName(newRecord.ZoneName)
if err != nil { if err != nil {
return fmt.Errorf("Error finding zone %q: %s", newRecord.ZoneName, err) return fmt.Errorf("Error finding zone %q: %s", newRecord.ZoneName, err)

View File

@ -0,0 +1,51 @@
package cloudflare
import (
"fmt"
"net"
"strings"
)
// validateRecordType ensures that the cloudflare record type is valid
func validateRecordType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
validTypes := map[string]struct{}{
"A": {},
"AAAA": {},
"CNAME": {},
"TXT": {},
"SRV": {},
"LOC": {},
"MX": {},
"NS": {},
"SPF": {},
}
if _, ok := validTypes[value]; !ok {
errors = append(errors, fmt.Errorf(
`%q contains an invalid type %q. Valid types are "A", "AAAA", "CNAME", "TXT", "SRV", "LOC", "MX", "NS" or "SPF"`, k, value))
}
return
}
// validateRecordName ensures that based on supplied record type, the name content matches
// Currently only validates A and AAAA types
func validateRecordName(t string, value string) error {
switch t {
case "A":
// Must be ipv4 addr
addr := net.ParseIP(value)
if addr == nil || !strings.Contains(value, ".") {
return fmt.Errorf("A record must be a valid IPv4 address, got: %q", value)
}
case "AAAA":
// Must be ipv6 addr
addr := net.ParseIP(value)
if addr == nil || !strings.Contains(value, ":") {
return fmt.Errorf("AAAA record must be a valid IPv6 address, got: %q", value)
}
}
return nil
}

View File

@ -0,0 +1,61 @@
package cloudflare
import "testing"
func TestValidateRecordType(t *testing.T) {
validTypes := []string{
"A",
"AAAA",
"CNAME",
"TXT",
"SRV",
"LOC",
"MX",
"NS",
"SPF",
}
for _, v := range validTypes {
_, errors := validateRecordType(v, "type")
if len(errors) != 0 {
t.Fatalf("%q should be a valid record type: %q", v, errors)
}
}
invalidTypes := []string{
"a",
"cName",
"txt",
"SRv",
"foo",
"bar",
}
for _, v := range invalidTypes {
_, errors := validateRecordType(v, "type")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid record type", v)
}
}
}
func TestValidateRecordName(t *testing.T) {
validNames := map[string]string{
"A": "192.168.0.1",
"AAAA": "2001:0db8:0000:0042:0000:8a2e:0370:7334",
}
for k, v := range validNames {
if err := validateRecordName(k, v); err != nil {
t.Fatalf("%q should be a valid name for type %q: %v", v, k, err)
}
}
invalidNames := map[string]string{
"A": "terraform.io",
"AAAA": "192.168.0.1",
}
for k, v := range invalidNames {
if err := validateRecordName(k, v); err == nil {
t.Fatalf("%q should be an invalid name for type %q", v, k)
}
}
}