8. 访问资源

传统上,AWX 使用主键访问单个资源对象。命名 URL 功能允许您通过特定于资源的人类可读标识符访问 AWX 资源。例如,通过 URL 路径 /api/v2/hosts/host_name++inv_name++org_name/ 的命名 URL 允许您访问资源对象而无需辅助查询字符串。

8.1. 配置设置

/api/v2/settings/named-url/ 下提供了两个与命名 URL 相关的配置设置:NAMED_URL_FORMATSNAMED_URL_GRAPH_NODES

NAMED_URL_FORMATS 是所有可用命名 URL 标识符格式的只读键值对列表。一个典型的 NAMED_URL_FORMATS 看起来像这样:

"NAMED_URL_FORMATS": {
"organizations": "<name>",
"teams": "<name>++<organization.name>",
"credential_types": "<name>+<kind>",
"credentials": "<name>++<credential_type.name>+<credential_type.kind>++<organization.name>",
"notification_templates": "<name>++<organization.name>",
"job_templates": "<name>++<organization.name>",
"projects": "<name>++<organization.name>",
"inventories": "<name>++<organization.name>",
"hosts": "<name>++<inventory.name>++<organization.name>",
"groups": "<name>++<inventory.name>++<organization.name>",
"inventory_sources": "<name>++<inventory.name>++<organization.name>",
"inventory_scripts": "<name>++<organization.name>",
"instance_groups": "<name>",
"labels": "<name>++<organization.name>",
"workflow_job_templates": "<name>++<organization.name>",
"workflow_job_template_nodes": "<identifier>++<workflow_job_template.name>++<organization.name>",
"applications": "<name>++<organization.name>",
"users": "<username>",
"instances": "<hostname>"
}

对于 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 的 labels 字段以获取标识符格式 <name>++<organization.name>

  • URL 格式的第一部分是 <name>,这表示标签资源详细信息可以在 /api/v2/labels/5/ 中找到,并在返回的 JSON 中查找 name 字段。假设您的 name 字段的值为“Foo”,则唯一标识符的第一部分为 **Foo**。

  • 格式的第二部分是两个加号 ++。这是分隔唯一标识符不同部分的分隔符。将其附加到唯一标识符以获得 **Foo++**。

  • 格式的第三部分是 <organization.name>,这表示该字段不在正在调查的当前标签对象中,而是在标签对象指向的组织中。因此,如格式所示,在返回的 JSON 的相关字段中查找组织。该字段可能存在也可能不存在。如果存在,请按照该字段中提供的 URL(例如 /api/v2/organizations/3/)获取特定组织的详细信息,提取其 name 字段(例如,“Default”),并将其附加到我们当前的唯一标识符。由于 <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 功能的同一集群上的 NAMED_URL_FORMATS

NAMED_URL_GRAPH_NODES 是另一个只读的键值对列表,它公开用于管理命名 URL 的内部图数据结构。这并非旨在为人阅读,而应用于以编程方式生成命名 URL。可以在 GitHub 上找到一个示例脚本,该脚本使用 NAMED_URL_GRAPH_NODES 提供的信息,根据可以具有命名 URL 的任意资源对象的 primary key 生成命名 URL,地址为 https://github.com/ansible/awx/blob/devel/tools/scripts/pk_to_named_url.py

8.2. 标识符格式协议

资源可以通过其唯一键来识别,这些键基本上是资源字段的元组。保证每个资源都只有其主键编号作为唯一键,但可能还有多个其他唯一键。如果资源包含至少一个满足以下规则的唯一键,则可以生成标识符格式,从而拥有命名 URL。

  1. 该键必须仅包含以下字段:name 字段,或具有有限数量可能选择的文本字段(例如凭据类型资源的 kind 字段)。

  2. 违反规则 #1 的唯一允许的例外字段是与自身以外的资源的多对一相关字段,该字段也允许具有 slug。

假设存在资源 FooBarFooBar 都包含一个 name 字段和一个 choice 字段,该字段只能具有值“yes”或“no”。此外,资源 Foo 包含一个与 Bar 相关的多对一字段(外键),例如 fkFoo 有一个唯一键元组(namechoicefk),Bar 有一个唯一键元组(namechoice)。Bar 可以具有命名 URL,因为它满足上面的规则 #1。 Foo 也可以具有命名 URL,即使它违反了规则 #1,违反规则 #1 的额外字段是 fk 字段,它与 Bar 多对一相关,而 Bar 可以具有命名 URL。

对于满足上述规则 #1 的资源,其人类可读的唯一标识符是由外键字段组合而成,并以 + 分隔。具体来说,上述示例中的资源 Bar 将具有 <name>+<choice> 的slug格式。请注意字段顺序在slug格式中很重要:如果存在 name 字段,则始终放在首位,之后是所有其余字段,按字段名称的字典顺序排列。例如,如果Bar还具有满足规则 #1 的 a_choice 字段,并且唯一键变为(namechoicea_choice),则其slug格式变为 <name>+<a_choice>+<choice>

对于满足上述规则 #2 的资源,如果通过额外外键字段追溯,结果将是一棵资源树,这些资源共同标识该资源的对象。为了生成标识符格式,追溯树中的每个资源都以之前描述的方式生成其自身的独立格式部分,使用所有字段,但不包括外键。最后,所有部分都按以下顺序用 ++ 组合

  • 将独立格式作为第一个标识符组件。

  • 递归地为每个资源生成唯一标识符。底层资源使用外键(追溯树节点的子节点)进行指向。

  • 将生成的唯一标识符视为标识符组件的其余部分。按相应外键的字典顺序对其进行排序。

  • 使用 ++ 将所有组件组合在一起,以生成最终的标识符格式。

参考上述示例,在为资源 Foo 生成标识符格式时,AWX 生成独立格式 <name>+<choice> 用于 Foo<fk.name>+<fk.choice> 用于 Bar,然后将它们组合在一起,得到 <name>+<choice>++<fk.name>+<fk.choice>

根据给定的标识符格式生成标识符时,外键可能指向任何地方的情况。在这种情况下,AWX 将对应于外键应指向的资源的格式部分替换为空字符串“”。例如,如果一个 Foo 对象具有 name =’alice’,choice =’yes’,但 fk 字段 = None,则其生成的标识符将为 alice+yes++