Ansible acessing vars提示值与dict中的多个值进行检查



我有一个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

我有一个剧本,如果是foobarbaz,它会提示用户查看我正在获取的数据类型。

我正在创建一个角色来检查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"

相关内容

最新更新