-
Notifications
You must be signed in to change notification settings - Fork 626
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New resource: cloudflare_zone. Closes #58
- Loading branch information
Showing
5 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package cloudflare | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
"strconv" | ||
"strings" | ||
|
||
cloudflare "github.com/cloudflare/cloudflare-go" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/helper/validation" | ||
) | ||
|
||
func resourceCloudflareZone() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceCloudflareZoneCreate, | ||
Read: resourceCloudflareZoneRead, | ||
Update: resourceCloudflareZoneUpdate, | ||
Delete: resourceCloudflareZoneDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"zone": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringMatch(regexp.MustCompile("^([a-zA-Z0-9][\\-a-zA-Z0-9]*\\.)+[\\-a-zA-Z0-9]{2,20}$"), ""), | ||
}, | ||
"jump_start": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { | ||
return true | ||
}, | ||
}, | ||
"paused": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
"vanity_name_servers": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"meta": { | ||
Type: schema.TypeMap, | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"page_rule_quota": { | ||
Type: schema.TypeInt, | ||
}, | ||
"wildcard_proxiable": { | ||
Type: schema.TypeBool, | ||
}, | ||
"phishing_detected": { | ||
Type: schema.TypeBool, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"status": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"type": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"name_servers": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
func resourceCloudflareZoneCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
|
||
zoneName := d.Get("zone").(string) | ||
jumpstart := d.Get("jump_start").(bool) | ||
organization := cloudflare.Organization{ | ||
ID: client.OrganizationID, | ||
} | ||
|
||
log.Printf("[INFO] Creating Cloudflare Zone: name %s", zoneName) | ||
|
||
zone, err := client.CreateZone(zoneName, jumpstart, organization) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error creating zone %q: %s", zoneName, err) | ||
} | ||
|
||
d.SetId(zone.ID) | ||
|
||
if paused, ok := d.GetOk("paused"); ok { | ||
if paused.(bool) == true { | ||
_, err := client.ZoneSetPaused(zone.ID, paused.(bool)) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error updating zone_id %q: %s", zone.ID, err) | ||
} | ||
} | ||
} | ||
|
||
return resourceCloudflareZoneRead(d, meta) | ||
} | ||
|
||
func resourceCloudflareZoneRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
zoneID := d.Id() | ||
|
||
zone, err := client.ZoneDetails(zoneID) | ||
|
||
log.Printf("[DEBUG] ZoneDetails: %#v", zone) | ||
log.Printf("[DEBUG] ZoneDetails error: %#v", err) | ||
|
||
if err != nil { | ||
if strings.Contains(err.Error(), "HTTP status 404") { | ||
log.Printf("[INFO] Zone %s no longer exists", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("Error finding Zone %q: %s", d.Id(), err) | ||
} | ||
|
||
d.Set("paused", zone.Paused) | ||
d.Set("vanity_name_servers", zone.VanityNS) | ||
d.Set("status", zone.Status) | ||
d.Set("type", zone.Type) | ||
d.Set("name_servers", zone.NameServers) | ||
d.Set("meta", flattenMeta(d, zone.Meta)) | ||
|
||
return nil | ||
} | ||
|
||
func resourceCloudflareZoneUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
zoneID := d.Id() | ||
|
||
log.Printf("[INFO] Updating Cloudflare Zone: id %s", zoneID) | ||
|
||
if paused, ok := d.GetOkExists("paused"); ok { | ||
log.Printf("[DEBUG] _ paused") | ||
|
||
_, err := client.ZoneSetPaused(zoneID, paused.(bool)) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error updating zone_id %q: %s", zoneID, err) | ||
} | ||
} | ||
|
||
return resourceCloudflareZoneRead(d, meta) | ||
} | ||
|
||
func resourceCloudflareZoneDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
zoneID := d.Id() | ||
|
||
log.Printf("[INFO] Deleting Cloudflare Zone: id %s", zoneID) | ||
|
||
_, err := client.DeleteZone(zoneID) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error deleting Cloudflare Zone: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func flattenMeta(d *schema.ResourceData, meta cloudflare.ZoneMeta) map[string]interface{} { | ||
cfg := map[string]interface{}{} | ||
|
||
cfg["page_rule_quota"] = strconv.Itoa(meta.PageRuleQuota) | ||
cfg["wildcard_proxiable"] = strconv.FormatBool(meta.WildcardProxiable) | ||
cfg["phishing_detected"] = strconv.FormatBool(meta.PhishingDetected) | ||
|
||
log.Printf("[DEBUG] flattenMeta %#v", cfg) | ||
|
||
return cfg | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package cloudflare | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
) | ||
|
||
func TestZone(t *testing.T) { | ||
name := "cloudflare_zone.test" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testZoneConfig("test", "example.org", "true", "false"), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(name, "zone", "example.org"), | ||
resource.TestCheckResourceAttr(name, "paused", "true"), | ||
resource.TestCheckResourceAttr(name, "name_servers.#", "2"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testZoneConfig(resourceID, zoneName, paused, jumpStart string) string { | ||
return fmt.Sprintf(` | ||
resource "cloudflare_zone" "%[1]s" { | ||
zone = "%[2]s" | ||
paused = %[3]s | ||
jump_start = %[4]s | ||
}`, resourceID, zoneName, paused, jumpStart) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
layout: "cloudflare" | ||
page_title: "Cloudflare: cloudflare_zone" | ||
sidebar_current: "docs-cloudflare-resource-zone" | ||
description: |- | ||
Provides a Cloudflare resource to create and modify a zone. | ||
--- | ||
|
||
# cloudflare_zone | ||
|
||
Provides a Cloudflare Zone resource. Zone is the basic resource for working with Cloudflare and is roughly equivalent to a domain name that the user purchases. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "cloudflare_zone" "example" { | ||
zone = "example.com" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
* `zone` - (Required) The DNS zone name which will be added. | ||
* `paused` - (Optional) Boolean of whether this zone is paused (traffic bypasses Cloudflare). Default: false. | ||
* `jump_start` - (Optional) Boolean of whether to scan for DNS records on creation. Ignored after zone is created. Default: false. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `id` - The zone ID. | ||
* `vanity_name_servers` - List of Vanity Nameservers (if set). | ||
* `meta.page_rule_quota` - Number of page rules that can be created. | ||
* `meta.wildcard_proxiable` - Indicates whether wildcard DNS records can receive Cloudflare security and performance features. | ||
* `meta.phishing_detected` - Indicates if URLs on the zone have been identified as hosting phishing content. | ||
* `status` - Status of the zone. Valid values: `active`, `pending`, `initializing`, `moved`, `deleted`, `deactivated` | ||
* `type` - A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Valid values: `full`, `partial` | ||
* `name_servers` - Cloudflare-assigned name servers. This is only populated for zones that use Cloudflare DNS. | ||
|
||
## Import | ||
|
||
Zone resource can be imported using a zone ID, e.g. | ||
|
||
``` | ||
$ terraform import cloudflare_zone.example d41d8cd98f00b204e9800998ecf8427e | ||
``` | ||
|
||
where: | ||
|
||
* `d41d8cd98f00b204e9800998ecf8427e` - zone ID, as returned from [API](https://api.cloudflare.com/#zone-list-zones) |