Customer is able to upgrade Juniper QFX successfully using Ansible PyEz, but failed to upgrade (and downgrade) the MX204 devices using Ansible PyEz.
In both cases we are using a Podman container for Ansible and its dependencies. Here are the installed library within the container:
Starting an interactive Bash session
bash-5.0# pip freeze
ansible==3.3.0
ansible-base==2.10.8
appdirs==1.4.4
bcrypt==3.2.0
CacheControl==0.12.6
certifi==2020.4.5.1
cffi==1.14.2
chardet==3.0.4
colorama==0.4.3
configparser==5.0.2
contextlib2==0.6.0
cryptography==3.1
distlib==0.3.0
distro==1.5.0
future==0.18.2
html5lib==1.0.1
icdiff==1.9.1
idna==2.9
Jinja2==2.11.2
jsnapy==1.3.6
junos-eznc==2.6.0
jxmlease==1.0.3
lockfile==0.12.2
lxml==4.5.1
MarkupSafe==1.1.1
msgpack==1.0.0
ncclient==0.6.9
netaddr==0.8.0
ntc-templates==1.5.0
ordered-set==4.0.1
packaging==20.4
paramiko==2.7.1
pep517==0.8.2
progress==1.5
pycparser==2.20
PyNaCl==1.4.0
pyparsing==2.4.7
pyserial==3.4
pytoml==0.1.21
PyYAML==5.3.1
requests==2.23.0
retrying==1.3.3
scp==0.13.2
six==1.15.0
textfsm==1.1.0
toml==0.10.1
transitions==0.8.2
urllib3==1.25.9
webencodings==0.5.1
xmltodict==0.12.0
yamlordereddictloader==0.4.0
We are using the latest version of the official juniper.device collection:
https://galaxy.ansible.com/ui/repo/published/juniper/device/docs/
bash-5.0# ansible-galaxy collection list | grep -i jun
junipernetworks.junos 1.3.0
juniper.device 1.0.6
Here is the Ansible task that fails:
- name: Install junos package on MX204
juniper.device.software:
host: "{{ host.netconf_ip }}"
user: "{{ junos_user }}"
passwd: "{{ junos_password }}"
port: "{{ netconf_port }}"
#reboot: yes
version: "20.0" # The running of this task on the MX204 is determined by the when statements below, not by the standard way of comparing software versions.
local_package: "{{ junos_upgrade_dir }}/{{ junos_upgrade_package }}"
logfile: "{{ junos_upgrade_logfile }}"
vmhost: yes
#all_re: no
register: junos_upgrade_software
notify:
- Wait for node to reboot
- Wait for node to come online
Here is the failure log:
TASK [junos_upgrade : Install junos package on MX204] ***********************************************************************************************************************************************************************************
task path: /project/roles/junos_upgrade/tasks/main.yml:221
redirecting filter ansible.builtin.ipaddr to ansible.netcommon.ipaddr
<10.61.81.120> ESTABLISH LOCAL CONNECTION FOR USER: root
<10.61.81.120> EXEC /bin/sh -c 'echo ~root && sleep 0'
<10.61.81.120> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360 `" && echo ansible-tmp-1732082941.262234-116-156391285562360="` echo /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360 `" ) && sleep 0'
Using module file /root/.ansible/collections/ansible_collections/juniper/device/plugins/modules/software.py
<10.61.81.120> PUT /root/.ansible/tmp/ansible-local-2kqw8zcdm/tmpgqwwo7ja TO /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py
<10.61.81.120> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/ /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py && sleep 0'
<10.61.81.120> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py && sleep 0'
<10.61.81.120> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py", line 102, in
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible_collections.juniper.device.plugins.modules.software', init_globals=None, run_name='__main__', alter_sys=True)
File "/usr/lib/python3.8/runpy.py", line 207, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/usr/lib/python3.8/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/tmp/ansible_juniper.device.software_payload_g373fu20/ansible_juniper.device.software_payload.zip/ansible_collections/juniper/device/plugins/modules/software.py", line 839, in
File "/tmp/ansible_juniper.device.software_payload_g373fu20/ansible_juniper.device.software_payload.zip/ansible_collections/juniper/device/plugins/modules/software.py", line 725, in main
File "/usr/lib/python3.8/site-packages/jnpr/junos/utils/sw.py", line 975, in install
add_ok = self.pkgadd(
File "/usr/lib/python3.8/site-packages/jnpr/junos/utils/sw.py", line 242, in pkgadd
rsp = self.rpc.request_vmhost_package_add(
File "/usr/lib/python3.8/site-packages/jnpr/junos/rpcmeta.py", line 343, in _exec_rpc
raise TypeError(
TypeError: The value None for argument member-id is of . Argument values must be a string, boolean, or list/tuple of strings and booleans.
fatal: [juvcw1sg2101.uae-dev.cmn-model.corp.telstra.com]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\
File \"/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py\", line 102, in \
_ansiballz_main()\
File \"/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py\", line 94, in _ansiballz_main\
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\
File \"/root/.ansible/tmp/ansible-tmp-1732082941.262234-116-156391285562360/AnsiballZ_software.py\", line 40, in invoke_module\
runpy.run_module(mod_name='ansible_collections.juniper.device.plugins.modules.software', init_globals=None, run_name='__main__', alter_sys=True)\
File \"/usr/lib/python3.8/runpy.py\", line 207, in run_module\
return _run_module_code(code, init_globals, run_name, mod_spec)\
File \"/usr/lib/python3.8/runpy.py\", line 97, in _run_module_code\
_run_code(code, mod_globals, init_globals,\
File \"/usr/lib/python3.8/runpy.py\", line 87, in _run_code\
exec(code, run_globals)\
File \"/tmp/ansible_juniper.device.software_payload_g373fu20/ansible_juniper.device.software_payload.zip/ansible_collections/juniper/device/plugins/modules/software.py\", line 839, in \
File \"/tmp/ansible_juniper.device.software_payload_g373fu20/ansible_juniper.device.software_payload.zip/ansible_collections/juniper/device/plugins/modules/software.py\", line 725, in main\
File \"/usr/lib/python3.8/site-packages/jnpr/junos/utils/sw.py\", line 975, in install\
add_ok = self.pkgadd(\
File \"/usr/lib/python3.8/site-packages/jnpr/junos/utils/sw.py\", line 242, in pkgadd\
rsp = self.rpc.request_vmhost_package_add(\
File \"/usr/lib/python3.8/site-packages/jnpr/junos/rpcmeta.py\", line 343, in _exec_rpc\
raise TypeError(\
TypeError: The value None for argument member-id is of . Argument values must be a string, boolean, or list/tuple of strings and booleans.\
",
"module_stdout": "",
"msg": "MODULE FAILURE\
See stdout/stderr for the exact error",
"rc": 1
}
There are multiple issue when use ansible PyEz to upgrade the Juniper platform with VMhost based routing-engine.
The fixes are tracked via github. Detailed info can be found below.
PyEZ - Fix is available in 2.7.3 release.
https://github.com/Juniper/py-junos-eznc/issues/1355
Ansible - Planned release is v1.0.8 along with few more other fixes which will be committed by Dinesh.
https://github.com/Juniper/ansible-junos-stdlib/issues/709 - Fixed and merged
https://github.com/Juniper/ansible-junos-stdlib/issues/705 - Issue is not reproducible after the #709 fix