如何在ansible中一起使用多个with_items
how to use mutiple with_items together in ansible
这里我附上了Json的输入格式,它由两个数组,对象和目标组成,我尝试使用Ansible with_item模块将对象循环到Uri模块中。
此概念适用于单个数组,但当我尝试将两个数组项都调用到 uri 时遇到问题。
有什么办法可以同时使用两个项目数组
Json 输入
{
"objects": [
{
"item": {
"action": "deny",
"srcaddr": "IP_100.1.2.3",
"src_ipv4": "ipmask",
"src_ipv4addr": "100.1.2.3/32",
"dstaddr": "IP_100.4.5.6",
"dst_ipv4addr": "100.4.5.6/32",
"dst_ipv4": "ipmask",
"port": "65511",
"protocol": "tcp"
}
},
{
"item": {
"action": "deny",
"srcaddr": "IP_200.1.2.3",
"src_ipv4": "ipmask",
"src_ipv4addr": "200.1.2.3/32",
"dstaddr": "IP_100.4.5.6",
"dst_ipv4addr": "100.4.5.6/32",
"dst_ipv4": "ipmask",
"port": "65511",
"protocol": "tcp"
}
}
],
"targets": [
{
"item": {
"domain": "dom-cn-1",
"fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064",
"mgmt_password": "admin123",
"mgmt_server": "192.168.10.20",
"target_fw": "dev-cn-c1"
}
},
{
"item": {
"domain": "dom-cn-2",
"fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064",
"mgmt_password": "admin123",
"mgmt_server": "192.168.10.20",
"target_fw": "dev-cn-c3"
}
}
]
}
基于uri模块的任务
- name: upating the task status
uri:
url: http://192.168.30.20/api/v2/job_templates/7/launch/
method: POST
body: '{ "extra_vars": { "action": "{{ item.item.action }}", "srcaddr": "{{ item.item.srcaddr }}", "src_ipv4": "{{ item.item.src_ipv4 }}", "mgmt_password": "{{ item.item.mgmt_password }}", "mgmt_server": "{{ item.item.mgmt_server }}", "targets": [ "{{ item.item.target_fw }}" ]} }'
status_code: 201
body_format: json
force_basic_auth: yes
validate_certs: no
user: "admin"
password: "admin123"
headers:
Accept: "application/json"
Content-Type: "application/json"
with_items: "{{ tmpdata.objects }}"
预期响应
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
您要实现的只是两个列表之间的乘积。非常幸运的是,ansible 有一个过滤器专门用于那个叫做.... product
.
在我下面的示例中,我还清理了一些原始数据,以从原始数据中删除 item
条目,这些条目使结果不太清晰。我使用 map
过滤器来提取我们需要的属性。
以下剧本:
- name: product and map(attribute=) demo
hosts: localhost
gather_facts: false
vars:
# Your orig data on a single line for legibility
tmpdata: {"objects": [{"item": {"action": "deny", "srcaddr": "IP_100.1.2.3", "src_ipv4": "ipmask", "src_ipv4addr": "100.1.2.3/32", "dstaddr": "IP_100.4.5.6", "dst_ipv4addr": "100.4.5.6/32", "dst_ipv4": "ipmask", "port": "65511", "protocol": "tcp"}}, {"item": {"action": "deny", "srcaddr": "IP_200.1.2.3", "src_ipv4": "ipmask", "src_ipv4addr": "200.1.2.3/32", "dstaddr": "IP_100.4.5.6", "dst_ipv4addr": "100.4.5.6/32", "dst_ipv4": "ipmask", "port": "65511", "protocol": "tcp"}}], "targets": [{"item": {"domain": "dom-cn-1", "fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064", "mgmt_password": "admin123", "mgmt_server": "192.168.10.20", "target_fw": "dev-cn-c1"}}, {"item": {"domain": "dom-cn-2", "fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064", "mgmt_password": "admin123", "mgmt_server": "192.168.10.20", "target_fw": "dev-cn-c3"}}]}
tasks:
- name: This is our final objects list for demo
debug:
msg: "{{ tmpdata.objects | map(attribute='item') | list }}"
verbosity: 1
- name: This is our final targets list for demo
debug:
msg: "{{ tmpdata.targets | map(attribute='item') | list }}"
verbosity: 1
- name: This is what the product list will look like
debug:
msg: >-
{{
tmpdata.objects | map(attribute='item')
| product(tmpdata.targets | map(attribute='item'))
| list
}}
verbosity: 1
- name: And this how we can loop on the result
vars:
msg_content:
- action is {{ item.0.action }}
- srcaddr is {{ item.0.srcaddr }}
- src_ipv4 is {{ item.0.src_ipv4 }}
- mgmt_password is {{ item.1.mgmt_password }}
- mgmt_server is {{ item.1.mgmt_server }}
- target_fw is {{ item.1.target_fw }}
debug:
msg: "{{ msg_content }}"
# Loop is equivalent to with_items here.
# see https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
loop: >-
{{
tmpdata.objects | map(attribute='item')
| product(tmpdata.targets | map(attribute='item'))
| list
}}
给(运行 自己用 -v
获取中间调试信息)
$ ansible-playbook playbook.yml
PLAY [product and map(attribute=) demo] ************************************************************************************************************************************************************************************************
TASK [This is our final objects list for demo] *****************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [This is our final targets list for demo] *****************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [This is what the product list will look like] ************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [And this how we can loop on the result] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_100.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '100.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-1', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c1'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_100.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '100.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-2', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c3'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_200.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '200.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-1', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c1'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_200.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '200.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-2', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c3'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
这里我附上了Json的输入格式,它由两个数组,对象和目标组成,我尝试使用Ansible with_item模块将对象循环到Uri模块中。
此概念适用于单个数组,但当我尝试将两个数组项都调用到 uri 时遇到问题。 有什么办法可以同时使用两个项目数组
Json 输入
{
"objects": [
{
"item": {
"action": "deny",
"srcaddr": "IP_100.1.2.3",
"src_ipv4": "ipmask",
"src_ipv4addr": "100.1.2.3/32",
"dstaddr": "IP_100.4.5.6",
"dst_ipv4addr": "100.4.5.6/32",
"dst_ipv4": "ipmask",
"port": "65511",
"protocol": "tcp"
}
},
{
"item": {
"action": "deny",
"srcaddr": "IP_200.1.2.3",
"src_ipv4": "ipmask",
"src_ipv4addr": "200.1.2.3/32",
"dstaddr": "IP_100.4.5.6",
"dst_ipv4addr": "100.4.5.6/32",
"dst_ipv4": "ipmask",
"port": "65511",
"protocol": "tcp"
}
}
],
"targets": [
{
"item": {
"domain": "dom-cn-1",
"fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064",
"mgmt_password": "admin123",
"mgmt_server": "192.168.10.20",
"target_fw": "dev-cn-c1"
}
},
{
"item": {
"domain": "dom-cn-2",
"fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064",
"mgmt_password": "admin123",
"mgmt_server": "192.168.10.20",
"target_fw": "dev-cn-c3"
}
}
]
}
基于uri模块的任务
- name: upating the task status
uri:
url: http://192.168.30.20/api/v2/job_templates/7/launch/
method: POST
body: '{ "extra_vars": { "action": "{{ item.item.action }}", "srcaddr": "{{ item.item.srcaddr }}", "src_ipv4": "{{ item.item.src_ipv4 }}", "mgmt_password": "{{ item.item.mgmt_password }}", "mgmt_server": "{{ item.item.mgmt_server }}", "targets": [ "{{ item.item.target_fw }}" ]} }'
status_code: 201
body_format: json
force_basic_auth: yes
validate_certs: no
user: "admin"
password: "admin123"
headers:
Accept: "application/json"
Content-Type: "application/json"
with_items: "{{ tmpdata.objects }}"
预期响应
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
您要实现的只是两个列表之间的乘积。非常幸运的是,ansible 有一个过滤器专门用于那个叫做.... product
.
在我下面的示例中,我还清理了一些原始数据,以从原始数据中删除 item
条目,这些条目使结果不太清晰。我使用 map
过滤器来提取我们需要的属性。
以下剧本:
- name: product and map(attribute=) demo
hosts: localhost
gather_facts: false
vars:
# Your orig data on a single line for legibility
tmpdata: {"objects": [{"item": {"action": "deny", "srcaddr": "IP_100.1.2.3", "src_ipv4": "ipmask", "src_ipv4addr": "100.1.2.3/32", "dstaddr": "IP_100.4.5.6", "dst_ipv4addr": "100.4.5.6/32", "dst_ipv4": "ipmask", "port": "65511", "protocol": "tcp"}}, {"item": {"action": "deny", "srcaddr": "IP_200.1.2.3", "src_ipv4": "ipmask", "src_ipv4addr": "200.1.2.3/32", "dstaddr": "IP_100.4.5.6", "dst_ipv4addr": "100.4.5.6/32", "dst_ipv4": "ipmask", "port": "65511", "protocol": "tcp"}}], "targets": [{"item": {"domain": "dom-cn-1", "fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064", "mgmt_password": "admin123", "mgmt_server": "192.168.10.20", "target_fw": "dev-cn-c1"}}, {"item": {"domain": "dom-cn-2", "fingerprint": "9125544D272B5AD28F3E9AB7BC8AA3F276E45064", "mgmt_password": "admin123", "mgmt_server": "192.168.10.20", "target_fw": "dev-cn-c3"}}]}
tasks:
- name: This is our final objects list for demo
debug:
msg: "{{ tmpdata.objects | map(attribute='item') | list }}"
verbosity: 1
- name: This is our final targets list for demo
debug:
msg: "{{ tmpdata.targets | map(attribute='item') | list }}"
verbosity: 1
- name: This is what the product list will look like
debug:
msg: >-
{{
tmpdata.objects | map(attribute='item')
| product(tmpdata.targets | map(attribute='item'))
| list
}}
verbosity: 1
- name: And this how we can loop on the result
vars:
msg_content:
- action is {{ item.0.action }}
- srcaddr is {{ item.0.srcaddr }}
- src_ipv4 is {{ item.0.src_ipv4 }}
- mgmt_password is {{ item.1.mgmt_password }}
- mgmt_server is {{ item.1.mgmt_server }}
- target_fw is {{ item.1.target_fw }}
debug:
msg: "{{ msg_content }}"
# Loop is equivalent to with_items here.
# see https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
loop: >-
{{
tmpdata.objects | map(attribute='item')
| product(tmpdata.targets | map(attribute='item'))
| list
}}
给(运行 自己用 -v
获取中间调试信息)
$ ansible-playbook playbook.yml
PLAY [product and map(attribute=) demo] ************************************************************************************************************************************************************************************************
TASK [This is our final objects list for demo] *****************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [This is our final targets list for demo] *****************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [This is what the product list will look like] ************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [And this how we can loop on the result] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_100.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '100.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-1', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c1'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_100.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '100.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-2', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c3'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_100.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_200.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '200.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-1', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c1'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c1"
]
}
ok: [localhost] => (item=[{'action': 'deny', 'srcaddr': 'IP_200.1.2.3', 'src_ipv4': 'ipmask', 'src_ipv4addr': '200.1.2.3/32', 'dstaddr': 'IP_100.4.5.6', 'dst_ipv4addr': '100.4.5.6/32', 'dst_ipv4': 'ipmask', 'port': '65511', 'protocol': 'tcp'}, {'domain': 'dom-cn-2', 'fingerprint': '9125544D272B5AD28F3E9AB7BC8AA3F276E45064', 'mgmt_password': 'admin123', 'mgmt_server': '192.168.10.20', 'target_fw': 'dev-cn-c3'}]) => {
"msg": [
"action is deny",
"srcaddr is IP_200.1.2.3",
"src_ipv4 is ipmask",
"mgmt_password is admin123",
"mgmt_server is 192.168.10.20",
"target_fw is dev-cn-c3"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0