# Ansible checking AP status

**URL:** <https://forum.ansible.com/t/ansible-checking-ap-status/2129>\
**Category:** Get Help\
**Tags:** playbook, ansible-core\
**Created:** [November 3, 2023, 8:49am UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129 "2023-11-03T08:49:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![bwchuah](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@bwchuah](https://forum.ansible.com/u/bwchuah)\
**Post date:** [November 3, 2023, 8:49am UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/1 "2023-11-03T08:49:37Z")

</div>

**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.](https://github.com/mtoshi/airwaveapiclient)  
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.

---

<div class="post-metadata">

**Author:** ![ptn](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/ptn/32/481_2.png) [@ptn](https://forum.ansible.com/u/ptn)\
**Post date:** [November 3, 2023, 5:14pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/2 "2023-11-03T17:14:31Z")

</div>

Hi,

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

- Use [script module](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_module.html) 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](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html)), or directly parse your registered var while exploiting it in your next task
- Send an email (using [mail module](https://docs.ansible.com/ansible/latest/collections/community/general/mail_module.html) 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](https://www.arubanetworks.com/techdocs/centralonprem/2.5.6/content/api/api_webhook.htm) (not sure if it’s an option for you) to [Event-driver Ansible](https://ansible.readthedocs.io/projects/rulebook/en/stable/), which could then parse the message and send the email in response, from a playbook or script.

---

<div class="post-metadata">

**Author:** ![bwchuah](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@bwchuah](https://forum.ansible.com/u/bwchuah)\
**Post date:** [November 4, 2023, 2:29pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/3 "2023-11-04T14:29:26Z")

</div>

```auto
---
- 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.

---

<div class="post-metadata">

**Author:** ![bwchuah](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@bwchuah](https://forum.ansible.com/u/bwchuah)\
**Post date:** [November 4, 2023, 3:58pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/4 "2023-11-04T15:58:41Z")

</div>

```auto
---
- 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?

---

<div class="post-metadata">

**Author:** ![ptn](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/ptn/32/481_2.png) [@ptn](https://forum.ansible.com/u/ptn)\
**Post date:** [November 6, 2023, 6:06pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/5 "2023-11-06T18:06:46Z")

</div>

Hey,

Seems alright to me 🙂. 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](https://ansible.readthedocs.io/projects/lint/rules/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.

---

<div class="post-metadata">

**Author:** ![bwchuah](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@bwchuah](https://forum.ansible.com/u/bwchuah)\
**Post date:** [November 7, 2023, 3:10pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/6 "2023-11-07T15:10:23Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ptn](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/ptn/32/481_2.png) [@ptn](https://forum.ansible.com/u/ptn)\
**Post date:** [November 7, 2023, 5:32pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/7 "2023-11-07T17:32:30Z")

</div>

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](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html#examples).

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

```python
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:

```yaml
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:

```yaml
---

- 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:

```bash
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.

---

<div class="post-metadata">

**Author:** ![bwchuah](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@bwchuah](https://forum.ansible.com/u/bwchuah)\
**Post date:** [November 8, 2023, 9:44am UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/8 "2023-11-08T09:44:28Z")

</div>

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.

```auto
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

```auto
---
- 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](https://us1.discourse-cdn.com/ansible/original/2X/f/fb02e4de8c79989036b405a88240040385bff452.png)

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

Thanks

---

<div class="post-metadata">

**Author:** ![ptn](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/ptn/32/481_2.png) [@ptn](https://forum.ansible.com/u/ptn)\
**Post date:** [November 13, 2023, 7:51pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/9 "2023-11-13T19:51:16Z")

</div>

Sorry for the delay 😕. 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:

- [community.general.json\_query filter – Select a single element or a data subset from a complex data structure — Ansible Documentation](https://docs.ansible.com/ansible/latest/collections/community/general/json_query_filter.html#ansible-collections-community-general-json-query-filter)
- [community.general.jc filter – Convert output of many shell commands and file-types to JSON — Ansible Documentation](https://docs.ansible.com/ansible/latest/collections/community/general/jc_filter.html)

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

Have a good one !

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [December 13, 2023, 7:51pm UTC](https://forum.ansible.com/t/ansible-checking-ap-status/2129/10 "2023-12-13T19:51:39Z")

</div>

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