跳转到: 导航, 搜索

Designate/APIv2

此页面应被视为已过时。最新的 API 文档可以在 这里 找到。
这是 Designate 版本 2 API 的草案。在完成实现之前,该草案不应被视为最终版本。

简介

本文档旨在描述 Designate v2 API 将遵循的概念和约定。 几个常用或新的资源已明确详细说明,其他资源则未说明。 任何未明确详细说明的资源应遵循本文档中设定的约定。

Designate v2 API 最终将取代 v1 API,但两者将并存一段时间。 此规范不会影响 v1 API。 v1 API 的保留时间未在此规范中说明。

如有疑问 - 我们遵循 Keystone V3 API 中设定的约定。

基本 APIv2 要求

  1. 将基于字符串的 rdata 切换为基于字典的 rdata。 这允许为更复杂的记录类型(SRV、GeoIP、WRR 等)提供合理的 API。
    1. 这使简单的记录类型复杂化,但简化了复杂的记录类型(SRV、GeoIP、加权 RR、故障转移等)
  2. 引入记录集的概念。 这有助于我们的 API 更准确地反映 DNS 规范,并为相关的 rdata 提供更合理的分组。
    1. 请参阅 RFC2181 第 5 节
  3. 记录“服务器池”的概念。 这允许 API 在我们引入私有 DNS 实例时保持不变。
  4. 提供一种防止并发修改的机制。
    1. 这旨在允许最终用户防止他们的 API 调用更新资源,如果该资源已被另一个 API 客户端更新。
  5. 分页
  6. 结果集的过滤

TODO

  • 所有租户访问
  • 如何在分页响应中包含“总项目数”?
  • 如何选择性地包含嵌套集合?
  • 记录错误响应格式

资源

“池”是一组可以安排区域的 DNS 服务器。 每个池都有一个不同的区域命名空间,允许“example.com”存在于多个池中。

池可以由提供商定义,并标记为“公共”。 公共池将拥有来自多个客户的区域,而私有池将限制为单个 project_id。

此外,客户可以创建私有池。 可用的池风味由提供商定义,可能包括“名称服务器数量”、“AnyCast”等属性。

此 API 的意图有两个方面

  1. 为了使提供商能够提供多个服务级别。 例如,一个在两个数据中心运营的“标准”服务,以及一个通过许多数据中心使用 AnyCast 运营的“高级”服务。
  2. 为了允许客户创建“私有”名称服务器,仅供其实例使用。 这允许客户创建“dev.local”风格的域,而不会与其他用户冲突或将这些名称暴露到全球互联网。
属性 类型 默认 必需 不可变 只读
id uuid 生成
project_id uuid
name 字符串
flavor_id 字符串
public 布尔值
nameservers list<string> 空列表
notes 字符串
status 字符串
version 整数 生成
created_at timestamp 生成
updated_at timestamp 生成

“status”属性的值可以是“ACTIVE”、“PENDING”、“DELETING”、“ERROR”、“ERROR_DELETING”或“SUSPENDED”。

Zone

属性 类型 默认 必需 不可变 只读
id uuid 生成
pool_id uuid 已配置
project_id uuid
name 字符串
email 字符串
ttl 整数 3600
serial 整数 生成
notes 字符串
status 字符串
version 整数 生成
created_at timestamp 生成
updated_at timestamp 生成

“status”属性的值可以是“ACTIVE”、“PENDING”、“DELETING”、“ERROR”、“ERROR_DELETING”或“SUSPENDED”。

记录集

属性 类型 默认 必需 不可变 只读
id uuid 生成
zone_id uuid 已配置
name domainname
type 字符串
ttl 整数 nil
records list<rdata> 空列表
notes 字符串
status 字符串
version 整数 生成
created_at timestamp 生成
updated_at timestamp 生成

“status”属性的值可以是“ACTIVE”、“PENDING”、“DELETING”、“ERROR”或“ERROR_DELETING”。

RData

注意: 此 RData 列表并非完整的列表。 额外的 RData 类型,包括用于 GeoIP/WRR/故障转移等事物的伪 RData,可以在不违反规范的情况下添加。

A

属性 类型 默认 必需 不可变 只读
address ipv4

AAAA

属性 类型 默认 必需 不可变 只读
address ipv6

CNAME

属性 类型 默认 必需 不可变 只读
cname hostname

MX

属性 类型 默认 必需 不可变 只读
preference 整数
exchange hostname

NS

属性 类型 默认 必需 不可变 只读
nsdname hostname

PTR

属性 类型 默认 必需 不可变 只读
ptrdname hostname

SOA

其他限制: 区域中只能存在一个 SOA 记录,并且它必须位于区域的根目录
属性 类型 默认 必需 不可变 只读
mname domainname 生成
rname domainname 生成
serial 整数 生成
refresh 整数 生成
retry 整数 生成
expire 整数 生成
minimun 整数 生成

SPF

属性 类型 默认 必需 不可变 只读
text 字符串

SRV

属性 类型 默认 必需 不可变 只读
priority 整数
weight 整数
port 整数
target hostname

SSHFP

属性 类型 默认 必需 不可变 只读
algorithm 整数
type 整数 1
fingerprint 字符串

TXT

属性 类型 默认 必需 不可变 只读
text 字符串

约定

通用

同步 vs 异步

所有创建、更新和删除操作都可以是异步或同步的。 异步操作仅限于包含“status”属性的资源。 API 消费者不得假定任何 API 调用始终是异步或同步的。 本文档定义了 API 消费者可用于确定已完成的 API 调用是否为异步或同步的方法。

同步

同步创建/更新/删除 API 调用将返回 HTTP 状态“201 Created”、“200 OK”或“204 No Content”。 此外,包含“status”属性的资源必须具有值“ACTIVE”。

异步

异步创建/更新/删除 API 调用将返回 HTTP 状态“202 Accepted”。 “status”属性不得具有值“ACTIVE”。

客户端可以通过查询资源 URL(或,对于创建,在“Location”标头中返回的 URL)并检查“status”属性的值来确定异步作业是否完成。 作业完成后,状态字段将为“ACTIVE”。

集合

以下约定适用于所有集合,除非另有说明。

链接

集合响应的根目录中将存在一个 links 对象。 至少,它将包含一个“self”链接。 如果集合结果集不完整,则将包含“next”和/或“previous”链接以进行分页。

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "examples": [{
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "....": "...."
   }, {
     "id": "fdd7b0dc-52a3-491e-829f-41d18e1d3ada",
     "....": "...."
   }],
   "links": {
     "self": "<URL for This Page>",
     "next": "<URL for Next Page>",
     "previous": "<URL for Previous Page>"
   }
 }

分页

分页在所有集合上可用,并使用两种查询参数组合进行控制 - `marker=<UUID>&limit=<INTEGER>`。 集合响应将包含一个 `links` 对象,其中包含 `next` 和 `previous` 页面的绝对 URL。 这些链接可能在分页集合的边缘被省略或为空。

要浏览集合,可以在 URI 中设置 limit 和 marker 参数(例如?limit=100&marker=<UUID>)。 marker 参数是先前列表中最后一个项目的 ID。 项目按创建时间降序排序。 如果没有可用的创建时间,则按 ID 排序。 limit 参数设置页面大小。 这两个参数都是可选的。

请求

 GET /v2/examples?marker=c74af170-0673-11e3-8ffd-0800200c9a66&limit=2 HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "examples": [{
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "....": "...."
   }, {
     "id": "fdd7b0dc-52a3-491e-829f-41d18e1d3ada",
     "....": "...."
   }],
   "links": {
     "self": "https://dns.provider.com/v2/examples?marker=e728bfe0-0673-11e3-8ffd-0800200c9a66&limit=2",
     "next": "https://dns.provider.com/v2/examples?marker=fdd7b0dc-52a3-491e-829f-41d18e1d3ada&limit=2",
     "previous": "https://dns.provider.com/v2/examples?marker=d9890c50-0673-11e3-8ffd-0800200c9a66&limit=2" 
   }
 }

过滤

过滤在所有集合上可用,并使用与正在过滤的属性名称匹配的查询参数进行控制。 并非所有属性都必须可用作过滤器目标,但大多数属性都是。

可以使用通配符和子字符串匹配,但可能会在 v2 API 的后续版本中引入,只要实现与向后兼容即可。

请求

 GET /v2/examples?title=MyExample HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 
 {
   "examples": [{
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "title": "MyExample",
     "....": "...."
   }, {
     "id": "fdd7b0dc-52a3-491e-829f-41d18e1d3ada",
     "title": "MyExample",
     "....": "...."
   }],
   "links": {
     "...": "..."
   }
 }

嵌套集合

嵌套集合是没有自己 URI 的集合。 我们目前拥有的唯一示例是记录集资源下的“records”数组。

默认情况下,嵌套集合不应包含在其父资源列表中。 例如,列出记录集不应包含返回的每个记录集的“records”集合。

资源

以下约定适用于所有资源,除非另有说明。


链接

资源对象内部将存在一个 links 对象。 至少,它将包含一个“self”链接。

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "example": {
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "....": "....",
     "links": {
       "self": "https://dns.provider.com/v2/examples/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     }
   }
 }

用法

区域操作

创建区域

请求

 POST /v2/zones HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json
 X-Auth-Token: HPAuth_*****
 {
   "zone": {
     "name": "example.org.",
     "email": "joe@example.org",
     "ttl": 7200
   }
 }

响应

 HTTP/1.1 201 Created
 Vary: Accept
 Content-Type: application/json
 Location: https://dns.provider.com/v2/zones/{zone-id}
 {
   "zone": {
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
     "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
     "name": "example.org.",
     "email": "joe@example.org",
     "ttl": 7200,
     "serial": 1351800588,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
     }
   }
 }

获取区域

请求

 GET /v2/zones/{zone-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "zone": {
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
     "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
     "name": "example.org.",
     "email": "joe@example.org.",
     "ttl": 7200,
     "serial": 1351800588,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
     }
   }
 }

列出区域

请求

 GET /v2/zones HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 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",
     "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
     "name": "example.org.",
     "email": "joe@example.org.",
     "ttl": 7200,
     "serial": 1351800588,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
     }
   }, {
     "id": "fdd7b0dc-52a3-491e-829f-41d18e1d3ada",
     "pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
     "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
     "name": "example.net.",
     "email": "joe@example.net.",
     "ttl": 7200,
     "serial": 1351800588,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/fdd7b0dc-52a3-491e-829f-41d18e1d3ada"
     }
   }],
   "links": {
     "self": "https://dns.provider.com/v2/zones",
     "next": "https://dns.provider.com/v2/zones?marker=fdd7b0dc-52a3-491e-829f-41d18e1d3ada"
   }
 }

更新区域

在下面的两个示例中,我们将 TTL 更新为 3600。

请求选项 1 - 正常请求

 PATCH https://dns.provider.com/v2/zones/{zone-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json
 X-Auth-Token: HPAuth_*****
 {
   "zone": {
     "ttl": 3600
   }
 }


请求选项 2 - JSON-Patch 请求

 PATCH https://dns.provider.com/v2/zones/{zone-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json-patch+json
 X-Auth-Token: HPAuth_*****
 [
   {"op": "test", "path": "/zone/version", "value": 1},
   {"op": "replace", "path": "/zone/ttl", "value": 3600}
 ]

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "zone": {
     "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989",
     "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66",
     "name": "example.org.",
     "email": "joe@example.org.",
     "ttl": 3600,
     "serial": 1351800588,
     "status": "ACTIVE",
     "version": 2,
     "created_at": "...",
     "updated_at": "...",
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"
     }
   }
 }

删除区域

请求

 DELETE https://dns.provider.com/v2/zones/{zone-id} HTTP/1.1
 Host: dns.provider.com
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 204 No Content

记录集操作

创建记录集

创建记录集 (A)

请求

 POST https://dns.provider.com/v2/zones/{zone-id}/recordsets HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json
 X-Auth-Token: HPAuth_*****
 {
   "recordset": {
     "name": "www.example.org.",
     "type": "A",
     "ttl": 3600,
     "records": [{
       "address": "10.1.2.3"
     },{
       "address": "10.3.2.1"
     }]
   }
 }

响应

 HTTP/1.1 201 Created
 Vary: Accept
 Content-Type: application/json
 Location: https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}
 {
   "recordset": {
     "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"
     }],
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b"
     }
   }
 }

创建记录集 (SRV)

请求

 POST https://dns.provider.com/v2/zones/{zone-id}/recordsets HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json
 X-Auth-Token: HPAuth_*****
 {
   "recordset": {
     "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."
     }]
   }
 }

响应

 HTTP/1.1 201 Created
 Vary: Accept
 Content-Type: application/json
 Location: https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}
 {
   "recordset": {
     "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."
     }],
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b"
     }
   }
 }

获取记录集

请求

 GET https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "recordset": {
     "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"
     }],
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b"
     }
   }
 }

列出记录集

请求

 GET /v2/zones/{zone-id}/recordsets HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 X-Auth-Token: HPAuth_*****

响应

 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,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b"
     }
   }, {
     "id": "dedf6879-fd9a-41d6-a7c2-eeac316fa7b3",
     "zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
     "name": "_xmpp-server._tcp.example.org.",
     "type": "SRV",
     "ttl": 3600,
     "status": "ACTIVE",
     "version": 1,
     "created_at": "...",
     "updated_at": null,
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/dedf6879-fd9a-41d6-a7c2-eeac316fa7b3"
     }
   }],
   "links": {
     "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets",
     "next": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets?marker=dedf6879-fd9a-41d6-a7c2-eeac316fa7b3"
   }
 }

更新记录集

在下面的两个示例中,我们将“127.0.0.1”添加到 RRSet 记录列表中。

请求选项 1 - 正常请求

 PATCH https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json
 X-Auth-Token: HPAuth_*****
 {
   "recordset": {
     "records": [{
       "address": "10.1.2.3"
     }, {
       "address": "10.3.2.1"
     }, {
       "address": "127.0.0.1"
     }]
   }
 }


请求选项 2 - JSON-Patch 请求

 PATCH https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id} HTTP/1.1
 Host: dns.provider.com
 Accept: application/json
 Content-Type: application/json-patch+json
 X-Auth-Token: HPAuth_*****
 [
   {"op": "test", "path": "/recordset/version", "value": 1},
   {"op": "add", "path": "/recordset/records/-", "value": {"address": "127.0.0.1"}}
 ]


响应

 HTTP/1.1 200 OK
 Vary: Accept
 Content-Type: application/json
 {
   "recordset": {
     "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"
     }],
     "status": "ACTIVE",
     "version": 2,
     "created_at": "...",
     "updated_at": "...",
     "links": {
       "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets/9e27811d-0320-4179-abb7-0e00e371e25b"
     }
   }
 }

删除记录集

请求

 DELETE https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id} HTTP/1.1
 Host: dns.provider.com
 X-Auth-Token: HPAuth_*****

响应

 HTTP/1.1 204 No Content