aruba / aoscx-ansible-collection

Ansible collections for AOS-CX switches 
47 stars 23 forks source link

macOS - No module named 'pyaoscx' #110

Closed fre4ki closed 2 months ago

fre4ki commented 2 months ago

Hey guys,

i'm trying to create a playbook in a python virtual environment on macOS Sonoma and deploy it - but get the message "No module named 'pyaoscx'".

It seems the pyaoscx role is installed but not recognized?

Outputs:

**# ansible-galaxy collection list**

# /Users/andreas/.ansible/collections/ansible_collections
Collection                               Version
---------------------------------------- -------
ansible.netcommon                        7.0.0
ansible.utils                            5.0.0
arubanetworks.aoscx                      4.4.0
**# pip list**
Package            Version
------------------ -----------
ansible-pylibssh   1.2.0.post4
bcrypt             4.1.3
certifi            2024.6.2
cffi               1.16.0
charset-normalizer 3.3.2
cryptography       42.0.8
idna               3.7
netaddr            1.3.0
paramiko           3.4.0
pip                24.1.1
pyaoscx            2.6.0
pycparser          2.22
PyNaCl             1.5.0
PyYAML             6.0.1
requests           2.32.3
requests-toolbelt  1.0.0
urllib3            2.2.2
wheel              0.43.0

Inventory File:

❯ cat cx-inv.yml
---
all:
  vars:     #  Global Variables
      ansible_user: admin
      ansible_password: admin
      ansible_network_os: arubanetworks.aoscx.aoscx
      ansible_connection: arubanetworks.aoscx.aoscx  # REST API via pyaoscx connection method
      ansible_aoscx_validate_certs: False
      ansible_aoscx_use_proxy: False
      ansible_acx_no_proxy: True
            #  Switch Variables
      switch_ip_netw:
      switch_ip_mask:
  hosts:
    cx6100:
      ansible_host: 10.10.99.12

Playbook:

❯ cat cx-fw-with-reboot.yml
---
- hosts: cx6100
  collections:
    - arubanetworks.aoscx
  vars:
    ansible_python_interpreter: /usr/bin/python3
  gather_facts: False
  tasks:
    - name: UPLOAD FIRMWARE TO 6100 DEVICES - PRIMARY SLOT
      aoscx_upload_firmware:
        partition_name: 'primary'
        firmware_file_path: '~/Daten/Firmware/Aruba/Switches/6000-6100/ArubaOS-CX_6100-6000_10_13_1020.swi'
    - name: BOOT PRIMARY SLOT
      aoscx_boot_firmware:
        partition_name: 'primary'

- hosts: cx6200
  collections:
    - arubanetworks.aoscx
  vars:
    ansible_python_interpreter: /usr/bin/python3
  gather_facts: False
  tasks:
    - name: UPLOAD FIRMWARE TO 6200 DEVICES - PRIMARY SLOT
      aoscx_upload_firmware:
        partition_name: 'primary'
        firmware_file_path: '~/Daten/Firmware/Aruba/Switches/6200/ArubaOS-CX_6200_10_13_1020.swi'
    - name: BOOT PRIMARY SLOT
      aoscx_boot_firmware:
        partition_name: 'primary'

- hosts: cx6300
  collections:
    - arubanetworks.aoscx
  vars:
    ansible_python_interpreter: /usr/bin/python3
  gather_facts: False
  tasks:
    - name: UPLOAD FIRMWARE TO 6300 DEVICES - PRIMARY SLOT
      aoscx_upload_firmware:
        partition_name: 'primary'
        firmware_file_path: '~/Daten/Firmware/Aruba/Switches/6300-6400/ArubaOS-CX_6400-6300_10_13_1020.swi'
    - name: BOOT PRIMARY SLOT
      aoscx_boot_firmware:
        partition_name: 'primary'

Complete output:

ansible-playbook cx-fw-with-reboot.yml -i cx-inv.yml -vvv
ansible-playbook [core 2.17.1]
  config file = /Users/andreas/.ansible.cfg
  configured module search path = ['/Users/andreas/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/Cellar/ansible/10.1.0/libexec/lib/python3.12/site-packages/ansible
  ansible collection location = /Users/andreas/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible-playbook
  python version = 3.12.4 (main, Jun  6 2024, 18:26:44) [Clang 15.0.0 (clang-1500.3.9.4)] (/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python)
  jinja version = 3.1.4
  libyaml = True
Using /Users/andreas/.ansible.cfg as config file
host_list declined parsing /Users/andreas/Documents/Automation/cx-inv.yml as it did not pass its verify_file() method
script declined parsing /Users/andreas/Documents/Automation/cx-inv.yml as it did not pass its verify_file() method
Parsed /Users/andreas/Documents/Automation/cx-inv.yml inventory source with yaml plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: cx-fw-with-reboot.yml ***********************************************************************************
3 plays in cx-fw-with-reboot.yml

PLAY [cx6100] *****************************************************************************************************

TASK [UPLOAD FIRMWARE TO 6100 DEVICES - PRIMARY SLOT] *************************************************************
task path: /Users/andreas/Documents/Automation/cx-fw-with-reboot.yml:9
<10.10.99.12> ESTABLISH LOCAL CONNECTION FOR USER: andreas
<10.10.99.12> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr `"&& mkdir "` echo /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954 `" && echo ansible-tmp-1719468600.7857878-2398-2680255875954="` echo /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954 `" ) && sleep 0'
Using module file /Users/andreas/.ansible/collections/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_upload_firmware.py
<10.10.99.12> PUT /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/tmpzom0v7sq TO /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954/AnsiballZ_aoscx_upload_firmware.py
<10.10.99.12> EXEC /bin/sh -c 'chmod u+x /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954/ /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954/AnsiballZ_aoscx_upload_firmware.py && sleep 0'
<10.10.99.12> EXEC /bin/sh -c '/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954/AnsiballZ_aoscx_upload_firmware.py && sleep 0'
<10.10.99.12> EXEC /bin/sh -c 'rm -f -r /Users/andreas/.ansible/tmp/ansible-local-2396ymedqelr/ansible-tmp-1719468600.7857878-2398-2680255875954/ > /dev/null 2>&1 && sleep 0'
### The full traceback is:
  File "/var/folders/1y/m5hml76n4m97qvh8gs_rsd500000gn/T/ansible_aoscx_upload_firmware_payload_h9ma3j0w/ansible_aoscx_upload_firmware_payload.zip/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_upload_firmware.py", line 137, in main
    from pyaoscx.device import Device
fatal: [cx6100]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "firmware_file_path": "~/Daten/Firmware/Aruba/Switches/6000-6100/ArubaOS-CX_6100-6000_10_13_1020.swi",
            "partition_name": "primary",
            "remote_firmware_file_path": null,
            "vrf": null,
            "wait_firmware_upload": false
        }
    },
    "msg": "No module named 'pyaoscx'"
}

PLAY RECAP ********************************************************************************************************
cx6100                     : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
alagoutte commented 2 months ago

Do you have try to remove

vars:
    ansible_python_interpreter: /usr/bin/python3

and check also if this version of python have the module ? /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python

using for example : /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python pip list

fre4ki commented 2 months ago

Do you have try to remove

vars:
    ansible_python_interpreter: /usr/bin/python3

and check also if this version of python have the module ? /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python

using for example : /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python pip list

Yes, i'm also trying to remove the variable.

When i enter:

❯ /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python pip list
/opt/homebrew/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python: can't open file '/Users/andreas/Documents/Automation/pip': [Errno 2] No such file or directory
alagoutte commented 2 months ago

/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python -m pip list ?

/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python --version

tchiapuziowong commented 2 months ago

@fre4ki Can you confirm if removing this line from your playbook allows it to run successfully? ansible_python_interpreter: /usr/bin/python3

fre4ki commented 2 months ago

/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python -m pip list ?

zsh: no matches found: ?

When entering: /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python -m pip list

Package Version


ansible 10.1.0 ansible-core 2.17.1 ansible-pylibssh 1.2.0.post4 apache-libcloud 3.8.0 attrs 23.2.0 autopage 0.5.2 bcrypt 4.1.3 boto3 1.34.128 botocore 1.34.128 cachetools 5.3.3 certifi 2024.6.2 cffi 1.16.0 charset-normalizer 3.3.2 cliff 4.7.0 cmd2 2.4.3 cryptography 42.0.8 debtcollector 3.0.0 decorator 5.1.1 dnspython 2.6.1 docker 7.1.0 dogpile.cache 1.3.3 future 1.0.0 google-auth 2.30.0 idna 3.7 iso8601 2.1.0 Jinja2 3.1.4 jmespath 1.0.1 jsonpatch 1.33 jsonpointer 3.0.0 junos-eznc 2.7.1 jxmlease 1.0.3 kerberos 1.3.1 keystoneauth1 5.6.0 kubernetes 30.1.0 lxml 5.2.2 MarkupSafe 2.1.5 msgpack 1.0.8 ncclient 0.6.15 netaddr 1.3.0 netifaces 0.11.0 ntc_templates 5.1.0 oauthlib 3.2.2 openshift 0.13.2 openstacksdk 3.1.0 os-client-config 2.1.0 os-service-types 1.7.0 osc-lib 3.0.1 oslo.config 9.4.0 oslo.context 5.5.0 oslo.i18n 6.3.0 oslo.log 6.0.0 oslo.serialization 5.4.0 oslo.utils 7.1.0 packaging 24.1 paramiko 3.4.0 passlib 1.7.4 pbr 6.0.0 pexpect 4.9.0 pip 24.1.1 platformdirs 4.2.2 prettytable 3.10.0 proxmoxer 2.0.1 ptyprocess 0.7.0 pyasn1 0.6.0 pyasn1_modules 0.4.0 pycparser 2.22 PyNaCl 1.5.0 pyparsing 3.1.2 pyperclip 1.8.2 pyserial 3.5 pysphere3 0.1.8 pyspnego 0.11.0 python-consul 1.1.0 python-dateutil 2.9.0.post0 python-keystoneclient 5.4.0 python-neutronclient 11.3.0 python-string-utils 1.0.0 pywinrm 0.4.3 PyYAML 6.0.1 requests 2.32.3 requests-credssp 2.0.0 requests_ntlm 1.3.0 requests-oauthlib 2.0.0 requestsexceptions 1.4.0 resolvelib 1.0.1 rfc3986 2.0.0 rsa 4.9 s3transfer 0.10.1 scp 0.15.0 setuptools 70.0.0 shade 1.33.0 simplejson 3.19.2 six 1.16.0 stevedore 5.2.0 textfsm 1.1.3 transitions 0.9.1 tzdata 2024.1 urllib3 2.2.2 wcwidth 0.2.13 websocket-client 1.8.0 wheel 0.43.0 wrapt 1.16.0 xmltodict 0.13.0 yamlordereddictloader 0.4.2 zabbix-api 0.5.6

/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python --version Python 3.12.4

fre4ki commented 2 months ago

@fre4ki Can you confirm if removing this line from your playbook allows it to run successfully? ansible_python_interpreter: /usr/bin/python3

My playbook file is now this:

image

This is the output: ansible-playbook cx-fw-with-reboot.yml -i cx-inv.yml -vvv

ansible-playbook [core 2.17.1]
  config file = /Users/andreas/.ansible.cfg
  configured module search path = ['/Users/andreas/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/Cellar/ansible/10.1.0/libexec/lib/python3.12/site-packages/ansible
  ansible collection location = /Users/andreas/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible-playbook
  python version = 3.12.4 (main, Jun  6 2024, 18:26:44) [Clang 15.0.0 (clang-1500.3.9.4)] (/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python)
  jinja version = 3.1.4
  libyaml = True
Using /Users/andreas/.ansible.cfg as config file
host_list declined parsing /Users/andreas/Documents/Automation/cx-inv.yml as it did not pass its verify_file() method
script declined parsing /Users/andreas/Documents/Automation/cx-inv.yml as it did not pass its verify_file() method
Parsed /Users/andreas/Documents/Automation/cx-inv.yml inventory source with yaml plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: cx-fw-with-reboot.yml ******************************************************************************
3 plays in cx-fw-with-reboot.yml

PLAY [cx6100] ************************************************************************************************

TASK [UPLOAD FIRMWARE TO 6100 DEVICES - PRIMARY SLOT] ********************************************************
task path: /Users/andreas/Documents/Automation/cx-fw-with-reboot.yml:7
<10.10.99.12> ESTABLISH LOCAL CONNECTION FOR USER: andreas
<10.10.99.12> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu `"&& mkdir "` echo /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300 `" && echo ansible-tmp-1719594393.075594-2159-148908275533300="` echo /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300 `" ) && sleep 0'
Using module file /Users/andreas/.ansible/collections/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_upload_firmware.py
<10.10.99.12> PUT /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/tmp0tifs_as TO /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300/AnsiballZ_aoscx_upload_firmware.py
<10.10.99.12> EXEC /bin/sh -c 'chmod u+x /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300/ /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300/AnsiballZ_aoscx_upload_firmware.py && sleep 0'
<10.10.99.12> EXEC /bin/sh -c '/opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300/AnsiballZ_aoscx_upload_firmware.py && sleep 0'
<10.10.99.12> EXEC /bin/sh -c 'rm -f -r /Users/andreas/.ansible/tmp/ansible-local-2155ch062qmu/ansible-tmp-1719594393.075594-2159-148908275533300/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
  File "/var/folders/1y/m5hml76n4m97qvh8gs_rsd500000gn/T/ansible_aoscx_upload_firmware_payload_y96k8r1i/ansible_aoscx_upload_firmware_payload.zip/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_upload_firmware.py", line 137, in main
    from pyaoscx.device import Device
fatal: [cx6100]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "firmware_file_path": "~/Daten/Firmware/Aruba/Switches/6000-6100/ArubaOS-CX_6100-6000_10_13_1020.swi",
            "partition_name": "primary",
            "remote_firmware_file_path": null,
            "vrf": null,
            "wait_firmware_upload": false
        }
    },
    "msg": "No module named 'pyaoscx'"
}

PLAY RECAP ***************************************************************************************************
cx6100                     : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
tchiapuziowong commented 2 months ago

Try manually installing using the command: /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python -m pip install pyaoscx

fre4ki commented 2 months ago

Try manually installing using the command: /opt/homebrew/Cellar/ansible/10.1.0/libexec/bin/python -m pip install pyaoscx

Amazing, i think thats it.

Another question: Is there a way to upgrade factory-default devices (which has no password configured)? I know the ZTP method with DHCP but sometimes it is easier to work with ansible or other methods (because no dhcp options has to be set).

When i'm not entering any password they are asking for a password. When i hit enter it works but maybe there is another way?

tchiapuziowong commented 2 months ago

Fantastic news! The pyaoscx & Ansible CX collection handle the initial password logic but it's basically as follows:

  1. Attempt to login with known credentials
  2. If response does not return 200 then attempt to login using default credentials (admin/)
  3. If response to step 3 returns code 268, the switch needs a password configured so PUT the password to the switch

Here's the code for which that's handled: https://github.com/aruba/pyaoscx/blob/master/pyaoscx/session.py#L243-L283