Chapter 8. Access resources Automation controller uses a primary key to access individual resource objects. You can access automation controller resources by using resource-specific, human-readable identifiers through the named URL feature. The following example shows the named URL path where you can access a resource object without an auxiliary query string: /api/v2/hosts/host_name++inv_name++org_name/ 8.1. Configuration settings There are two named-URL-related configuration settings available under /api/v2/settings/named-url/: NAMED_URL_FORMATS and NAMED_URL_GRAPH_NODES . NAMED_URL_FORMATS is a read only key-value pair list of all available named URL identifier formats. The following shows an example 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>" } For each item in NAMED_URL_FORMATS , the key is the API name of the resource to have named URL. The value is a string indicating how to form a human-readable unique identifier for that resource. NAMED_URL_FORMATS only lists the resources that can have named URL, any resource not listed there has no named URL. If a resource can have named URL, its objects must have a named_url field that represents the object-specific named URL. That field is only visible under detail view, not list view. You can access specified resource objects by using accurately generated named URL. This the object and its related URLs. For example, if /api/v2/res_name/obj_slug/ is valid, /api/v2/res_name/obj_slug/related_res_name/ is also valid. NAMED_URL_FORMATS are instructive enough to compose human-readable unique identifiers and named URLs themselves. For ease-of-use, every object of a resource that can have named URL has a related field named_url that displays that object's named URL. You can copy and paste that field for your own custom use. For more information, see the help text of the API browser if a resource object has named URL. You can manually decide the named URL label, for example with ID 5. To compose a named URL for this specific resource object by using NAMED_URL_FORMATS , first look up the labels field of NAMED_URL_FORMATS to get the identifier format <name>++<organization.name> : The first part of the URL format is <name> , which indicates that you can find the label resource detail in /api/v2/labels/5/ , and look for name field in returned JSON. If you have the name field with value Foo , then the first part of the unique identifier is Foo . The second part of the format is double plus sign ++. That is the delimiter that separates different parts of a unique identifier. Append them to the unique identifier to get Foo++ . The third part of the format is <organization.name> , which indicates that the field is not in the current label object under investigation, but in an organization that the label object points to. As the format indicates, look up the organization in the related field of the current returned JSON. That field might not exist. If it exists, follow the URL given in that field, for example, /api/v2/organizations/3/ , to get the details of the specific organization, extract its name field, for example, "Default", and append it to the current unique identifier. Since <organizations.name> is the last part of the format, it generates the following named URL: /api/v2/labels/Foo++Default/ . In the case where an organization does not exist in the related field of the label object detail, append an empty string instead. This does not alter the current identifier. Therefore, Foo++ becomes the final unique identifier and the resulting generated named URL becomes /api/v2/labels/Foo++/ . An important aspect of generating a unique identifier for named URL has to do with reserved characters. As the identifier is part of a URL, the following reserved characters by URL standard are encoded by percentage symbols: ;/?:@=&[] . For example, if an organization is named ;/?:@=&[] , its unique identifier should be %3B%2F%3F%3A%40%3D%26%5B%5D . Another special reserved character is + , which is not reserved by URL standard but used by named URL to link different parts of an identifier. It is encoded by [+] . For example, if an organization is named [+] , its unique identifier is %5B[+]%5D , where original [ and ] are percent encoded and + is converted to [+] . Although you cannot manually change NAMED_URL_FORMATS , modifications do occur automatically and expand over time, reflecting underlying resource modification and expansion. Consult the NAMED_URL_FORMATS on the same cluster where you want to use the named URL feature. NAMED_URL_GRAPH_NODES is another read-only list of key-value pairs that exposes the internal graph data structure used to manage named URLs. This is not intended to be human-readable but must be used for programmatically generating named URLs. An example script for generating named URL given the primary key of arbitrary resource objects that can have a named URL, using info provided by NAMED_URL_GRAPH_NODES , can be found in GitHub . 8.2. Identifier format protocol Resources are identifiable by their unique keys, which are tuples of resource fields. Every resource is guaranteed to have its primary key number alone as a unique key, but there might be many other unique keys. A resource can generate an identifier format and, therefore, have a named URL if it has at least one unique key that satisfies the following rules: The key must contain only fields that are either the name field, or text fields with a finite number of possible choices (such as credential type resource's kind field). The only permitted exceptional field that breaks the preceding rule is a many-to-one related field relating to a resource other than itself, which is also allowed to have a slug. If there are resources Foo and Bar , both Foo and Bar contain a name field and a choice field that can only have values "yes" or "no". Additionally, resource Foo has a many-to-one field (a foreign key) relating to Bar , for example fk . Foo has a unique key tuple ( name , choice , fk ) and Bar has a unique key tuple ( name , choice ). Bar can have named URL because it satisfies the preceding first rule. Foo can also have named URL, even though it breaks the first rule, the extra field breaking rule number one is the fk field, which is many-to-one-related to Bar and Bar can have named URL. For resources satisfying the rule number one, their human-readable unique identifiers are combinations of foreign key fields, delimited by + . In specific, resource Bar in the preceding example has slug format <name>+<choice> . Note that the field order matters in slug format and the name field always comes first if present, followed by the remaining fields arranged in lexicographic order of field name. For example, if Bar also has an a_choice field satisfying rule one and the unique key becomes ( name , choice , a_choice ), its slug format becomes <name><a_choice><choice> . For resources satisfying rule number two, if traced back through the extra foreign key fields, the result is a tree of resources that identify objects of that resource. To generate the identifier format, each resource in the traceback tree generates its own part of the standalone format, using all fields but the foreign keys. Finally, all parts are combined by ++ in the following order: Put standalone format as the first identifier part. Recursively generate unique identifiers for each resource. The underlying resource is pointing to using a foreign key (a child of a traceback tree node). Treat generated unique identifiers as the rest of the identifier components. Sort them in lexicographic order of corresponding foreign keys. Combine all components together using ++ to generate the final identifier format. When generating an identifier format for resource Foo , automation controller generates the standalone formats, <name>+<choice> for Foo and <fk.name>+<fk.choice> for Bar , then combines them together to be <name><choice>+<fk.name>+<fk.choice> . When generating identifiers according to the given identifier format, there are cases where a foreign key might point to nowhere. In this case, automation controller substitutes the part of the format corresponding to the resource the foreign key should point to with an empty string. For example, if a Foo object has the name ="alice" , choice ="yes", but fk field = None , its resulting identifier is alice+yes++ .

Commands:
/api/v2/hosts/host_name++inv_name++org_name/
"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>" }