Skip to content

Commit

Permalink
zone: Add support for partial zone management (#294)
Browse files Browse the repository at this point in the history
Updates the `CreateZone` function to allow the creation of a partially
managed zone within Cloudflare. Prior to this change, all zones were
assumed as full setups.

This unblocks some work in
terraform-providers/terraform-provider-cloudflare#280 where we would
like the ability to manage all zone types instead of just full zones.
  • Loading branch information
jacobbednarz authored and patryk committed Apr 19, 2019
1 parent b311651 commit 9108469
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 2 deletions.
7 changes: 6 additions & 1 deletion cmd/flarectl/zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,17 @@ func zoneCreate(c *cli.Context) {
zone := c.String("zone")
jumpstart := c.Bool("jumpstart")
orgID := c.String("org-id")
zoneType := c.String("type")
var org cloudflare.Organization
if orgID != "" {
org.ID = orgID
}

_, err := api.CreateZone(zone, jumpstart, org)
if zoneType != "partial" {
zoneType = "full"
}

_, err := api.CreateZone(zone, jumpstart, org, zoneType)
if err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("%s", err))
return
Expand Down
9 changes: 8 additions & 1 deletion zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ type PurgeCacheResponse struct {
type newZone struct {
Name string `json:"name"`
JumpStart bool `json:"jump_start"`
Type string `json:"type"`
// We use a pointer to get a nil type when the field is empty.
// This allows us to completely omit this with json.Marshal().
Organization *Organization `json:"organization,omitempty"`
Expand All @@ -276,14 +277,20 @@ type newZone struct {
// This will add the new zone to the specified multi-user organization.
//
// API reference: https://api.cloudflare.com/#zone-create-a-zone
func (api *API) CreateZone(name string, jumpstart bool, org Organization) (Zone, error) {
func (api *API) CreateZone(name string, jumpstart bool, org Organization, zoneType string) (Zone, error) {
var newzone newZone
newzone.Name = name
newzone.JumpStart = jumpstart
if org.ID != "" {
newzone.Organization = &org
}

if zoneType == "partial" {
newzone.Type = "partial"
} else {
newzone.Type = "full"
}

res, err := api.makeRequest("POST", "/zones", newzone)
if err != nil {
return Zone{}, errors.Wrap(err, errMakeRequestError)
Expand Down
270 changes: 270 additions & 0 deletions zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,273 @@ func TestZoneFilter(t *testing.T) {
t.Errorf("expected param %s to be %s, got %s", "name", "example.org", got)
}
}

var createdAndModifiedOn, _ = time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
var expectedFullZoneSetup = Zone{
ID: "023e105f4ecef8ad9ca31a8372d0c353",
Name: "example.com",
DevMode: 7200,
OriginalNS: []string{
"ns1.originaldnshost.com",
"ns2.originaldnshost.com",
},
OriginalRegistrar: "GoDaddy",
OriginalDNSHost: "NameCheap",
CreatedOn: createdAndModifiedOn,
ModifiedOn: createdAndModifiedOn,
Owner: Owner{
ID: "7c5dae5552338874e5053f2534d2767a",
Email: "user@example.com",
OwnerType: "user",
},
Account: Account{
ID: "01a7362d577a6c3019a474fd6f485823",
Name: "Demo Account",
},
Permissions: []string{"#zone:read", "#zone:edit"},
Plan: ZonePlan{
ZonePlanCommon: ZonePlanCommon{
ID: "e592fd9519420ba7405e1307bff33214",
Name: "Pro Plan",
Price: 20,
Currency: "USD",
Frequency: "monthly",
},
LegacyID: "pro",
IsSubscribed: true,
CanSubscribe: true,
},
PlanPending: ZonePlan{
ZonePlanCommon: ZonePlanCommon{
ID: "e592fd9519420ba7405e1307bff33214",
Name: "Pro Plan",
Price: 20,
Currency: "USD",
Frequency: "monthly",
},
LegacyID: "pro",
IsSubscribed: true,
CanSubscribe: true,
},
Status: "active",
Paused: false,
Type: "full",
NameServers: []string{"tony.ns.cloudflare.com", "woz.ns.cloudflare.com"},
}
var expectedPartialZoneSetup = Zone{
ID: "023e105f4ecef8ad9ca31a8372d0c353",
Name: "example.com",
DevMode: 7200,
OriginalNS: []string{
"ns1.originaldnshost.com",
"ns2.originaldnshost.com",
},
OriginalRegistrar: "GoDaddy",
OriginalDNSHost: "NameCheap",
CreatedOn: createdAndModifiedOn,
ModifiedOn: createdAndModifiedOn,
Owner: Owner{
ID: "7c5dae5552338874e5053f2534d2767a",
Email: "user@example.com",
OwnerType: "user",
},
Account: Account{
ID: "01a7362d577a6c3019a474fd6f485823",
Name: "Demo Account",
},
Permissions: []string{"#zone:read", "#zone:edit"},
Plan: ZonePlan{
ZonePlanCommon: ZonePlanCommon{
ID: "e592fd9519420ba7405e1307bff33214",
Name: "Pro Plan",
Price: 20,
Currency: "USD",
Frequency: "monthly",
},
LegacyID: "pro",
IsSubscribed: true,
CanSubscribe: true,
},
PlanPending: ZonePlan{
ZonePlanCommon: ZonePlanCommon{
ID: "e592fd9519420ba7405e1307bff33214",
Name: "Pro Plan",
Price: 20,
Currency: "USD",
Frequency: "monthly",
},
LegacyID: "pro",
IsSubscribed: true,
CanSubscribe: true,
},
Status: "active",
Paused: false,
Type: "partial",
NameServers: []string{"tony.ns.cloudflare.com", "woz.ns.cloudflare.com"},
}

func TestCreateZoneFullSetup(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, "POST", "Expected method 'POST', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "023e105f4ecef8ad9ca31a8372d0c353",
"name": "example.com",
"development_mode": 7200,
"original_name_servers": [
"ns1.originaldnshost.com",
"ns2.originaldnshost.com"
],
"original_registrar": "GoDaddy",
"original_dnshost": "NameCheap",
"created_on": "2014-01-01T05:20:00.12345Z",
"modified_on": "2014-01-01T05:20:00.12345Z",
"activated_on": "2014-01-02T00:01:00.12345Z",
"owner": {
"id": "7c5dae5552338874e5053f2534d2767a",
"email": "user@example.com",
"type": "user"
},
"account": {
"id": "01a7362d577a6c3019a474fd6f485823",
"name": "Demo Account"
},
"permissions": [
"#zone:read",
"#zone:edit"
],
"plan": {
"id": "e592fd9519420ba7405e1307bff33214",
"name": "Pro Plan",
"price": 20,
"currency": "USD",
"frequency": "monthly",
"legacy_id": "pro",
"is_subscribed": true,
"can_subscribe": true
},
"plan_pending": {
"id": "e592fd9519420ba7405e1307bff33214",
"name": "Pro Plan",
"price": 20,
"currency": "USD",
"frequency": "monthly",
"legacy_id": "pro",
"is_subscribed": true,
"can_subscribe": true
},
"status": "active",
"paused": false,
"type": "full",
"name_servers": [
"tony.ns.cloudflare.com",
"woz.ns.cloudflare.com"
]
}
}
`)
}

mux.HandleFunc("/zones", handler)

actual, err := client.CreateZone(
"example.com",
false,
Organization{ID: "01a7362d577a6c3019a474fd6f485823"},
"full",
)

if assert.NoError(t, err) {
assert.Equal(t, expectedFullZoneSetup, actual)
}
}

func TestCreateZonePartialSetup(t *testing.T) {
setup()
defer teardown()

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Method, "POST", "Expected method 'POST', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "023e105f4ecef8ad9ca31a8372d0c353",
"name": "example.com",
"development_mode": 7200,
"original_name_servers": [
"ns1.originaldnshost.com",
"ns2.originaldnshost.com"
],
"original_registrar": "GoDaddy",
"original_dnshost": "NameCheap",
"created_on": "2014-01-01T05:20:00.12345Z",
"modified_on": "2014-01-01T05:20:00.12345Z",
"activated_on": "2014-01-02T00:01:00.12345Z",
"owner": {
"id": "7c5dae5552338874e5053f2534d2767a",
"email": "user@example.com",
"type": "user"
},
"account": {
"id": "01a7362d577a6c3019a474fd6f485823",
"name": "Demo Account"
},
"permissions": [
"#zone:read",
"#zone:edit"
],
"plan": {
"id": "e592fd9519420ba7405e1307bff33214",
"name": "Pro Plan",
"price": 20,
"currency": "USD",
"frequency": "monthly",
"legacy_id": "pro",
"is_subscribed": true,
"can_subscribe": true
},
"plan_pending": {
"id": "e592fd9519420ba7405e1307bff33214",
"name": "Pro Plan",
"price": 20,
"currency": "USD",
"frequency": "monthly",
"legacy_id": "pro",
"is_subscribed": true,
"can_subscribe": true
},
"status": "active",
"paused": false,
"type": "partial",
"name_servers": [
"tony.ns.cloudflare.com",
"woz.ns.cloudflare.com"
]
}
}
`)
}

mux.HandleFunc("/zones", handler)

actual, err := client.CreateZone(
"example.com",
false,
Organization{ID: "01a7362d577a6c3019a474fd6f485823"},
"partial",
)

if assert.NoError(t, err) {
assert.Equal(t, expectedPartialZoneSetup, actual)
}
}

0 comments on commit 9108469

Please sign in to comment.