通常,Ansible Tower 使用主键访问单个资源对象。从 3.2 和 API v2 开始,命名的 URL 功能允许您通过特定于资源的人类可读标识符来访问 Tower 资源。在 3.2 之前的 Ansible Tower 版本中,不使用辅助查询字符串访问资源对象的唯一方法是通过资源主键号(例如,通过 URL 路径:/api/v2/hosts/2/
)。现在,您可以使用命名 URL 来进行同一操作,例如通过 URL 路径 /api/v2/hosts/host_name++inv_name++org_name/
。
/api/v2/settings/named-url/
下有两个与 named-URL 相关的 Tower 配置设置:
NAMED_URL_FORMATS
和NAMED_URL_GRAPH_NODES
NAMED_URL_FORMATS
是所有可用命名 URL 标识符格式的只读键值对列表。典型的 NAMED_URL_FORMATS
如下所示:
"NAMED_URL_FORMATS": {
"job_templates": "<name>",
"workflow_job_templates": "<name>",
"inventories": "<name>++<organization.name>",
"users": "<username>",
"custom_inventory_scripts": "<name>++<organization.name>",
"labels": "<name>++<organization.name>",
"credential_types": "<name>+<kind>",
"notification_templates": "<name>++<organization.name>",
"instances": "<hostname>",
"instance_groups": "<name>",
"hosts": "<name>++<inventory.name>++<organization.name>",
"system_job_templates": "<name>",
"groups": "<name>++<inventory.name>++<organization.name>",
"organizations": "<name>",
"credentials": "<name>++<credential_type.name>+<credential_type.kind>++<organization.name>",
"teams": "<name>++<organization.name>",
"inventory_sources": "<name>",
"projects": "<name>"
}
对于 NAMED_URL_FORMATS
中的每项,键是具有命名 URL 的资源的 API 名称,值是一个字符串,表明如何为该资源形成一个人类可读的唯一标识符。NAMED_URL_FORMATS
仅列出所有可具有命名 URL 的资源,任何没有列出的资源都没有命名 URL。如果资源可具有命名 URL,则其对象应具有 named_url 字段,该字段代表特定于对象是命名 URL。该字段只能在详情视图中可见,而不是列表视图。您可以使用准确生成的命名 URL来访问指定的资源对象。这不仅包括对象本身还包括其相关的 URL。例如,如果 /api/v2/res_name/obj_slug/
有效,则 /api/v2/res_name/obj_slug/related_res_name/
也将有效。
NAMED_URL_FORMATS
指导性强,可以自行编写人类可读的唯一标识符和命名 URL。为了实现易用性,具有命名 URL 的资源的每个对象都会具有一个相关的字段 named_url
来显示对象的命名 URL。您可以复制并粘贴该字段供您自己自定义使用。另外,如果资源对象具有命名 URL,还可参考 API 浏览器的帮助文本,以获得进一步指导。
假设您要手动决定一个 ID 为 5 的标签的命名 URL。使用 NAMED_URL_FORMATS
为此特定资源对象编写命名 URL 的典型步骤是首先查找 NAMED_URL_FORMATS
的标签字段,以获得标识符格式 <name>++<organization.name>
:
URL 格式的第一部分是
<name>
,它表示可在/api/v2/labels/5/
中找到标签资源详情,并在返回的 JSON 中查找name
字段。假定请具有带值“Foo”的name
字段,那么唯一标识符的第一部分为 Foo。这个格式的第二部分是双加号 ++。 这是分隔一个唯一标识符的不同部分的限定符。将它们附加到唯一标识符以获得 Foo++
格式的第三个部分是
<organization.name>
,它代表字段不在调查下的当前标签对象中,但在标签对象指向的机构中。因此,如格式所示,在当前返回的 JSON 的相关字段中查找机构。字段可能存在也可能不存在。如果存在,点击字段中给定的 URL,例如/api/v2/organizations/3/
用于获得特定机构的详细信息,提取其name
字段,例如“默认”,并将其附加到当前的唯一标示符中。因为<organizations.name>
是格式的最后一部分,因此,生成结果命名 URL/api/v2/labels/Foo++Default/
。如果标签对象详情的相关字段中不存在机构,请附加空字符串,它基本不会改变当前标识符。因此Foo++
变为最终的唯一标识符,结果生成的命名 URL 变为/api/v2/labels/Foo++/
。
为命名 URL 生成唯一标识符的一个重要方面是处理保留的字符。因为标识符是 URL 的一部分,以下 URL 标准保留的字符使用百分比符号 ;/?:@=&[]
来编码。例如,如果一个机构被命名 ;/?:@=&[]
,它的唯一保留标识符应该是 %3B%2F%3F%3A%40%3D%26%5B%5D
。另一个特殊的保留符是 +
,它不是由 URL 标准保留,而是由链接标识符不同部分的命名 URL 使用。它由 [+]
编码。例如,如果机构命名为 [+]
,其唯一标示符是 %5B[+]%5D
,其中原始 [
和 ]
时百分比编码,+
转换为 [+]
。
虽然 NAMED_URL_FORMATS
无法手动修改,但修改操作会随着时间自动进行并扩展,反映底层的资源修改和扩展。请在您要使用命名 URL 功能的同一个 Tower 集群中查看 NAMED_URL_FORMATS
。
NAMED_URL_GRAPH_NODES
是另一个只读键值对列表,它公开了用来管理命名 URL 的内部图形数据结构 Tower。它不用于人工读取,而是应该用于编程生成命名 URL。用于生成命名 URL 的示例脚本给出了任意资源对象的主键,它可能具有命名 URL,使用 NAMED_URL_GRAPH_NODES
提供的信息,可在 GitHub 中找到:https://github.com/ansible/awx/blob/devel/tools/scripts/pk_to_named_url.py.
Tower 中的资源可以通过其唯一键来识别,它们基本是资源字段的元组。每个 Tower 资源都保证将其主键数作为唯一键,但可能还有多个其他唯一键。因此,如果资源至少包含满足以下规则的唯一键,则可生成标识符格式,具有命名 URL:
键必须只包含 name
字段或文本字段,且具有有限数量的选项(比如凭证类型资源的 kind
字段)。
可以不满足第一条规则的唯一允例外字段是与自身以外的资源相关的多对一的关联字段,它也允许具有 slug。
假设 Tower 具有资源 Foo
和 Bar
,Foo
和 Bar
含有 name
字段和 choice
字段,后者的值只能是“yes”或“no”。另外,资源 Foo
包含与 Bar
相关的多对一字段(外键),例如 fk
。Foo
具有唯一键元组(name
、choice
、fk
),Bar
具有唯一键元组(name
、choice
)。Bar
可以具有命名 URL,因为它满足的上面的第一条规则。Foo
也可具有命名 URL,但是它违背了第一条规则,违背规则的额外字段是 fk
字段,它是多对一与 Bar
和 Bar
相关,可以具有命名 URL。
对于满足上述第一条规则的资源,它们的人类可读唯一标识符是外键字段的组合,由 +
限定。具体来说,上例中的资源 Bar
将使用 slug 格式 <name>+<choice>
。请注意,在 slug 格式中字段顺序很重要:name
字段总是排在最前(如果存在),后面是所有字段名称按字母顺序排列的剩余字段。例如,如果 Bar 还具有满足第一条规则 的 a_choice
字段,且唯一键将变为(name
、choice
、a_choice
),其 slug 格式变为 <name>+<a_choice>+<choice>
。
对于满足上面第二条规则要求的资源,如果通过额外的外键字段追溯,结果是一个资源树,所有资源都标识该资源的对象。为了生成标识符格式,追溯树中的每个资源都会以前面描述的方式生成自己的独立格式,使用所有字段,但不使用外键。最后,所有组件都按照以下顺序由 ++
组合:
将独立格式设置为第一个标识符组件。
为每个资源递归生成唯一标识符。底层资源指向使用一个外键(追溯 树节点的子代)。
将生成的唯一标识符作为标识符组件的其余部分处理,按对应外键的字符顺序排序。
使用 ++
组合所有组件来生成最终识别符格式。
在上面的例子中,在为资源 Foo
生成标识符格式时,Tower 会生成独立格式,<name>+<choice>
用于 Foo
和 <fk.name>+<fk.choice>
用于 Bar
,然后将它们组合在一起成为 <name>+<choice>++<fk.name>+<fk.choice>
。
根据给定的标识符格式生成标识符时,会出现外键可能不指向任何位置的情况。在这种情况下,Tower 替换了与该资源相对应的格式部分,外键应该指向一个空字符串。例如,如果对象 Foo
具有 name ='alice', choice ='yes',但 fk
field = None,则其生成的标识符将是 alice+yes++
。