f5-ansible icon indicating copy to clipboard operation
f5-ansible copied to clipboard

Unable to gather facts about a single node in BigIP

Open vijayravi17 opened this issue 3 years ago • 4 comments

I am using the below code to collect facts about a singe node inside a pool on F5. We use prompt and trying to fetch result. But while we try to execute it brings all the pool name and members from the ltm-pools instead of the node that we are trying to fetch information. Any help in fixing or correcting the issue would be a great help.

Also it takes about 15 minutes for the result to display . I suppose it does because it brings all the pool member information.


  • name: Conditionally force a node offline hosts: bigip15-0.askf5team.local:bigip14-1.askf5team.local gather_facts: False vars: provider: password: "{{ bigip_password }}" server: "{{ ansible_host }}" user: "{{ bigip_username }}" validate_certs: False active_list: []

    vars_prompt:

    • name: node prompt: "What is the node address? " private: no

    tasks:

    • name: Collect bigip facts bigip_device_facts: gather_subset: - ltm-pools provider: "{{ provider }}" register: pools

    • name: Determine pools the node is in and record their active member counts set_fact: active_list: "{{ active_list + [ item[1] ] }}" when: node in item[2] loop: "{{ pools | json_query('ltm_pools[].[name, active_member_count, members[*].address]') }}"

    • name: Display active member count list debug: var=active_list

    • name: Display count with the least amount of active members debug: msg="Minimum active member count from all pools {{ active_list | min }}"

    • name: Force node offline bigip_node: state: offline name: "{{ node }}" provider: "{{ provider }}" delegate_to: localhost when: active_list | min | int > 1

vijayravi17 avatar Mar 16 '21 10:03 vijayravi17

i've tried your code: BIG-IP v14.1 Ansible Collection 1.8.1 (you need to switch from bigip_device_fact to bigip_device_info)

---

- hosts: default
  gather_facts: false
  vars: 
    provider:
      server: 192.168.143.154
      user: admin
      password: xxxxxxx
      validate_certs: no
      server_port: 443
    active_list: []

  vars_prompt:

    - name: node
      prompt: "What is the node address? "
      private: no

  tasks:

    - name: Collect bigip facts
      bigip_device_info:
        gather_subset:
          - ltm-pools
        provider: "{{ provider }}"
      register: pools
      delegate_to: localhost

    - name: Determine pools the node is in and record their active member counts
      set_fact:
        active_list: "{{ active_list + [item[1]] }}"
      when: node in item[2]
      loop: "{{ pools | json_query('ltm_pools[].[name, active_member_count, members[*].address]') }}"

    - name: Display active member count list
      debug: var=active_list

    - name: Display count with the least amount of active members
      debug: msg="Minimum active member count from all pools {{ active_list | min }}"

    - name: Force node offline
      bigip_node:
        state: offline
        name: "{{ node }}"
        provider: "{{ provider }}"
        when: active_list | min | int > 1
      delegate_to: localhost

This is the output

(Ansible) BZH $ ansible-playbook -i hosts site.yml
What is the node address? : 172.16.2.1

PLAY [default] **********************************************************************************************************************************************************************

TASK [Collect bigip facts] **********************************************************************************************************************************************************
ok: [192.168.143.154]

TASK [Determine pools the node is in and record their active member counts] *********************************************************************************************************
skipping: [192.168.143.154] => (item=['pool-https-nginx', 0, ['172.16.1.1']])
ok: [192.168.143.154] => (item=['test-pool', 2, ['1.2.3.4', '172.16.1.1', '172.16.2.1', '172.16.2.80']])
ok: [192.168.143.154] => (item=['test_ansible_issue', 2, ['172.16.1.1', '172.16.2.1']])
skipping: [192.168.143.154] => (item=['NGINXPool', 0, ['172.16.1.1']])

TASK [Display active member count list] *********************************************************************************************************************************************
ok: [192.168.143.154] => {
    "active_list": [
        2,
        2
    ]
}

TASK [Display count with the least amount of active members] ************************************************************************************************************************
ok: [192.168.143.154] => {
    "msg": "Minimum active member count from all pools 2"
}

TASK [Force node offline] ***********************************************************************************************************************************************************
changed: [192.168.143.154]

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

Here we can see that the node has been disabled as expected. I've done some more tests and if a pool contain only the node that is about to be disabled, then nothing will happen. This will help making sure that you won't bring any service down

nmenant avatar Mar 22 '21 10:03 nmenant

Thank you for your response. Let me try this today and get back to you.

vijayravi17 avatar Mar 24 '21 06:03 vijayravi17

i've tried your code: BIG-IP v14.1 Ansible Collection 1.8.1 (you need to switch from bigip_device_fact to bigip_device_info)

---

- hosts: default
  gather_facts: false
  vars: 
    provider:
      server: 192.168.143.154
      user: admin
      password: xxxxxxx
      validate_certs: no
      server_port: 443
    active_list: []

  vars_prompt:

    - name: node
      prompt: "What is the node address? "
      private: no

  tasks:

    - name: Collect bigip facts
      bigip_device_info:
        gather_subset:
          - ltm-pools
        provider: "{{ provider }}"
      register: pools
      delegate_to: localhost

    - name: Determine pools the node is in and record their active member counts
      set_fact:
        active_list: "{{ active_list + [item[1]] }}"
      when: node in item[2]
      loop: "{{ pools | json_query('ltm_pools[].[name, active_member_count, members[*].address]') }}"

    - name: Display active member count list
      debug: var=active_list

    - name: Display count with the least amount of active members
      debug: msg="Minimum active member count from all pools {{ active_list | min }}"

    - name: Force node offline
      bigip_node:
        state: offline
        name: "{{ node }}"
        provider: "{{ provider }}"
        when: active_list | min | int > 1
      delegate_to: localhost

This is the output

(Ansible) BZH $ ansible-playbook -i hosts site.yml
What is the node address? : 172.16.2.1

PLAY [default] **********************************************************************************************************************************************************************

TASK [Collect bigip facts] **********************************************************************************************************************************************************
ok: [192.168.143.154]

TASK [Determine pools the node is in and record their active member counts] *********************************************************************************************************
skipping: [192.168.143.154] => (item=['pool-https-nginx', 0, ['172.16.1.1']])
ok: [192.168.143.154] => (item=['test-pool', 2, ['1.2.3.4', '172.16.1.1', '172.16.2.1', '172.16.2.80']])
ok: [192.168.143.154] => (item=['test_ansible_issue', 2, ['172.16.1.1', '172.16.2.1']])
skipping: [192.168.143.154] => (item=['NGINXPool', 0, ['172.16.1.1']])

TASK [Display active member count list] *********************************************************************************************************************************************
ok: [192.168.143.154] => {
    "active_list": [
        2,
        2
    ]
}

TASK [Display count with the least amount of active members] ************************************************************************************************************************
ok: [192.168.143.154] => {
    "msg": "Minimum active member count from all pools 2"
}

TASK [Force node offline] ***********************************************************************************************************************************************************
changed: [192.168.143.154]

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

Here we can see that the node has been disabled as expected. I've done some more tests and if a pool contain only the node that is about to be disabled, then nothing will happen. This will help making sure that you won't bring any service down

While I try this, I am getting this below error. Please help.

['pool_analyticsuatu-inside_gpsflex_8443', 1, ['10.0.0.1']]) skipping: [localhost] => (item=['pool_analyticsuatu-inside_gpsws_8443', 0, ['10.10.20.10', '10.90.80.90']]) skipping: [localhost] => (item=['pool_aperekdev-inside_443', 0, ['10.20.30.40']]) fatal: [localhost]: FAILED! => {"msg": "The conditional check 'node in item[2]' failed. The error was: Unexpected templating type error occurred on ({% if node in item[2] %} True {% else %} False {% endif %}): argument of type 'NoneType' is not iterable\n\nThe error appears to be in '/root/serverdecom/F5Virtual.yml': line 30, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Determine pools the node is in and record their active member counts\n ^ here\n"}

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

vijayravi17 avatar Mar 26 '21 10:03 vijayravi17

Hey, As I am facing error when node checks with the member[*].address as some pools have zero members. So I have now trying to create a path to check with node and now it doesn't need to be empty. Please anyone check whether it can be run or can be fixed. Thanks in advance


- hosts: localhost
  gather_facts: false
  vars:
    provider:
      server: admin
      user: nes
      password: "********" 
      validate_certs: no
    path: []

  vars_prompt:

    - name: node
      prompt: "What is the node address? "
      private: no

  tasks:

    - name: Collect bigip facts for Pool name
      bigip_device_info:
        gather_subset:
          - ltm-pools
        provider: "{{ provider }}"
      register: pools
      delegate_to: localhost


    - name: Determine Pool name using Node IP
      set_fact:
        path: "{{ path + [ item[1]] }}"
      when node in path []
      loop: "{{ pools | json_query('ltm_pools[].[name, members[*].address]')}}"
      
    - name: Display the Var
      debug: var=path

VishalVinu avatar May 11 '21 06:05 VishalVinu

Closing this now. Reopen if you still face the issue. Thanks!

KrithikaChidambaram avatar Jan 18 '23 17:01 KrithikaChidambaram