指定/蓝图/过滤 API
目录
需要讨论
该规范仍在进行大量修改,在实施之前需要进一步讨论一些功能。 目前的主要话题是子字符串过滤。 目前,API 支持使用 SQL LIKE 模式匹配进行通配符搜索(例如,abc% 将匹配 abc.com,%abc 将匹配 www.abc,%abc% 将匹配 www.abc.com)。 但是,当客户有数千或数万个资源需要过滤时,左侧带有通配符的查询会对 Designate 系统造成压力,因为它们需要对这些资源进行近乎完全或完全扫描。 在进一步推进之前,需要回答一些问题。
- 是否需要限制子字符串过滤,以便通配符只能位于搜索的最右端(例如,abc%)?
- 如果是这样,我们将如何实现它? 两种可能的方法
- 之前在蓝图中提出的方案:不要依赖 "%" 通配符。 而是添加一个 URL 参数“match_type”,用于确定搜索是精确搜索还是子字符串搜索(默认很可能是精确搜索)。 因此,/zones?name="abc"&match_type=substr 将匹配区域“abc.com.”,但 /zones?name="abc"&match_type=exact 将不会。
- 允许 % 通配符,但如果在过滤条件中的任何位置(最右端除外)存在 % 通配符,则返回错误代码。
- 如果这不是限制子字符串的正确方法,应该如何操作? 或者是否需要这样做?
- 如果是这样,我们将如何实现它? 两种可能的方法
概述
| Gerrit补丁 | [] |
|---|---|
| Launchpad蓝图 | [1] |
过滤提供了一种限定 designate api 查询返回结果集的能力。 它最终将在所有集合上可用 - 区域、记录集、记录集的 rdata 和池。
过滤将使用与要过滤的属性名称匹配的查询参数进行控制。 并非所有属性都需要作为过滤目标可用,但大多数属性都会可用。
过滤器可以是精确匹配或子字符串匹配,由可选的 URL 参数 match_type 指定。 只要实现与旧版本兼容,就可以在 v2 API 的后续版本中引入通配符和正则表达式匹配。 现在,子字符串匹配应仅限于右侧子字符串(例如,/zones?name=abc&match_type=substr 将匹配名称为 abc.com. 和 abcd.com. 的区域,但不匹配 "aabc.com.")。
如果过滤请求成功,则返回通过过滤条件筛选的资源,以及用于检索更多详细信息的链接。
结果分页将利用建议的 Designate 分页 (https://blueprints.launchpad.net/designate/+spec/pagination)
过滤澄清
注意:过滤和搜索是两个完全不同的功能,将分别解决。 搜索涉及从存储中编译结果列表的能力,可能从许多不同的位置获取(例如,查找租户的所有具有特定 IP 地址的 A 记录)。 过滤仅涉及进一步限制 API 提供的标准查询(例如,/zones、/zones/{id}/recordsets 等)。
您可以在 此处 找到搜索规范。
完成历史
该规范已部分实施。 以下是已完成的功能列表以及待完成的功能列表。 此外,为了进一步明确过滤和搜索之间的区别,还包括了专门属于搜索的功能列表。
已完成
- 基本过滤
- 黑名单:pattern
- 记录:data
- 记录集:name, type, TTL
- TLDs:name
- 区域:name
- 使用 SQL 模式匹配的子字符串搜索
待定
- 对子字符串搜索的限制(当前子字符串搜索不受限制)
- 添加更多用于过滤的属性
- 记录集 API 变更后的记录/记录集过滤变更
搜索功能,将不会在此实现
- 跨所有租户搜索其他参数
- 通过添加 all_tenants 选项完成
- 跨所有租户搜索按 IP 地址的记录集
API 变更
过滤 API 的大部分将是对现有资源(区域、记录集、记录集的 rdata 和池)上现有 GET API 的扩展,以使用查询参数指定过滤器。
实现逻辑的高级描述
以下是逻辑流程的高级描述。 详细的请求/响应格式在下面的示例和用例部分中指定。
1. 用户使用适当的过滤器对资源发出过滤请求。 可选地,可以指定额外的参数,match-type(exact/substr)。
例如:GET /v2/zones?name=example.com&match-type=exact HTTP/1.1
Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_*****
2. 在 Central
- 使用请求查询参数作为 WHERE 子句值,对存储数据库发出正确的 SQL 查询。
- 如果过滤器是子字符串过滤器,则修改查询,以便在正在过滤的参数的右侧添加通配符。 然后,使用 SQL LIKE 子句进行过滤。
- 返回到 designate-api
3. Api - 返回结果集。
API 细节
以下是一些过滤示例,包括精确匹配和子字符串匹配。
| 动词 | 资源 | 描述 |
|---|---|---|
| GET | zones/{zone-id}/recordsets/{recordset-id}/records?name=www.example.com&match_type=exact。 | 从指定的记录集中返回名称与指定的过滤器(“name”)完全匹配的任何记录。 |
| GET | zones/{zone-id}/recordsets/{recordset-id}/records?name=www.test&match_type=substr | 从指定的记录集中返回名称中包含指定过滤器(“name”)的任何记录(仅在左侧)。 |
| GET | zones?name=test-server.com.&match_type=exact | 按名称精确搜索区域。 |
| GET | zones?name=test-server | 按名称精确搜索区域。 如果未指定 match_type,则默认情况下为“exact”。 |
特权用户在给定租户中,按名称在指定区域内搜索指定的记录集
这是在可能包含大量记录的给定区域中按名称过滤记录的能力。 通过定义,特定区域属于一个租户,因此即使是特权用户(支持/管理员)也只能在任何特定帐户内搜索,而不能同时跨所有帐户搜索。
请求
GET zones/{zone-id}/recordsets?name=example&match-type=substr
Host: dns.provider.com
Accept: application/json
X-Auth-Token: KeyStoneAuth_*****
X-Tenant-ID: 44441
响应
{
"recordsets": [{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "_xmpp-server._tcp.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-server2._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"
}
}
客户在指定区域内按名称过滤指定的记录集
客户能够过滤属于客户的区域。 通过定义,特定区域属于一个租户。 此外,普通租户无权对任何其他租户 ID 执行任何操作。
请求
GET zones/{zone-id}/recordsets?name=www.example.org.&match-type=exact
Host: dns.provider.com
Accept: application/json
X-Auth-Token: KeyStoneAuth_*****
X-Tenant-ID: 33377
响应
{
"recordsets": [{
"id": "9e27811d-0320-4179-abb7-0e00e371e25b",
"zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3",
"name": "www.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/9e27811d-0320-4179-abb7-0e00e371e25b"
}
}],
"links": {
"self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3/recordsets",
}
}
数据库更改
不适用
建议的测试场景
可以测试每种可能的过滤条件;但是,由于无论过滤的属性如何,查询逻辑都是相似的,因此可能只需要测试一个。 仍然存在多个自由度,包括
- 使用 match_type = exact 或 substr 进行过滤
- 过滤空列表或填充列表
理想情况下,所有这些因素的组合都应该有一个测试用例。
此外,性能测试也很好,特别是为了测试子字符串匹配的效率。 限制子字符串匹配到右侧匹配的主要动力是由于担心左侧匹配对 Designate 数据库的影响。 因此,了解真实的性能差异将有助于了解是否需要这种限制。