diff --git a/dns_zones.go b/dns_zones.go index 5127008..4533e31 100644 --- a/dns_zones.go +++ b/dns_zones.go @@ -8,6 +8,7 @@ import ( const zoneAvailableNameserversURL = "/dns/available-name-servers.json" const zoneListURL = "/dns/list-zones.json" +const zoneCreateUrl = "/dns/register.json" const zoneGetURL = "/dns/get-zone-info.json" const zoneTriggerUpdateURL = "/dns/update-zone.json" const zoneUpdateStatusURL = "/dns/update-status.json" @@ -78,6 +79,47 @@ type ZoneUpdateStatus struct { IsUpdated APIBool `json:"updated"` } +type CreateZone struct { + Name string `json:"name"` + Type ZoneType `json:"type"` + Ns []string `json:"ns"` + MasterIp string `json:"master_ip"` +} + +// AsParams returns the HTTP parameters for a zone to use within the create zone API method +func (zone CreateZone) AsParams() HTTPParams { + params := HTTPParams{ + "domain-name": zone.Name, + "ns": zone.Ns, + } + switch zone.Type { + case ZoneTypeMaster: + params["zone-type"] = "master" + case ZoneTypeGeoDNS: + params["zone-type"] = "geo-dns" + case ZoneTypeParked: + params["zone-type"] = "parked" + case ZoneTypeSlave: + params["zone-type"] = "slave" + params["master-ip"] = zone.MasterIp + case ZoneTypeUnknown: + params["zone-type"] = "unknown" + } + + return params +} + +// NewZone instantiates a new CreateZone which can be used within ClouDNS API methods. It does -not- add this zone +// automatically. +func NewZone(name string, zoneType ZoneType, ns []string, masterIp string) CreateZone { + return CreateZone{ + Name: name, + Type: zoneType, + Ns: ns, + MasterIp: masterIp, + } +} + // List returns all zones // Official Docs: https://www.cloudns.net/wiki/article/50/ func (svc *ZoneService) List(ctx context.Context) ([]Zone, error) { @@ -181,6 +223,14 @@ func (svc *ZoneService) GetUsage(ctx context.Context) (result ZoneUsage, err err return } +// Create a new zone +func (svc *ZoneService) Create(ctx context.Context, zone CreateZone) (result StatusResult, err error) { + params := zone.AsParams() + + err = svc.api.request(ctx, "POST", zoneCreateUrl, params, nil, &result) + return +} + // UnmarshalJSON converts the ClouDNS zone type into the correct ZoneType enumeration value func (zt *ZoneType) UnmarshalJSON(data []byte) error { switch strings.Trim(string(data), `"`) { diff --git a/dns_zones_test.go b/dns_zones_test.go index 1de5b38..a3e7f6b 100644 --- a/dns_zones_test.go +++ b/dns_zones_test.go @@ -1,8 +1,9 @@ package cloudns import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestZoneService_AvailableNameservers(t *testing.T) { @@ -90,3 +91,14 @@ func TestZoneService_GetUsage(t *testing.T) { _, err := client.Zones.GetUsage(ctx) assert.NoError(t, err, "should not fail") } + +func TestZoneService_Create(t *testing.T) { + teardown := setup(t) + defer teardown() + + zone := NewZone("sampion.io", ZoneTypeMaster, []string{}, "") + _, err := client.Zones.Create(ctx, zone) + if err != nil { + t.Fatalf("Records.Create() returned error: %v", err) + } +} diff --git a/fixtures/TestZoneService_Create.yaml b/fixtures/TestZoneService_Create.yaml new file mode 100644 index 0000000..d374850 --- /dev/null +++ b/fixtures/TestZoneService_Create.yaml @@ -0,0 +1,105 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.cloudns.net + remote_addr: "" + request_uri: "" + body: '{"domain-name":"sampion.io","ns":[],"zone-type":"master"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - cloudns-go/test + url: https://api.cloudns.net/dns/add-record.json + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"status":"Failed","statusDescription":"Invalid authentication, incorrect user ID or password."}' + headers: + Content-Type: + - application/json + Date: + - Sat, 04 Mar 2023 08:51:41 GMT + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000; includeSubdomains; preload + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: 605.6862ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.cloudns.net + remote_addr: "" + request_uri: "" + body: '{"domain-name":"sampion.io","ns":[],"zone-type":"master"}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - cloudns-go/test + url: https://api.cloudns.net/dns/register.json + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: -1 + uncompressed: true + body: '{"status":"Failed","statusDescription":"Invalid authentication, incorrect user ID or password."}' + headers: + Content-Type: + - application/json + Date: + - Sat, 04 Mar 2023 09:26:16 GMT + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000; includeSubdomains; preload + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: 734.0522ms diff --git a/go.mod b/go.mod index ebbb7c9..d03db0f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ppmathis/cloudns-go +module github.com/inamvar/cloudns-go go 1.16