Optional Args Not working for Arista
derfUrban opened this issue · 5 comments
When attempting to push a config to Arista using napalm_install_config the subsystem fails to recognize the optional_args being passed.
According to the readthedocs entry here, https://media.readthedocs.org/pdf/napalmsdf/latest/napalmsdf.pdf, there is a list of optional args expected and on page 36 it says we can add to them but it isn't clear where the model exists to add the optional args needed for our use case.
In either case I lack the confidence that the subsystem will operate as needed if the model is updated accordingly. Please advise.
Below is sample yaml
- name: Load configuration into the device and diff
napalm_install_config:
hostname: "{{ ansible_host }}"
username: test_user
dev_os: "{{ ansible_os_family }}"
optional_args:
commit_session: "{{ ansible_host }}"
commit: True
commit_timer: 00:02:00
commit_comments: "word"
password: test_password
config_file: "{{ config_file_name }}"
commit_changeas: True
replace_config: False
get_diffs: False
diff_file: "{{ ansible_os_family }}.{{ state }}.conf.diff"
when: has_pending_config == false
tags: [print_action]`
Below is output error s you can see optional_args is null
fatal: [arista7508e.cvr]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_args": {"archive_file": null, "candidate_file": null, "commit_changes": false, "config": null, "config_file": "/arista7508e.cvr.eos.present.conf", "dev_os": "eos", "diff_file": "/arista7508e.cvr.eos.present.conf.diff", "get_diffs": true, "hostname": "arista7508e.cvr.d0cdn.net", "optional_args": null, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "provider": null, "replace_config": false, "timeout": 60, "username": "fjone"}, "module_name": "napalm_install_config"}, "msg": "cannot load config: Error [1002]: CLI command 3 of 4510 'commit timer ' failed: invalid command [incomplete command (at token 2: None)]"}
I can manually edit the eos.py class however we want dynamic variable input rather than static.
Optional args need to be supported by the corresponding napalm drivers. So in order for those to work you'd need to implement them first here.
I am closing this issue as it's not related to napalm-ansible
. Feel free to open a PR in napalm
or open an issue there for discussion.
This response is a bit confusing as the eos drivers appears to support the optional args parameter unless I am missing something.
So adding this in my playbook...
- name: Load configuration into the device and diff
napalm_install_config:
hostname: "{{ ansible_host }}"
username: fjone
dev_os: "{{ ansible_os_family }}"
optional_args:
commit_session: "{{ ansible_host }}"
commit_pending: True
commit_timer: 00:02:00
commit_comments: "word"
password: test123
config_file: "{{ config_file_name }}"
commit_changeas: True
replace_config: False
get_diffs: False
diff_file: "{{ path }}/{{ hostname }}.conf.diff"
when: has_pending_config == false
tags: [print_action]
Add this to eos.py
` def init(self, hostname, username, password, comments, timeout=60, optional_args=None):
"""Constructor."""
self.device = None
self.hostname = hostname
self.username = username
self.password = password
self.timeout = timeout
self.config_session = None
self.commit_timer = None
self.comments = None
self.locked = False
if optional_args is None:
optional_args = {}
# eos_transport is there for backwards compatibility, transport is the preferred method
self.transport = optional_args.get('transport', optional_args.get('eos_transport', 'https'))
self.config_session = 'napalm_{}'.format(optional_args.get('commit_session', 'Testing Session Commit'))
self.commit_timer = optional_args.get('commit_timer', '00:05:00')
self.comments = optional_args.get('commit_comments', 'Testing comments')
self.commit_pending = optional_args.get('commit_pending', 'Testing comments')`
And it produces null optional_args as displayed above.
So either ansible is passing null to napalm_ansible or na is passing null to eos.py but somewhere optional_args isn't making it to the code I've implemented.
Digging deeper into the code I see in napalm_install_config is instantiating the optional args object to Ansible module
module = AnsibleModule( argument_spec=dict( hostname=dict(type='str', required=False, aliases=['host']), username=dict(type='str', required=False), password=dict(type='str', required=False, no_log=True), provider=dict(type='dict', required=False), timeout=dict(type='int', required=False, default=60), optional_args=dict(required=False, type='dict', default=None), config_file=dict(type='str', required=False), config=dict(type='str', required=False), dev_os=dict(type='str', required=False), commit_changes=dict(type='bool', required=True), replace_config=dict(type='bool', required=False, default=False), diff_file=dict(type='str', required=False, default=None), get_diffs=dict(type='bool', required=False, default=True), archive_file=dict(type='str', required=False, default=None), candidate_file=dict(type='str', required=False, default=None) ), supports_check_mode=True
Then this code digging deep in and instantiating the the network driver object with the eos class.
` if module.params['optional_args'] is None:
optional_args = {}
else:
optional_args = module.params['optional_args']
try:
network_driver = get_network_driver(dev_os)
except ModuleImportError as e:
module.fail_json(msg="Failed to import napalm driver: " + str(e))`
So I added this code to check what this is actually doing...
` #ToDO FWJ_NET_719 I believe variable scope is eating the optional args here
if module.params['optional_args'] is None:
optional_args = {}
save_to_file('No optional args', '/tmp/option_args/no_args.txt')
else:
save_to_file(module.params['optional_args'], '/tmp/option_args/no_args.txt')
optional_args = module.params['optional_args']
save_to_file(optional_args, '/tmp/option_args/no_args.txt')`
And the output of that file is...
[Tue Oct 02 21:53:25] fjones@nae501.lc:/nae/bin$ cat /tmp/option_args/no_args.txt/nae/bin$ vi ../nae/library/napalm_ansible/modules/napalm_install_config.py
No optional args[Tue Oct 02 21:53:36] fjones@nae501.dle.lc4:
[Tue Oct 02 21:54:56] fjones@nae501.lc:~/nae/bin$
And the output of that execution is...
fatal: [arista7508e.cvr]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_args": {"archive_file": null, "candidate_file": null, "commit_changes": false, "config": null, "config_file": "/aristae.cvr.eos.present.conf", "dev_os": "eos", "diff_file": "/aristae.cvr.eos.present.conf.diff", "get_diffs": true, "hostname": "aristae.cvr.d0cdn.net", "optional_args": null, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "provider": null, "replace_config": false, "timeout": 60, "username": "fjone"}, "module_name": "napalm_install_config"},
So again even though I have edited the eos.py driver and made my playbook role with the optional_args it is not being passed accordingly so please reopen this issue or advise where I need to go to get this resolved.
Here is a simple example, I just ran in my lab:
---
- name: Test optional_args
hosts: nxos
tasks:
- name: Verify IP interface
napalm_get_facts:
hostname: "{{ ansible_host }}"
username: "{{ ansible_user }}"
password: "{{ ansible_ssh_pass }}"
dev_os: "nxos"
optional_args:
port: 8443
filter: "interfaces_ip"
Which runs correct and debugging shows this (only included relevant section)
"invocation": {
"module_args": {
"args": null,
"dev_os": "nxos",
"filter": [
"interfaces_ip"
],
"hostname": "nxos1.domain.com",
"ignore_notimplemented": false,
"optional_args": {
"port": 8443
},
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"provider": {
"hostname": "nxos1.domain.com",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"timeout": 60,
"username": "admin"
},
"timeout": 60,
"username": "admin"
}
}
So everything I see indicates that napalm-ansible is running correctly. My guess is that you are doing something wrong on the Ansible side.
For grins, I added an arbitrary argument to optional_args:
optional_args:
port: 8443
foo: bar
This also showed up in the invocation arguments. This was using Ansible 2.6.5