[英]Ansible - issue with loop and json_query's
I am using the ansible URI module to talk to a REST api.我正在使用 ansible URI 模块与 REST api 对话。 I have a task to perform a GET to get me some data that i want to use later on.
我有一项任务要执行 GET 以获取一些我稍后要使用的数据。 I want to be able to match a certain variable from the GET to create the path to do a PUT on the REST api.
我希望能够匹配来自 GET 的某个变量来创建在 REST api 上执行 PUT 的路径。 My code is as followed
我的代码如下
*host_vars/host.yml * *host_vars/host.yml *
---
inputs:
- title: "test_input_api"
type: "org.graylog2.inputs.syslog.udp.SyslogUDPInput"
global: false
configuration:
allow_override_date: false
bind_address: "0.0.0.0"
expand_structured_data: false
force_rdns: false
number_worker_threads: 8
override_source: null
port: 5999
recv_buffer_size: null
store_full_message: true
- title: "test_input_api_2"
type: "org.graylog2.inputs.syslog.udp.SyslogUDPInput"
global: false
configuration:
allow_override_date: false
bind_address: "0.0.0.0"
expand_structured_data: false
force_rdns: false
number_worker_threads: 8
override_source: null
port: 5998
recv_buffer_size: null
store_full_message: true
playbook.yml剧本.yml
---
- name: Configure system
hosts: graylog
connection: local
gather_facts: no
roles:
- graylog/inputs
roles/graylog/inputs/tasks/main.yml角色/graylog/inputs/tasks/main.yml
---
- include_tasks: get_inputs.yml
- include_tasks: put_inputs.yml
roles/graylog/inputs/tasks/get_inputs.yml角色/graylog/inputs/tasks/get_inputs.yml
---
- name: "API GET System Inputs"
uri:
url: http://{{ ansible_host }}:9000/api/system/inputs
url_username : "{{ system.users.triple_admin.api_token }}"
url_password: token
method: GET
return_content: yes
register: get_graylog_inputs
- name: Set Fact
set_fact:
get_input_id: "{{ get_graylog_inputs.content | from_json | json_query('inputs[?title == `{}`] | [0].id '.format(input.title)) }}"
loop: "{{ inputs }}"
loop_control:
loop_var: input
roles/graylog/inputs/tasks/put_inputs.yml角色/graylog/inputs/tasks/put_inputs.yml
---
- name: "API PUT System Inputs"
uri:
url: http://{{ ansible_host }}:9000/api/system/inputs/{{ get_input_id }}
url_username : "{{ system.users.triple_admin.api_token }}"
url_password: token
headers:
X-Requested-By: X-Ansible
method: PUT
body_format: json
body: "{{ lookup('template', 'templates/post_template.j2') }}"
status_code: 201
return_content: yes
loop: "{{ inputs }}"
loop_control:
loop_var: input
A double loop statement within the play剧中的双循环语句
As you can see in the get_inputs.yml I do a loop over the inputs dict in the host_vars within the set_fact task to get the ID from the REST api for each input entry that is defined in the host_vars that matches the title.正如您在get_inputs.yml 中看到的,我在 set_fact 任务中对 host_vars 中的输入dict 进行循环,以从 REST api 获取与标题匹配的host_vars中定义的每个输入条目的 ID。
The idea behind this is when i want to change something about the input entry i can do a PUT that builds a path within the task put_inputs.yml the variable URL to the input with the id that is gathered with the GET and set to fact by the get_facts task and then play the PUT task to the rest api and adjust some parameter.这背后的想法是,当我想更改有关输入条目的某些内容时,我可以执行 PUT 在任务put_inputs.yml中构建路径的变量URL到输入的变量URL使用 GET 收集并设置为事实get_facts 任务,然后将 PUT 任务播放到其余 api 并调整一些参数。
But i also need do a loop over the same inputs dict in the host_vars within the put_inputs.yml because if there are changes to multiple entries i want to loop the PUT.但是我还需要在 put_inputs.yml 内的host_vars 中对相同的输入字典进行循环,因为如果对多个条目进行了更改,我想循环 PUT。
The issue is that the get_facts get's both the id values as show below only the last one is being registered as the fact because it's a loop and they get the same name.问题是 get_facts 获得了两个 id 值,如下所示,只有最后一个被注册为事实,因为它是一个循环,并且它们具有相同的名称。
"ansible_facts": {
"get_input_id": "61015085eca1554750236084",
"get_input_titles": "test_input_api"
},
"ansible_facts": {
"get_input_id": "610282d0eca155475024ac91",
"get_input_titles": "test_input_api_2"
So when the put_inputs.yml task is played ( after the get_inputs.yml ) I end up with the following response from the play which in short is that both times te task is being played ( as per loop ) i get the same get_input_id value.因此,当播放put_inputs.yml任务时(在get_inputs.yml 之后)我最终得到了来自播放的以下响应,简而言之,两次 te 任务正在播放(根据循环)我得到相同的get_input_id值。
loop 1 - this needs to be matched to the title and therefor get id "61015085eca1554750236084"循环 1 - 这需要与标题匹配,因此获取 id "61015085eca1554750236084"
"title": "test_input_api",
"url": "http://192.168.21.82:9000/api/system/inputs/610282d0eca155475024ac91",
loop 2循环 2
"title": "test_input_api_2",
"url": "http://192.168.21.82:9000/api/system/inputs/610282d0eca155475024ac91",
I need to get the ID from the GET because it's needed in the URL in the PUT task to edit a specific "input" entry.我需要从 GET 获取 ID,因为在 PUT 任务的 URL 中需要它来编辑特定的“输入”条目。 But because i need to match the ID to the Title i need to do a loop but this as I said previously results in only getting one ID value as a fact which is being used in the PUT loop for all items in the inputs dict this is not what i need because i need to be able to edit every entry separately based on ID.
但是因为我需要将 ID 与 Title 匹配,所以我需要做一个循环,但是正如我之前所说的,这导致只获得一个 ID 值作为一个事实,该值在 PUT 循环中用于输入字典中的所有项目,这是不是我需要的,因为我需要能够根据 ID 分别编辑每个条目。
All help is welcome !欢迎所有帮助!
json_decode
the result get_graylog_inputs.content
. json_decode
结果get_graylog_inputs.content
。 If the server on the over side sends the correct Content-type: application/json
header, you should have a get_graylog_inputs.json
entry containing the already decoded json result.Content-type: application/json
标头,您应该有一个包含已解码 json 结果的get_graylog_inputs.json
条目。set_fact
loop (which is not correct anyway) in your first file and use the value from your register directly in the second loop.set_fact
循环(无论如何都不正确),并直接在第二个循环中使用寄存器中的值。json_query
at all and can stick to generic core ansible filters.json_query
并且可以坚持使用通用核心 ansible 过滤器。 Here is how I see the solution in the second file once you cleaned-up the first:这是清理第一个文件后我在第二个文件中看到的解决方案:
---
- name: "API PUT System Inputs"
vars:
get_input_id: "{{ get_graylog_inputs.json | selectattr('title', '==', item.title) | map(attribute='id') | first }}"
uri:
url: http://{{ ansible_host }}:9000/api/system/inputs/{{ get_input_id }}
url_username : "{{ system.users.triple_admin.api_token }}"
url_password: token
headers:
X-Requested-By: X-Ansible
method: PUT
body_format: json
body: "{{ lookup('template', 'templates/post_template.j2') }}"
status_code: 201
return_content: yes
loop: "{{ inputs }}"
loop_control:
loop_var: input
You will probably have to debug and tune the expression to get the input id as I could not do it myself against an example data structure.您可能需要调试和调整表达式以获取输入 id,因为我无法针对示例数据结构自行完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.