如何解决Ansible - 循环和 json_query 的问题
问题
我需要从 GET 中获取 ID,因为在 PUT 任务的 URL 中需要它来编辑特定的“输入”条目。我正在使用 Ansible URI 与 REST API 通信来管理这个。
剧本
*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
---
- name: Configure system
hosts: graylog
connection: local
gather_facts: no
roles:
- graylog/inputs
roles/graylog/inputs/tasks/main.yml
---
- include_tasks: get_inputs.yml
- include_tasks: put_inputs.yml
roles/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
get 中注册的 var 如下
{
"json": {
"inputs": [
{
"attributes": {
"allow_override_date": "False","bind_address": "0.0.0.0","expand_structured_data": "False","force_rdns": "False","number_worker_threads": 8,"override_source": "","port": 5999,"recv_buffer_size": "","store_full_message": "True"
},"content_pack": null,"created_at": "2021-07-30T15:21:47.590Z","creator_user_id": "triple_admin","global": false,"id": "6104170beca15547502665d6","name": "Syslog UDP","node": "ba52ad48-0b13-419d-b957-d47d8911b413","static_fields": {},"title": "test_input_api","type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput"
},
roles/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
"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"
运行结果
循环 1 - 这需要与标题匹配,因此获取 id "61015085eca1554750236084"
"title": "test_input_api","url": "http://192.168.21.82:9000/api/system/inputs/610282d0eca155475024ac91",
循环 2
"title": "test_input_api_2",
欢迎所有帮助!
解决方法
- (不相关)您不需要
json_decode
结果get_graylog_inputs.content
。如果另一端的服务器发送正确的Content-type: application/json
标头,您应该有一个get_graylog_inputs.json
条目,其中包含已解码的 json 结果。 - 您不需要循环两次。删除第一个文件中的
set_fact
循环(无论如何都不正确),并直接在第二个循环中使用寄存器中的值。 - 您没有显示输入数据的任何示例,因此我必须从您的 jmespath 表达式中猜测一下……但您基本上根本不需要
json_query
并且可以坚持使用通用核心 ansible 过滤器.
这是我清理第一个文件后在第二个文件中看到的解决方案:
---
- name: "API PUT System Inputs"
vars:
get_input_id: "{{ get_graylog_inputs.json.inputs | selectattr('title','==',input.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
您可能需要调试和调整表达式以获取输入 id,因为我无法针对示例数据结构自行完成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。