Designate/APIv2
This is a EARLY DRAFT of the Designate Version 2 API.
Contents
Basic APIv2 Requirements
- Switch from string based rdata to dict based rdata. This allows for a sane API for the more complex record types (SRV, GEOIP, WRR etc).
- Introduce the concept of RecordSets. This helps our API more accurately reflect the DNS specs, and provides saner grouping of related rdatas.
- Introduce the concept of "server groups". This allows the API to remain the same when we introduce private DNS instances.
- Design error outputs BEFORE writing the code.
- Provided a mechanism to prevent concurrent modifications.
- Pagination
- Filtering of result sets
TODOs
- Ideally, we can support both dict and string based rdata's ({"weight": 0, "priority": 10, "target": "xmpp1.example.org."} AND "0 10 xmpp1.example.org.")
- Pagination?
- All tenant access?
- Should we include a top level container on responses?
- Filtering/searching syntax?
Resources
Zone
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| id | uuid | Generated | ✔ | ✔ | ✔ |
| pool_id | uuid | Configured | ✘ | ✔ | ✘ |
| name | string | None | ✔ | ✔ | ✘ |
| string | None | ✔ | ✘ | ✘ | |
| ttl | int | 3600 | ✔ | ✘ | ✘ |
| serial | int | Generated | ✔ | ✘ | ✔ |
| version | int | Generated | ✔ | ✘ | ✔ |
| created_at | timestamp | Generated | ✔ | ✘ | ✔ |
| updated_at | timestamp | Generated | ✔ | ✘ | ✔ |
Record Set
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| id | uuid | Generated | ✔ | ✔ | ✔ |
| zone_id | uuid | Configured | ✔ | ✔ | ✔ |
| name | domainname | None | ✔ | ✔ | ✘ |
| type | string | None | ✔ | ✔ | ✘ |
| ttl | int | nil | ✔ | ✘ | ✘ |
| records | list<rdata> | Empty List | ✔ | ✘ | ✘ |
| version | int | Generated | ✔ | ✘ | ✔ |
| created_at | timestamp | Generated | ✔ | ✘ | ✔ |
| updated_at | timestamp | Generated | ✔ | ✘ | ✔ |
RData
A
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| address | ipv4 | None | ✔ | ✘ | ✘ |
AAAA
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| address | ipv6 | None | ✔ | ✘ | ✘ |
CNAME
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| cname | hostname | None | ✔ | ✘ | ✘ |
MX
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| preference | int | None | ✔ | ✘ | ✘ |
| exchange | hostname | None | ✔ | ✘ | ✘ |
NS
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| nsdname | hostname | None | ✔ | ✘ | ✘ |
PTR
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| ptrdname | hostname | None | ✔ | ✘ | ✘ |
SOA
{note:title=Additional Restrictions}Only 1 SOA record may be present in a zone, and it must be at the root of the zone{note}
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| mname | domainname | Generated | ✔ | ✔ | ✔ |
| rname | domainname | Generated | ✔ | ✔ | ✔ |
| serial | int | Generated | ✔ | ✔ | ✔ |
| refresh | int | Generated | ✔ | ✔ | ✔ |
| retry | int | Generated | ✔ | ✔ | ✔ |
| expire | int | Generated | ✔ | ✔ | ✔ |
| minimun | int | Generated | ✔ | ✔ | ✔ |
SPF
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| text | string | None | ✔ | ✘ | ✘ |
SRV
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| priority | int | None | ✔ | ✘ | ✘ |
| weight | int | None | ✔ | ✘ | ✘ |
| port | int | None | ✔ | ✘ | ✘ |
| target | hostname | None | ✔ | ✘ | ✘ |
SSHFP
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| algorithm | int | None | ✔ | ✘ | ✘ |
| type | int | 1 | ✔ | ✘ | ✘ |
| fingerprint | string | None | ✔ | ✘ | ✘ |
TXT
| Property | Type | Default | Required | Immutable | Read Only |
|---|---|---|---|---|---|
| text | string | None | ✔ | ✘ | ✘ |
Usage
Zone Operations
Create Zone
Request:
POST /v2/zones HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json X-Auth-Token: HPAuth_*****
{
"name": "example.org.",
"email": "joe@example.org.",
"ttl": 7200
}
Response:
HTTP/1.1 201 Created Vary: Accept Content-Type: application/json Location: https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3
{
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
"name": "example.org.",
"email": "joe@example.org.",
"ttl": 7200,
"serial": 1351800588,
"version": 1,
"created_at": "...",
"updated_at": null
}
Get Zone
Request:
GET /v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3 HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 200 OK Vary: Accept Content-Type: application/json
{
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
"name": "example.org.",
"email": "joe@example.org.",
"ttl": 7200,
"serial": 1351800588,
"version": 1,
"created_at": "...",
"updated_at": null
}
List Zones
Request:
GET /v2/zones HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 200 OK Vary: Accept Content-Type: application/json
{
"zones": [{
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
"name": "example.org.",
"email": "joe@example.org.",
"ttl": 7200,
"serial": 1351800588,
"version": 1,
"created_at": "...",
"updated_at": null
}, {
"id": "fdd7b0dc-52a3-491e-829f-41d18e1d3ada",
"pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
"name": "example.net.",
"email": "joe@example.net.",
"ttl": 7200,
"serial": 1351800588,
"version": 1,
"created_at": "...",
"updated_at": null
}]
}
Update Zone
In both examples below, we update the TTL to 3600.
Request Option 1 - PUT Request:
PUT https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3 HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json X-Auth-Token: HPAuth_*****
{
"ttl": 3600
}
Request Option 2 - PATCH Request:
PATCH https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3 HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json-patch+json X-Auth-Token: HPAuth_*****
[
{"op": "test", "path": "/version", "value": 1},
{"op": "replace", "path": "/ttl", "value": 3600}
]
Response:
HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json
{
"id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
"name": "example.org.",
"email": "joe@example.org.",
"ttl": 3600,
"serial": 1351800588,
"version": 2,
"created_at": "...",
"updated_at": "..."
}
Delete Zone
Request:
DELETE https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3 HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 202 Accepted
RecordSet Operations
Create RecordSet
Create RecordSet (A)
Request:
POST https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json X-Auth-Token: HPAuth_*****
{
"name": "www.example.org.",
"type": "A",
"ttl": 3600,
"records": [{
"address": "10.1.2.3"
},{
"address": "10.3.2.1"
}]
}
Response:
HTTP/1.1 201 Created Vary: Accept Content-Type: application/json Location: https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b
{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "www.example.org.",
"type": "A",
"ttl": 3600,
"records": [{
"address": "10.1.2.3"
},{
"address": "10.3.2.1"
}],
"version": 1,
"created_at": "...",
"updated_at": null
}
Create RecordSet (SRV)
Request:
POST https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json X-Auth-Token: HPAuth_*****
{
"name": "_xmpp-server._tcp.example.org.",
"type": "SRV",
"ttl": 3600,
"records": [{
"weight": 0,
"priority": 10,
"target": "xmpp1.example.org."
}, {
"weight": 0,
"priority": 20,
"target": "xmpp2.example.org."
}]
}
Response:
HTTP/1.1 201 Created Vary: Accept Content-Type: application/json Location: https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b
{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "_xmpp-server._tcp.example.org.",
"type": "SRV",
"ttl": 3600,
"records": [{
"weight": 0,
"priority": 10,
"target": "xmpp1.example.org."
}, {
"weight": 0,
"priority": 20,
"target": "xmpp2.example.org."
}],
"version": 1,
"created_at": "...",
"updated_at": null
}
Get RecordSet
Request:
GET https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 200 OK Vary: Accept Content-Type: application/json
{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "www.example.org.",
"type": "A",
"ttl": 3600,
"records": [{
"address": "10.1.2.3"
},{
"address": "10.3.2.1"
}],
"version": 1,
"created_at": "...",
"updated_at": null
}
List RecordSets
Request:
GET /v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 200 OK Vary: Accept Content-Type: application/json
{
"recordsets": [{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "www.example.org.",
"type": "A",
"ttl": 3600,
"records": [{
"address": "10.1.2.3"
},{
"address": "10.3.2.1"
}],
"version": 1,
"created_at": "...",
"updated_at": null
}, {
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "_xmpp-server._tcp.example.org.",
"type": "SRV",
"ttl": 3600,
"records": [{
"weight": 0,
"priority": 10,
"target": "xmpp1.example.org."
}, {
"weight": 0,
"priority": 20,
"target": "xmpp2.example.org."
}],
"version": 1,
"created_at": "...",
"updated_at": null
}]
}
Update RecordSet
In both examples below, we add "127.0.0.1" to the RRSet records list.
Request Option 1 - PUT Request:
PUT https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json X-Auth-Token: HPAuth_*****
{
"records": [{
"address": "10.1.2.3"
}, {
"address": "10.3.2.1"
}, {
"address": "127.0.0.1"
}]
}
Request Option 2 - PATCH Request:
PATCH https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com Accept: application/json Content-Type: application/json-patch+json X-Auth-Token: HPAuth_*****
[
{"op": "test", "path": "/version", "value": 1},
{"op": "add", "path": "/records/-", "value": {"address": "127.0.0.1"}}
]
Response:
HTTP/1.1 202 Accepted Vary: Accept Content-Type: application/json
{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "www.example.org.",
"type": "A",
"ttl": 3600,
"records": [{
"address": "10.1.2.3"
}, {
"address": "10.3.2.1"
}, {
"address": "127.0.0.1"
}],
"version": 2,
"created_at": "...",
"updated_at": "..."
}
Delete RecordSet
Request:
DELETE https://region-a.geo-1.dns.hpcloudsvc.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b HTTP/1.1 Host: region-a.geo-1.dns.hpcloudsvc.com X-Auth-Token: HPAuth_*****
Response:
HTTP/1.1 202 Accepted