[英]How to split a string into a list with Ansible/Jinja2?
我有以下变量:
domain_names:
- app1.example.com
- app2.example.com
customers:
- name: customer1
- name: customer2
我正在尝试生成以下域名列表:
- customer1.app1.example.com
- customer2.app1.example.com
- customer1.app2.example.com
- customer2.app2.example.com
通过使用以下 Ansible/Jinja2 代码:
- name: check which certificates exist
stat:
path: '/etc/nginx/{{item}}.crt'
register: cert_file
loop: '{% for d in domain_names %}{{ d }} {% for customer in customers %}{{ customer.name }}.{{ d }} {% endfor %}{% endfor %}'
但是,我收到以下错误:
failed | msg: Invalid data passed to 'loop', it requires a list, got this instead: customer1.app1.example.com customer2.app1.example.com customer1.app2.example.com customer2.app2.example.com. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup.
我怎样才能解决这个问题?
只需使用正确的工具:)。 在这种情况下,您的朋友是:
map
过滤器从您的customers
变量中提取name
属性作为列表product
过滤器混淆你的两个列表例如test.yml
剧本:
---
- name: product and map filters demo
hosts: localhost
gather_facts: false
vars:
domain_names:
- app1.example.com
- app2.example.com
customers:
- name: customer1
- name: customer2
tasks:
- name: Demonstrate product and map filters use
debug:
msg: "{{ item.0 }}.{{ item.1 }}"
loop: "{{ customers | map(attribute='name') | product(domain_names) | list }}"
这使:
$ ansible-playbook test.yml
PLAY [product and map filters demo] *******************************************************************************************************************************************************************************
TASK [Demonstrate product and map filters use] ********************************************************************************************************************************************************************
ok: [localhost] => (item=['customer1', 'app1.example.com']) => {
"msg": "customer1.app1.example.com"
}
ok: [localhost] => (item=['customer1', 'app2.example.com']) => {
"msg": "customer1.app2.example.com"
}
ok: [localhost] => (item=['customer2', 'app1.example.com']) => {
"msg": "customer2.app1.example.com"
}
ok: [localhost] => (item=['customer2', 'app2.example.com']) => {
"msg": "customer2.app2.example.com"
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
应用于您的任务,这给出:
- name: Check which certificates exist
stat:
path: '/etc/nginx/{{ item.0 }}.{{ item.1 }}.crt'
register: cert_file
loop: "{{ customers | map(attribute='name') | product(domain_names) | list }}"
如果您真的想重用该列表,您可以将其构建到另一个 var 中。 一种简单的理解方法是在set_fact
任务中构建它,例如
- name: Create my application names list
vars:
current_name: "{{ item.0 }}.{{ item.1 }}"
set_fact:
application_names_list: "{{ application_names_list | default([]) + [current_name] }}"
loop: "{{ customers | map(attribute='name') | product(domain_names) | list }}"
- name: Check which certificates exist
stat:
path: '/etc/nginx/{{ item }}.crt'
register: cert_file
loop: "{{ application_names_list }}"
但是您也可以使用更复杂的表达式在您的变量中“静态地”声明它(请参阅map
过滤器可能性和join
过滤器)
---
- name: product and map filters demo
hosts: localhost
gather_facts: false
vars:
domain_names:
- app1.example.com
- app2.example.com
customers:
- name: customer1
- name: customer2
application_names_list: "{{ customers | map(attribute='name') | product(domain_names) | map('join', '.') | list }}"
tasks:
- name: Demonstrate product and map filters use
debug:
var: application_names_list
=>
PLAY [product and map filters demo] ****************************************************************************************************************************************************************************************************
TASK [Demonstrate product and map filters use] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
"all_domains": [
"customer1.app1.example.com",
"customer1.app2.example.com",
"customer2.app1.example.com",
"customer2.app2.example.com"
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
这很有帮助,谢谢,但它没有回答我正在寻找的内容。
我将如何提取以下示例的第一个和第二个 IP 地址。 我正在尝试使用拆分来执行此操作,但我收到一条错误消息,建议使用 q/query 而不是查找。 我们也可以使用提取物吗? 如果 var 是一个列表,则此示例可能有效,但我不确定如何将字符串转换为列表。 这是剧本:
这是我在 Python 中所做的并且效果很好,但我正在尝试在 ansible 中做到这一点。
output = "ntp server 192.168.1.2 prefer use-vrf management ntp server 192.168.1.3 use-vrf management" output 'ntp server 192.168.1.2 prefer use-vrf management ntp server 192.168.1.3 use-vrf management' output = output.split () output ['ntp', 'server', '192.168.1.2', 'prefer', 'use-vrf', 'management', 'ntp', 'server', '192.168.1.3', 'use-vrf ', '管理'] 输出[2] '192.168.1.2' 输出[8] '192.168.1.3'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.