我有一个vars数据类型文件:
foo:
foo_root_path: faaa
foo_dest_path: baa
bar:
bar_root_path: xyz
bar_dest_path: wxy
baz:
baz_root_path: abc
baz_dest_path: def
我有一个剧本,如果是foo
、bar
或baz
,它会提示用户查看我正在获取的数据类型。
我正在创建一个角色来检查vars prompt == foo
是否访问foo
中的值,并使用它们执行复制命令。
我是Ansible的新手,正在努力理解
- https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#accessing-复杂变量数据和
- https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html
我现在拥有的是,对于每个when条件,我都在重复我的命令,但我想使用循环和条件:
role:
when: "'foo' == {{ data_type }}"
- name: move foo data from source to destination
copy:
src: '{{ foo_root_path }}/{{ name }}'
dest: '{{foo_destination_path}}'
owner: foo
group: foo
mode: '0644'
when: "'bar' == {{ type }}"
- name: move bar
copy:
src: '{{ bar_root_path }}/{{ name }}'
dest: '{{bar_destination_path}}'
owner: bar
group: bar
mode: '0644'
when: "'baz' == {{ type }}"
- name: move baz
copy:
src: '{{ baz_root_path }}/{{ name }}'
dest: '{{baz_destination_path}}'
owner: baz
group: baz
mode: '0000'
我想要实现的是使用条件语句来找出vars提示符是什么,然后访问vars部分,在替换vars文件中的params而不是三个命令后执行复制命令。
您可以使用vars
查找来实现这样的任务
请注意,该主机可访问的所有变量都可以通过该查找访问,可能有来自播放变量、任务变量、库存变量或通过var_files
导入的变量,语法保持不变。
这使您能够根据变量查找变量,例如:
lookup('vars', type)
会给你字典吗
foo_root_path: faaa
foo_dest_path: baa
当CCD_ 8为CCD_。
由于您的类型也是字典键的一部分,因此您还需要使用波浪形符号~
,这是Jinja:中的串联运算符
"{{ type ~ '_root_path' }}"
会给你字符串吗
foo_root_path
当CCD_ 11为CCD_。
因此,根据战术手册:
- hosts: all
gather_facts: no
vars:
foo:
foo_root_path: faaa
foo_dest_path: baa
bar:
bar_root_path: xyz
bar_dest_path: wxy
baz:
baz_root_path: abc
baz_dest_path: def
vars_prompt:
- name: type
prompt: "What variable type do you want to use?"
private: no
pre_tasks:
- assert:
that: lookup('vars', type, default='') | length
tasks:
- debug:
msg:
root_path: "{{ lookup('vars', type)[type ~ '_root_path'] }}"
dest_path: "{{ lookup('vars', type)[type ~ '_dest_path'] }}"
以下是它的一些运行:
What variable type do you want to use?: foo PLAY [all] ******************************************************************************************************* TASK [assert] **************************************************************************************************** ok: [localhost] => { "changed": false, "msg": "All assertions passed" } TASK [debug] ***************************************************************************************************** ok: [localhost] => { "msg": { "dest_path": "baa", "root_path": "faaa" } } PLAY RECAP ******************************************************************************************************* localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
What variable type do you want to use?: bar PLAY [all] ******************************************************************************************************* TASK [assert] **************************************************************************************************** ok: [localhost] => { "changed": false, "msg": "All assertions passed" } TASK [debug] ***************************************************************************************************** ok: [localhost] => { "msg": { "dest_path": "wxy", "root_path": "xyz" } } PLAY RECAP ******************************************************************************************************* localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- 由于
assert
模块被定义为pre_tasks
,如果没有定义提示的变量,这将使剧本正常失败
如果变量未定义,则需要使用default=''
,否则,vars
查找将出错,如文档中所示
然后,当默认值为空字符串时,通过Jinja过滤器测试其length
,结果将为false
,如果该字符串恰好为空,则使length
返回0
,否则,如果它是字典,则length
将为值> 0
,因此,结果为true
。What variable type do you want to use?: evil PLAY [all] ******************************************************************************************************* TASK [assert] **************************************************************************************************** fatal: [localhost]: FAILED! => { "assertion": "lookup('vars', type, default='') | length", "changed": false, "evaluated_to": false, "msg": "Assertion failed" } PLAY RECAP ******************************************************************************************************* localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
因此,根据您的情况调整所有这些会产生以下剧本:
- hosts: all
gather_facts: no
vars:
name: file.ext
foo:
foo_root_path: faaa
foo_dest_path: baa
bar:
bar_root_path: xyz
bar_dest_path: wxy
baz:
baz_root_path: abc
baz_dest_path: def
vars_prompt:
- name: type
prompt: "What variable type do you want to use?"
private: no
pre_tasks:
- assert:
that: lookup('vars', type, default='') | length
tasks:
- name: "Move {{ type }} data from source to destination"
copy:
src: "{{ lookup('vars', type)[type ~ '_root_path'] }}/{{ name }}"
dest: "{{ lookup('vars', type)[type ~ '_dest_path'] }}"
owner: "{{ type }}"
group: "{{ type }}"
mode: "0644"