首页 > 解决方案 > 如何在 URI 模块 GET 注册循环输出中检索值?

问题描述

我正在通过 Ansible Tower API 搜索作业模板,并希望从存储在注册结果 json 条目中的返回的“名称”和“id”字段中创建键/值对的字典 (?)。

- name: Search for job templates
  uri:
    url: "{{ tower_url }}/api/v2/job_templates?search={{ item.name }}"
    method: GET
    user: admin
    password: "{{ tower_admin_password }}"
    force_basic_auth: yes
    validate_certs: no
  register: get_job_templates
  loop: "{{ job_template_search }}"

这将搜索作业模板并返回以下输出 - 我删除了一堆不需要进行故障排除的输出;

"get_job_templates": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "_ansible_ignore_errors": null,
                "_ansible_item_label": {
                    "name": "example_template"
                },
                "_ansible_item_result": true,
                "_ansible_no_log": false,
                "_ansible_parsed": true,
                "allow": "GET, POST, HEAD, OPTIONS",
                "cache_control": "no-cache, no-store, must-revalidate",
                "changed": false,
                "connection": "close",
                "content_language": "en",
                "content_length": "3264",
                "content_type": "application/json",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "headers": {
                            "Authorization": "Basic "
                        },
                        "status_code": [
                            200
                        ],
                        "timeout": 30,
                        "unsafe_writes": null,
                        "url": "",
                        "url_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                        "url_username": "admin",
                        "use_proxy": true,
                        "user": "admin",
                        "validate_certs": false
                    }
                },
                "item": {
                    "name": "example_template"
                },
                "json": {
                    "count": 1,
                    "next": null,
                    "previous": null,
                    "results": [
                        {
                            "become_enabled": false,
                            "created": "2019-06-03T13:08:54.586346Z",
                            "credential": null,
                            "custom_virtualenv": null,
                            "description": "",
                            "diff_mode": false,
                            "extra_vars": "",
                            "force_handlers": false,
                            "forks": 0,
                            "host_config_key": "",
                            "id": 10,
                            "inventory": 88,
                            "name": "example_template",
                        }
                    ]
                },
            }
        ]
    }
}

我尝试使用几种不同的方法从结果中提取名称和 ID,所有这些方法都与此类似。

- set_fact:
    job_template_ids: "{{ job_template_ids | default({}) | combine( { item.name: item.id } ) }}"
  loop: "{{ get_job_templates.results.json }}"

除此之外,我尝试使用此处提供的解决方案映射属性但没有成功:Ansible loop over JSON output from URI Call

我相信我缺少关于 Ansible 如何处理像这样定义的注册变量的一些基本知识。令人沮丧的是,如果我只是对所有作业模板、用户、组织等执行 GET,则此代码对循环项 ( get_job_templates.json.results ) 稍作更改即可生成 name:id 键/值对,但布局在搜索特定的模板列表(可能还有其他对象)时,注册的变量略有不同。干杯!

编辑:发布此内容后,我尝试了其他适用于单个工作模板搜索的方法,但由于某种原因不能搜索多个。

此代码返回预期的输出,然后可以在以后的代码中使用将返回模板 ID 的模板名称调用作业模板。

- set_fact:
    job_template_ids: "{{ get_job_templates.results | map(attribute='json') | list | join }}"

- set_fact:
    job_template_ids: "{{ job_template_ids | default({}) | combine( { item.name: item.id } ) }}"
  loop: "{{ job_template_ids.results }}"

如果我在初始任务中添加要搜索的模板列表,它将停止工作,在上述代码中的第二个 set_fact 设置 fact 时返回以下错误。

fatal: [localhost]: FAILED! => {"msg": "'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'results'"}

虽然我想进步就是进步!

标签: ansibleansible-tower

解决方案


下面的任务

- set_fact:
    job_template_ids: "{{ dict(
      get_job_templates.results|json_query('[].json.results[].[name,id]')) }}"
- debug:
    var: job_template_ids

给:

"job_template_ids": {
    "example_template": 10
}

推荐阅读