Is there a way in Ansible to replace a dictionary value based on k:v lookup to another dictionary?

南楼画角 提交于 2021-01-28 21:02:38

问题


I have k:v dictionary of hostname: IP that I want to use in a lookup from another dictionary to replace entries matching key from 1st dictionary and replacing it with the corresponding value in 2nd dictionary;

1st:

"nb_console_ip": {
    "office-con01": "10.20.30.100",

2nd:

"nb_console_port": [
        {
            "console": "office-con01", 
            "hostname": "office-core01", 
            "port": "con1"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-core02", 
            "port": "con2"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-fw01", 
            "port": "con5"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-fw02", 
            "port": "con6"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-vpn01", 
            "port": "con3"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-vpn02", 
            "port": "con4"
        }
    ]

Essentially Im trying to set_fact for 2nd dict with a find and replace of office-con01 with 10.20.30.100 but for a list of 30+ hosts. Reason being I then have a jinja template that will use the 3 values of console_ip, hostname & port. I was thinking maybe within there are better suited filters for lookup, find, replace etc. Both sets of data are results of json_query on return from an API call.


回答1:


It's possible to loop include_tasks and replace k:v in each iteration. For example, create a file with the task that replaces outer_item.key: outer_item.value submitted from the external loop

shell> cat test-task.yml
- set_fact:
    nb_console_port: "{{ nb_console_port|difference([item]) +
                         [dict(my_keys|zip(my_values2))] }}"
  vars:
    my_keys: "{{ item.keys()|list }}"
    my_values: "{{ item.values()|list }}"
    my_values2: "{{ my_values|
                   map('regex_replace', outer_item.key, outer_item.value)|
                   list }}"
  loop: "{{ nb_console_port }}"

Then the playbook below does the job. The variable nb_console_port is stored in the file test-data.yml

shell> cat test.yml
- hosts: localhost

  vars:

    nb_console_ip:
      office-con01: "10.20.30.100"
      office-con02: "10.20.30.101"
      office-con03: "10.20.30.102"

  tasks:

    - include_vars: test-data.yml

    - include_tasks: test-task.yml
      loop: "{{ nb_console_ip|dict2items }}"
      loop_control:
        loop_var: outer_item

    - debug:
        var: nb_console_port


来源:https://stackoverflow.com/questions/60568260/is-there-a-way-in-ansible-to-replace-a-dictionary-value-based-on-kv-lookup-to-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!