跳转到: 导航, 搜索

指定/蓝图/过滤 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 数据库的影响。 因此,了解真实的性能差异将有助于了解是否需要这种限制。