diff --git a/builtin/providers/cloudflare/resource_cloudflare_record.go b/builtin/providers/cloudflare/resource_cloudflare_record.go index ad478dc7ddd8..a5f861f54802 100644 --- a/builtin/providers/cloudflare/resource_cloudflare_record.go +++ b/builtin/providers/cloudflare/resource_cloudflare_record.go @@ -17,6 +17,8 @@ func resourceCloudFlareRecord() *schema.Resource { Update: resourceCloudFlareRecordUpdate, Delete: resourceCloudFlareRecordDelete, + SchemaVersion: 1, + MigrateState: resourceAwsCloudFlareRecordMigrateState, Schema: map[string]*schema.Schema{ "domain": &schema.Schema{ Type: schema.TypeString, diff --git a/builtin/providers/cloudflare/resource_cloudflare_record_migrate.go b/builtin/providers/cloudflare/resource_cloudflare_record_migrate.go new file mode 100644 index 000000000000..63c0e24ab24b --- /dev/null +++ b/builtin/providers/cloudflare/resource_cloudflare_record_migrate.go @@ -0,0 +1,96 @@ +package cloudflare + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform/terraform" + // NOTE: Temporary until they merge my PR: + "github.com/mitchellh/cloudflare-go" +) + +func resourceAwsCloudFlareRecordMigrateState( + v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { + switch v { + case 0: + log.Println("[INFO] Found AWS CloudFlare Record State v0; migrating to v1") + return migrateCloudFlareRecordStateV0toV1(is, meta) + default: + return is, fmt.Errorf("Unexpected schema version: %d", v) + } +} + +func migrateCloudFlareRecordStateV0toV1(is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { + if is.Empty() { + log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") + return is, nil + } + + log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes) + client := meta.(*cloudflare.API) + + // look up new id based on attributes + domain := is.Attributes["domain"] + zoneId, err := client.ZoneIDByName(domain) + if err != nil { + return is, fmt.Errorf("Error finding zone %q: %s", domain, err) + } + + // all other information is ignored in the DNSRecords call + searchRecord := cloudflare.DNSRecord{ + Type: is.Attributes["type"], + Name: is.Attributes["hostname"], + Content: is.Attributes["value"], + } + + records, err := client.DNSRecords(zoneId, searchRecord) + if err != nil { + return is, err + } + + for _, r := range records { + if is.Attributes["ttl"] != "" { + v, err := strconv.Atoi(is.Attributes["ttl"]) + if err != nil { + return is, fmt.Errorf("Error converting ttl to int in CloudFlare Record Migration") + } + + if v != r.TTL { + continue + } + } + + if is.Attributes["proxied"] != "" { + b, err := strconv.ParseBool(is.Attributes["proxied"]) + if err != nil { + return is, fmt.Errorf("Error converting proxied to bool in CloudFlare Record Migration") + } + + if b != r.Proxied { + continue + } + } + + if is.Attributes["priority"] != "" { + v, err := strconv.Atoi(is.Attributes["priority"]) + if err != nil { + return is, fmt.Errorf("Error converting priority to int in CloudFlare Record Migration") + } + + if v != r.Priority { + continue + } + } + + // assume record found + is.Attributes["id"] = r.ID + is.ID = r.ID + log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes) + return is, nil + } + + // assume no record found + log.Printf("[DEBUG] Attributes after no migration: %#v", is.Attributes) + return is, fmt.Errorf("No matching Record found") +}