Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

jinja2 - Need help using Jinja Templates with Ansible

Is there a way to add no commands in templates based on difference and not hardcoding any variable to be removed in a separate file? For example:

Ansible task for difference after comparing the running-config with a config in a file:

- name: Capture the Existing Config
  set_fact:
    existing_config: "{{ post_output['stdout'][0] | regex_findall('interface \S+|ip dhcp relay address \S+') }}"

- name: View the Existing Config
  debug:
    var: existing_config

- name: Required Config Based on Vars
  set_fact:
    required_config: "{{ lookup('file', './Config/{{ inventory_hostname }}.cfg') | regex_findall('interface \S+|ip dhcp relay address \S+') }}"

- name: View Required Config
  debug:
    var: required_config

- name: Compare Existing and Required to Remove Unwanted Config
  set_fact:
    config_to_remove: "{{ existing_config | difference(required_config) }}"

- name: View the Difference Against Existing and Required Configs
  debug:
    var: config_to_remove
TASK [Capture the Existing Config] ***********************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View the Existing Config] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "existing_config": [
        "interface Vlan1",
        "ip dhcp relay address 10.1.1.2",
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
        "interface Ethernet1/49",
        "ip dhcp relay address 10.1.1.2",
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
        "interface Ethernet1/50",
        "ip dhcp relay address 10.1.1.2"
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
    ]
}

TASK [Desired Config Based on Vars] ************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View Required Config] *******************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "reuired_config": [
        "interface Vlan1",
        "ip dhcp relay address 10.1.1.2",
        "interface Ethernet1/49",
        "ip dhcp relay address 10.1.1.2",
        "interface Ethernet1/50",
        "ip dhcp relay address 10.1.1.2"
    ]
}

TASK [Compare Existing and Required Configs to Remove Unwanted Config] ***************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View the Difference Against Existing and Required Configs] *************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "config_to_remove": [
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
    ]
}

j2 file to build config:

{% for ip in config %}
interface Vlan1
  ip dhcp relay address {{ ip }} 
interface Ethernet1/49
  ip dhcp relay address {{ ip }} 
interface Ethernet1/50
  ip dhcp relay address {{ ip }} 
{% endfor %}
vars:
  config:
    10.1.1.2

Note: No commands are coming from a list based on the difference

Can I use an if statement to use no command based on items from a list within the playbook?

{% if <ip is not in vars> %}
  no ip dhcp relay address <ip to be removed>
{% endif %}

So the final config file will look similar to the following which will then be pushed to the devices is separate task:

interface Vlan1
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/49
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/50
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For this kind of task, and since Ansible/Jinja is Python, you can even use the wonderful for ... if construct.

Given the playbook:

- hosts: all
  gather_facts: no

  tasks:
    - debug:
        msg: |-
          #jinja2: trim_blocks:False
          {% for ip in config %}
          interface Vlan1
            ip dhcp relay address {{ ip }}
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %}
          interface Ethernet1/49
            ip dhcp relay address {{ ip }}
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %} 
          interface Ethernet1/50
            ip dhcp relay address {{ ip }} 
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %}
          {% endfor %}
      vars:
        guess_on_existing_config:
          - interface Vlan1
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
          - interface Ethernet1/49
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
          - interface Ethernet1/50
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
        guess_on_required_config:
          - interface Vlan1
          - ip dhcp relay address 10.1.1.2
          - interface Ethernet1/49
          - ip dhcp relay address 10.1.1.2
          - interface Ethernet1/50
          - ip dhcp relay address 10.1.1.2
        config:
          - 10.1.1.2
        config_to_remove: "{{ guess_on_existing_config | difference(guess_on_required_config) }}"

This yields:

$ ansible-playbook play.yml -i inventory.yml | sed 's/\n/
/g'

PLAY [all] *********************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "
interface Vlan1
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99
interface Ethernet1/49
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/50
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99
"
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...