aruba / aoscx-ansible-collection

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

aoscx_upload_config, upload from local #8

Closed bidetzz closed 2 years ago

bidetzz commented 3 years ago

Hi,

I have a problem when trying to upload a CLI configuration file onto an aoscx switch from local.

In the documentation it says: ref: https://github.com/aruba/aoscx-ansible-collection/blob/master/docs/aoscx_upload_config.md

config_file:
    description: "File name and path for locally uploading configuration,
      will be converted to JSON,
      only JSON version of configuration can be uploaded"
    type: str
    required: false

and the example below:

- name: Copy Running Config from local JSON file as JSON
  aoscx_upload_config:
    config_name: 'running-config'
    remote_config_file_tftp_path: '/user/admin/running.json'

First of all, in the example, it says " remote_config_file_tftp_path:" instead of "config_file" when uploading from a local file. Is it intended ? I'm trying to recreate this example to upload a cli file from local to the switch, but I'm always getting this error:

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Which lead me to believe that the file is supposed to be in JSON? My file is in cli format and in the doc it says "will be converted to JSON". I went to check in the aoscx_upload_config.py file and I found at line 123 and 126 that both config_json and config_file is opening the file as a json file:

https://github.com/aruba/aoscx-ansible-collection/blob/e703f381fad350eea5ecd364640a37005a66d48d/plugins/modules/aoscx_upload_config.py#L122-L128

I never found the part where the cli file should be converted to JSON format for the API. If I try to upload the cli file to the switch with a tftp path, it works fine and the cli file gets uploaded onto the switch without problems. But in this case where the file is stored locally (on the ansible machine), it doesn't seem to make the conversion to JSON. Or at least that's what the error is leading me to believe.

The switch I am using is a aruba CX 6300m JL661a.

Here are my ansible configs in case it's needed:

Ansible version:

ansible 2.10.5
  config file = /ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, May  6 2021, 00:05:59) [GCC 10.2.1 20201203]

Ansible variables:

ansible_user: <our user>
ansible_password: <our password>
ansible_net_user: <our user>
ansible_net_password: <our password>
ansible_network_os: aoscx
ansible_connection: httpapi  # REST API connection method
ansible_httpapi_validate_certs: False
ansible_httpapi_use_ssl: True
ansible_acx_no_proxy: True

Ansible playbook:

---
- hosts: aoscx_switches
  roles:
    - role: arubanetworks.aoscx_role
  tasks:
    - name: Copy Config to Running Config
      aoscx_upload_config:
        config_name: 'running-config'
        config_file: '/ansible/rendered_configs/client.conf'
        vrf: 'mgmt'

FYI: I also tried with "remote_config_file_tftp_path:" instead of "config_file" but without luck.

To summarize:

I'm trying to upload a CLI config file stored locally on the ansible machine to an aoscx switch using the aoscx_upload_config module. The documentation seems to say that this is something possible.

Thank you,

Antoine

tchiapuziowong commented 3 years ago

Hi @bidetzz - thank you for raising this issue! Yes that appeasrs to be a mistake in the example, for aoscx_upload_config CLI configurations are only available to be uploaded via a TFTP server therefore you need to provide the remote_config_file_tftp_path option instead:

- name: Copy CLI from TFTP Server to Running Config
  aoscx_upload_config:
    config_name: 'running-config'
    remote_config_file_tftp_path: 'tftp://192.168.1.2/ansible/rendered_configs/client.conf'
    vrf: 'mgmt'

If you'd rather not use a TFTP server, the best option for a CLI config would be to use one our SSH module to configure the switch using the CLI configurations found in the /ansible/rendered_configs/client.conf file, remember when using SSH modules you'll have to set the ansible_connection variable to network_cli. Here's an example playbook:

- hosts: all
  gather_facts: False
  collections:
    - arubanetworks.aoscx
  vars:
    ansible_connection: network_cli
  tasks:
    - name: Copy generated config to device via SSH
      aoscx_config:
        src: "/ansible/rendered_configs/client.conf"

Please let me know if that answers your question and I'll be sure to update the documentation to reflect the proper info.

bidetzz commented 3 years ago

Hi @tchiapuziowong, Thank you for the quick reply.

When trying the aoscx_config with the SSH module, I get this error:

msg: unable to retrieve current config
  stderr: Unable to decode JSON from response to exec_command('show running-config'). Received 'None'.

my playbook:

- hosts: aoscx_switches
  collections:
    - arubanetworks.aoscx
  gather_facts: False    
  vars:
    ansible_connection: network_cli
  tasks:
    - name: Copy Config to Running Config
      aoscx_config:
        src: '/ansible/rendered_configs/client.conf'

The main goal I am trying to reach is to be able to manage my switches as code. Meaning that I would have all my configs in Git, and when I would want to make a change (ex: change a VLAN or an interface), I could make a merge request, make the change in the config, and then push it back onto the switch.

Thank you,

Antoine

tchiapuziowong commented 3 years ago

You'll need to change your inventory variable ansible_network_os to arubanetworks.aoscx.aoscx that should fix the issue, previously you were using the Ansible role. You should be able to achieve what you're trying to achieve using this module/workflow. Again, this module (aoscx_config) will use SSH to configure your switch using that file (/ansible/rendered_configs/client.conf) as a source for what commands to execute.

bidetzz commented 3 years ago

I already changed the variable and I have the same issue..

My inventory file:


ansible_user: ****
ansible_password: ****
ansible_net_user: ****
ansible_net_password: ****
ansible_network_os: arubanetworks.aoscx.aoscx
ansible_connection: httpapi  # REST API connection method
ansible_httpapi_validate_certs: False
ansible_httpapi_use_ssl: True
ansible_acx_no_proxy: True

And I specify the network_cli in the playbook directly

tchiapuziowong commented 3 years ago

Is the user enabled for SSH login/authentication?

Access-6200-01# show ssh authentication-method
 SSH publickey authentication  : Enabled
 SSH password authentication   : Enabled
 SSH two factor authentication : Disabled
Access-6200-01#
bidetzz commented 3 years ago

Yes it is

STK-001# show ssh authentication-method
 SSH publickey authentication  : Enabled
 SSH password authentication   : Enabled
 SSH two factor authentication : Disabled
tchiapuziowong commented 3 years ago

Can you run ansible-galaxy collection list and verify you have the ansible.netcommon collection ?

ansible-control-machine$ansible-galaxy collection list

# /users/chiapuzi/.ansible/collections/ansible_collections
Collection               Version
------------------------ -------
**ansible.netcommon        1.4.1**
ansible.posix            1.1.1
arubanetworks.aos_switch 1.4.0
arubanetworks.aoscx      2.2.0
ansible-control-machine$
bidetzz commented 3 years ago

Should be all there

/ansible # ansible-galaxy collection list

# /root/.ansible/collections/ansible_collections
Collection          Version
------------------- -------
ansible.netcommon   2.1.0
ansible.utils       2.2.0
arubanetworks.aoscx 2.2.1
tchiapuziowong commented 3 years ago

Are you able to ping the switch from the Ansible machine?

bidetzz commented 3 years ago

yes, I'm able to run other playbook on it, This doesn't feel like a "connection" problem with the switch. If I put Gathering Facts to true, it will connect in the gathering Facts task, but I'm still having the same error on the aoscx_config task.

tchiapuziowong commented 3 years ago

Are you using REST API in your other playbook?

bidetzz commented 3 years ago

yes, first time using the SSH module, I'm always logged in in the switch directly with SSH, but did not use SSH to run playbooks.

bidetzz commented 3 years ago

I'm also able to ssh to the switch from the ansible machine

tchiapuziowong commented 3 years ago

When you SSH into the switch using hte same username/password as what's in the inventory are you able to execute "show running-config" through the CLI?

bidetzz commented 3 years ago

yes I can, I just tested it and it's working fine

tchiapuziowong commented 3 years ago

Can you run in verbose mode and post the output? -vvvv ?

bidetzz commented 3 years ago
TASK [Copy Config to Running Config] ************************************************************************************************************************************************************************
task path: /ansible/playbooks/push_config.yml:8
Tuesday 25 May 2021  16:54:06 +0000 (0:00:01.577)       0:00:01.597 ***********
redirecting (type: connection) ansible.builtin.network_cli to ansible.netcommon.network_cli
Loading collection ansible.netcommon from /root/.ansible/collections/ansible_collections/ansible/netcommon
<10.X.X.X> attempting to start connection
<10.X.X.X> using connection plugin ansible.netcommon.network_cli
Found ansible-connection at path /usr/bin/ansible-connection
<10.X.X.X> found existing local domain socket, using it!
<10.X.X.X> updating play_context for connection
<10.X.X.X>
<10.X.X.X> local domain socket path is /root/.ansible/pc/b1e11ad760
<10.X.X.X> ESTABLISH LOCAL CONNECTION FOR USER: root
<10.X.X.X> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-407x6kb_113 `"&& mkdir "` echo /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475 `" && echo ansible-tmp-1621961646.8850582-459-190720053439475="` echo /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475 `" ) && sleep 0'
redirecting module_util ansible.module_utils.network.common.config to ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config
redirecting module_util ansible.module_utils.network.common.config to ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config
redirecting module_util ansible.module_utils.network.common.utils to ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils
redirecting module_util ansible.module_utils.network.common.utils to ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils
Using module file /root/.ansible/collections/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_config.py
<10.X.X.X> PUT /root/.ansible/tmp/ansible-local-407x6kb_113/tmp5hthw1g9 TO /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475/AnsiballZ_aoscx_config.py
<10.X.X.X> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475/ /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475/AnsiballZ_aoscx_config.py && sleep 0'
<10.X.X.X> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475/AnsiballZ_aoscx_config.py && sleep 0'
<10.X.X.X> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-407x6kb_113/ansible-tmp-1621961646.8850582-459-190720053439475/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
  File "/tmp/ansible_aoscx_config_payload_jw4s44nx/ansible_aoscx_config_payload.zip/ansible_collections/arubanetworks/aoscx/plugins/module_utils/aoscx.py", line 93, in get_config
    return _DEVICE_CONFIGS[cmd]
fatal: [client1]: FAILED! => changed=false
  invocation:
    module_args:
      after: null
      backup: false
      backup_options: null
      before: null
      diff_against: null
      diff_ignore_lines: null
      intended_config: null
      lines: null
      match: line
      parents: null
      provider: null
      replace: line
      running_config: null
      save_when: modified
      src: /ansible/rendered_configs/client.conf
  msg: unable to retrieve current config
  stderr: Unable to decode JSON from response to exec_command('show running-config'). Received 'None'.
  stderr_lines: <omitted>
tchiapuziowong commented 3 years ago

Hmm okay - do you have this entry in your ansible.cfg file as well? host_key_checking = false

bidetzz commented 3 years ago

Yes I do, under [defaults]

tchiapuziowong commented 3 years ago

@bidetzz can you verify you have paramiko installed with python3 ?

ansible-control-machine$pip3 list Package Version


ansible 4.0.0 ansible-core 2.11.1 bcrypt 3.2.0 cffi 1.14.5 cryptography 3.4.7 Jinja2 3.0.1 MarkupSafe 2.0.1 packaging 20.9 paramiko 2.7.2 pip 20.1.1 pycparser 2.20 PyNaCl 1.4.0 pyparsing 2.4.7 PyYAML 5.4.1 resolvelib 0.5.4 setuptools 47.1.0 six 1.16.0

bidetzz commented 3 years ago

Yes it is installed paramiko 2.7.2

bidetzz commented 3 years ago

I contacted my SE about this issue.

bidetzz commented 3 years ago

Hi @tchiapuziowong

Is it the same thing with the aoscx_backup_config module ?

Meaning that I can only backup the config as JSON if i'm downloading to local and not with TFTP ?

Seems like when I run the playbook with config_type: 'cli', it's saving in JSON format anyway.

My playbook:

---
- hosts: aoscx_switches
  roles:
    - role: arubanetworks.aoscx_role
  tasks: 
    - name: Backup running-config as golden
      aoscx_backup_config:
        config_name: 'running-config'
        output_file: '/ansible/golden_configs/golden_test.cli'
        config_type: 'cli'

And the result is saved as JSON.

Thank you,

tchiapuziowong commented 3 years ago

Yes if not using TFTP - JSON is the output option only -

options:
  config_name:
    description: "Config file or checkpoint to be downloaded. When using TFTP
      only running-config or startup-config can be used"
    type: str
    default: 'running-config'
    required: false
  output_file:
    description: "File name and path for locally downloading configuration,
      only JSON version of configuration will be downloaded"
    type: str
    required: false
ljb2of3 commented 3 years ago

@tchiapuziowong curious if there's any movement on this. I'm getting stuck using aoscx_config with the same error:

Unable to decode JSON from response to exec_command('show running-config'). Received 'None'

tchiapuziowong commented 3 years ago

Hi @ljb2of3 ! We were able to detect various reasons for this output so it's been a bit difficult to troubleshoot - are you able to produce the output of ansible --version and python3 -m pip list - also are you using Ansible AWX or a container at all? Also if you're able to contact your Aruba SE we could get it escalated internally.

ljb2of3 commented 3 years ago

Thanks @tchiapuziowong would it it beneficial if I open a new issue here, or a case with TAC? I can certainly talk to my SE... He's been camped out at my office for several days working on other issues with me this week.

tchiapuziowong commented 3 years ago

Go ahead and work with your SE to reach out to our PDL aruba-automation@hpe.com and we can figure it out over a call - We'll keep this issue open and I'll post the results of our resolution so others can benefit as well!

tchiapuziowong commented 3 years ago

@ljb2of3 - just to make sure , have you verified you have

# uncomment this to disable SSH key host checking
host_key_checking = False

in your ansible.cfg file? you can find it's location through ansible --version

tchiapuziowong commented 2 years ago

I'm happy to announce a fix for this issue has been published and you can now pull the latest version of our Collection to verify: ansible-galaxy collection install arubanetworks.aoscx -f

Also ensure you're working with the most updated version of the ansible.netcommon library as well: ansible-galaxy collection install ansible.netcommon -f