Ansible checking AP status

ansible checking AP status.

Tool:
a. ansible core 2.14.2
b. python script edited from github GitHub - mtoshi/airwaveapiclient: Aruba Networks AirWave API Client.
c. aruba airwave

Issue: the airwave server send alot email when devices is down so need so help to automate it.

Expectation:

  1. run the python script → show the output as below
    AP Name: AP01
    Is Up: false
    AP Name: AP15
    Is Up: false
  2. rerun the script after 5-10mins to check if the device is down.
  3. if down, send email if not just ignore.

I have completed the script, im looking into drafting the playbook and what module need to be use to achieve above task.

Hi,

Not saying it’s the best way to do it, but you could:

  • Use script module to run your script locally, using delegate_to or local_action (for instance, except if you plan to run it from another node), then register result in var
  • Parse var to extract AP Names whom “Is Up” field have value “false”, assuming script doesn’t only list down APs for starter. You could either store the parsed list in facts for later use (using set_fact module), or directly parse your registered var while exploiting it in your next task
  • Send an email (using mail module or something else) if APs down list is not empty, adding list’s items to mail body

Then schedule playbook execution with whatever you usually use to schedule jobs (AWX, CI system, jobs scheduler, systemd timer, cron, at, …).

Another suggestion would be for your AP to send a notification using a webhook (not sure if it’s an option for you) to Event-driver Ansible, which could then parse the message and send the email in response, from a playbook or script.

1 Like
---
- name: Healthcheck AP
  hosts: localhost
  tasks:
    - name: Alert received from source run python script, print the AP name Is up is false
      ansible.builtin.script: /root/nus/script.py
      args:
        executable: python3
      register: result1

#    - ansible.builtin.debug:
#        var: result1

    - name: Recheck the AP status after 5 minutes
      ansible.builtin.wait_for:
        timeout: 300
      delegate_to: localhost

    - name: Rerun the script
      ansible.builtin.script: /root/nus/script.py
      args:
        executable: python3
      register: result2

#    - name: compare the difference between result
#      ansible.utils.fact_diff:
#        before: "{{ result1}}"
#        after: "{{ result2 }}"
#      when:  result1 == result2
#      register: compare_result

Hi,

Thanks for your reply, might need your or ansible guru here to help how can i compare the result1 and result 2 in ansible

Result1:
AP Name: AP01
AP Name: AP02
AP Name: AP03

Result2: (maybe)
AP Name: AP01
AP Name: AP02

Then from here we can know the AP01 and AP02 is got issue then need to perform the email task.

---
- name: Healthcheck AP
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Alert received from source run python script, print the AP name Is up is false
      ansible.builtin.script: /root/nus/script.py
      args:
        executable: python3
      register: result1

    - set_fact:
        ap_result1: "{{ result1.stdout_lines }}"

    - name: Recheck the AP status after 5 minutes
      ansible.builtin.wait_for:
        timeout: 300
      delegate_to: localhost

    - name: Rerun the script
      ansible.builtin.script: /root/nus/script.py
      args:
        executable: python3
      register: result2

    - set_fact:
        ap_result2: "{{ result2.stdout_lines }}"

    - name: compare the result
      set_fact:
        common_ap: "{{ ap_result1 | intersect(ap_result2) }}"

    - debug:
        msg: "{{ common_ap }}"

Almost there to complete, but if the playbook is too long is it ok?

1 Like

Hey,

Seems alright to me :slight_smile:. Also, nice use of intersect filter !

Only things I adjust would be:

  • To use connection: local (assuming you haven’t defined it elsewhere) to avoid having to connect through ssh on localhost
  • To use fqcn, as it’s best practice

You could also define your script task in another file (comporting only task, no play) and use import_tasks or include_tasks from your playbook to reuse it without having to write it twice, but it might not be worth it for such a small “improvement”.

Another thing you could do would be to periodically run your script and store result in facts, but in a persistent way (file, database, …). So you could just compare the last two runs without having to run your script again, or twice in the same play.
Depending on how much time your script execution take, it could be a good idea to do so.

2 Likes

Hi Pierre,

Thanks for the suggestion, if i need set_fact for a list of python script is it possible?
Result1:
AP-ID: 1
AP Name: AP01
AP-ID: 2
AP Name: AP02
AP-ID: 3
AP Name: AP03

when running the script, it show the output as above, how can i bind AP-ID value and AP name together?

Thanks

Hey,

if i need set_fact for a list of python script is it possible?

You’d like to store a list in a var using set_fact module, is that it ? If so, yes you can. Check examples on module doc page.

Now your example output would look more like a list of dicts, because for a pure dict, you would then have duplicate keys. So:

result1:
  - AP-ID: 1
    AP Name: AP01
  - AP-ID: 2
    AP Name: AP02
  - AP-ID: 3
    AP Name: AP03

In the case your script gives you exactly this output:

AP-ID: 1
AP Name: AP01
AP-ID: 2
AP Name: AP02
AP-ID: 3
AP Name: AP03

You would need to parse it before or while storing it in a var, adding each item pair (AP-ID and AP Name) as individual list item. Tell me if you’d like me to give you some snippet.

Another solution would be to parse it raw with awk, sed, … beforehand, or see if your script could output each item individually. Depends on your usecase really.

how can i bind AP-ID value and AP name together?

There are multiple ways to do so and I’m not very good with data manipulation, but here is an example:

---

- name: Test Playbook
  gather_facts: no
  connection: local
  hosts: localhost
  vars:
    result1:
      - AP-ID: 1
        AP Name: AP01
      - AP-ID: 2
        AP Name: AP02
      - AP-ID: 3
        AP Name: AP03
  tasks:
    - name: Combine dict values
      ansible.builtin.debug:
        msg: "{{ item.values()|join(',') }}"
      loop: "{{ result1 }}"

Output:

PLAY [Test Playbook] *******************************************************************************************************************************************************************************************************************************************************************************************************

TASK [Combine dict values] *************************************************************************************************************************************************************************************************************************************************************************************************
Tuesday 07 November 2023  18:24:07 +0100 (0:00:00.008)       0:00:00.008 ****** 
ok: [localhost] => (item={'AP-ID': 1, 'AP Name': 'AP01'}) => {
    "msg": "1,AP01"
}
ok: [localhost] => (item={'AP-ID': 2, 'AP Name': 'AP02'}) => {
    "msg": "2,AP02"
}
ok: [localhost] => (item={'AP-ID': 3, 'AP Name': 'AP03'}) => {
    "msg": "3,AP03"
}

I’m not sure if it’s precisely what you’re looking for; if not, please provide more context and I’ll see what I can do.

1 Like

Hi Pierre,

What i want actually is something like this. Run python script from the gihub with little bit changes it will return the values like following.

ap_list = []
 
def add_ap(ap_id, ap_name):
    ap_list.append({'AP ID': ap_id, 'AP Name': ap_name})
 
add_ap(630, 'WSG-TMHD-01-AP15')
add_ap(5746, 'WSG-RH4-01-AP14')
add_ap(6314, 'WSG-RH5-01-AP21')
add_ap(5689, 'WSG-RH3-03-AP25')
 
print(ap_list)

the output

[{‘AP ID’: 630, ‘AP Name’: ‘WSG-AP15’}, {‘AP ID’: 5746, ‘AP Name’: ‘WSG-AP14’}, {‘AP ID’: 6314, ‘AP Name’: ‘WSG-AP21’}, {‘AP ID’: 5689, ‘AP Name’: ‘WSG-AP25’}]

After 5-10mins, rerun the above script, it will return another status down AP.
imagine the output2 is below:

[{‘AP ID’: 630, ‘AP Name’: ‘WSG-AP15’}, {‘AP ID’: 5746, ‘AP Name’: ‘WSG-AP14’}, {‘AP ID’: 6314, ‘AP Name’: ‘WSG-AP21’}, {‘AP ID’: 56, ‘AP Name’: ‘WSG-AP01’}]

After do the compare value

---
- name: Healthcheck AP
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: output the result1
      command: cat /root/bwchuah-local/list1.txt
      register: result1

    - set_fact:
        ap_result1: "{{ result1.stdout }}"

    - debug:
        msg: "{{ ap_result1 }}"

    - name: output the result2
      command: cat /root/bwchuah-local/list2.txt
      register: result2

    - set_fact:
        ap_result2: "{{ result2.stdout }}"

    - debug:
        msg: "{{ ap_result2 }}"

    - name: compare the result
      set_fact:
        common_ap: "{{ ap_result1 | intersect(ap_result2) }}"

    - debug:
        msg: "{{ common_ap }}"

so once get the value i need to put them accordingly to jinja template so that it can presentable to itsm or email to helpdesk to proceed rma or further action.
image

Now working on the jinja template. But thanks for your response.

Thanks

1 Like

Sorry for the delay :confused:. You’ll need to parse the output, or do it another way.
There are a handful of plugins you can use to that effect, like one of those:

You have been resourceful enough to solve your own issues so far :smile:, but please tell if you need help on this, and I’ll try to take some time on your issue.

Have a good one !

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.