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

Categories

I'm pulling the facts from Juniper devices and pushing that information to NetBox.

Below is my playbook, basically set_fact gives me the last result and then the netbox play sends the same result to all my interfaces, and that's not what I want.

- name: SETTING INT TYPE VIRTUAL
  set_fact:
    interfacetype: "Virtual"
  loop: "{{ansible_network_resources.interfaces}}"
  when: item.name == "irb" or 
        item.name == "lo0" 
      
- name: SETTING INT TYPE 1GE
  set_fact:
    interfacetype: "1000BASE-T (1GE)"
  loop: "{{ansible_network_resources.interfaces}}"
  when: item.name | regex_search('(ge-)')
  register: inter1

- name: SETTING INT TYPE 40GE
  set_fact:
    interfacetype: "QSFP+ (40GE)"
  loop: "{{ansible_network_resources.interfaces}}"
  when: item.name | regex_search('(et-)') and
        ansible_net_model | regex_search('^ex[2-4][2346]00|qfx5100$')

- name: CREATE DEVICE INTERFACES
  netbox_device_interface:
    netbox_url: https://netbox.something.org
    netbox_token: 99999999999999999999999999999999999
    data:
      device: "{{ ansible_net_hostname }}"
      name: "{{ item.name }}"
      description: "{{ item.description|default('') }}"
      enabled: "{{ item.enabled }}"
      mtu: "{{ item.mtu|default('') }}"
      type: "{{ interfacetype }}"
    state: present
  loop: "{{ansible_network_resources.interfaces}}"
  delegate_to: localhost

I think the below makes more sense based on the above. I think I need to combine inside the list, on each part that has a dictionary pointing to ge- a new item that will be like intertype:"1000BASE-T (1GE)"

That way I can use that list of dictionaries on the last play.

This is what I get:

ok: [device1.something.org] => {
"ansible_network_resources.interfaces": [
    {
        "enabled": true,
        "mtu": 9216,
        "name": "ge-0/0/0"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "ge-0/0/1"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "ge-0/0/2"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "ge-0/0/3"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "ge-0/0/4"
    },
    {
        "description": "agaga2",
        "enabled": true,
        "mtu": 9216,
        "name": "et-0/1/0"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "et-0/1/1"
    },
    {
        "enabled": true,
        "mtu": 9216,
        "name": "xe-0/2/0"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "xe-0/2/1"
    },
    {
        "enabled": false,
        "mtu": 9216,
        "name": "xe-0/2/2"
    },
    {
        "description": "blabla1",
        "enabled": true,
        "mtu": 9216,
        "name": "xe-0/2/3"
    },
    {
        "enabled": true,
        "name": "irb"
    },
    {
        "enabled": true,
        "name": "lo0"
    }
]

}

Can I add inside there a new dictionary so that the result is the following:

    {
    "intertype":"Virtual"  
    "enabled": true,
        "name": "lo0"
    }
    {
    "intertype":"QSFP+ (40GE)"  
    "enabled": false,
    "mtu": 9216,
     "name": "et-0/2/2"
    },
    {
    "intertype":"1000BASE-T (1GE)"     
    "enabled": false,
        "mtu": 9216,
        "name": "ge-0/0/1"
    },
question from:https://stackoverflow.com/questions/65930814/sec-fact-gives-me-the-last-match

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.1k views
Welcome To Ask or Share your Answers For Others

1 Answer

In your code, the variable interfacetype is set in each iteration

- name: SETTING INT TYPE VIRTUAL
  set_fact:
    interfacetype: "Virtual"
  loop: "{{ansible_network_resources.interfaces}}"
  when: item.name == "irb" or 
        item.name == "lo0" 

I read the logic of this task as "If any of [irb, lo0] is in the interfaces set interfacetype to Virtual". It's more efficient to select the interfaces and intersect the lists. For example, given the data

    ansible_network_resources:
      interfaces:
        - {enabled: true, name: em1, mtu: '1476'}
        - {enabled: true, name: irb, mtu: '1514'}
        - {enabled: true, name: lo0, mtu: "Unlimited"}
    sel_intfs: [irb, lo0]

select the interfaces

    - set_fact:
        my_intfs: "{{ ansible_network_resources.interfaces|
                      map(attribute='name')|list }}"

gives

  my_intfs:
  - em1
  - irb
  - lo0

and intersect

    - set_fact:
        no_intfs: "{{ sel_intfs|intersect(my_intfs)|length }}"

gives the number of common interfaces

  no_intfs: '2'

When you put this together

    - set_fact:
        interfacetype: Virtual
      when: no_intfs|int > 0
      vars:
        my_intfs: "{{ ansible_network_resources.interfaces|
                              map(attribute='name')|list }}"
        no_intfs: "{{ sel_intfs|intersect(my_intfs)|length }}"
    - debug:
        var: interfacetype

give

  interfacetype: Virtual

In the case the intersect is an empty list, i.e. there are no common interfaces, for example, sel_intfs: [irc, lo1] the same tasks give

  interfacetype: VARIABLE IS NOT DEFINED!

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...