nxos enable mode (#39355)

* nxos enable mode

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* fix prompt

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* Add authorize,auth_pass

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* remove byte string from exec_cli_command

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* Add on_become test

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* removed_in_version

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>
This commit is contained in:
Trishna Guha 2018-05-08 15:31:02 +05:30 committed by GitHub
parent 83df7249fd
commit f08332acb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 162 additions and 1 deletions

View file

@ -49,6 +49,9 @@ nxos_provider_spec = {
'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True),
'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE'])),
'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
'auth_pass': dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS'])),
'use_ssl': dict(type='bool'),
'use_proxy': dict(default=True, type='bool'),
'validate_certs': dict(type='bool'),
@ -68,6 +71,9 @@ nxos_top_spec = {
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9),
'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
'auth_pass': dict(removed_in_version=2.9, no_log=True),
'use_ssl': dict(removed_in_version=2.9, type='bool'),
'validate_certs': dict(removed_in_version=2.9, type='bool'),
'timeout': dict(removed_in_version=2.9, type='int'),

View file

@ -63,6 +63,10 @@ class ActionModule(_ActionModule):
pc.password = provider['password'] or self._play_context.password
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
pc.become = provider['authorize'] or False
if pc.become:
pc.become_method = 'enable'
pc.become_pass = provider['auth_pass']
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)

View file

@ -20,9 +20,11 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import re
import json
from ansible.plugins.terminal import TerminalBase
from ansible.errors import AnsibleConnectionFailure
from ansible.module_utils._text import to_bytes, to_text
class TerminalModule(TerminalBase):
@ -48,9 +50,50 @@ class TerminalModule(TerminalBase):
re.compile(br"invalid (.+?)at '\^' marker", re.I)
]
def on_become(self, passwd=None):
if self._get_prompt().endswith(b'enable#'):
return
out = self._exec_cli_command('show privilege')
out = to_text(out, errors='surrogate_then_replace').strip()
if 'Disabled' in out:
raise AnsibleConnectionFailure('Feature privilege is not enabled')
# if already at privilege level 15 return
if '15' in out:
return
cmd = {u'command': u'enable'}
if passwd:
cmd[u'prompt'] = to_text(r"(?i)[\r\n]?Password: $", errors='surrogate_or_strict')
cmd[u'answer'] = passwd
cmd[u'prompt_retry_check'] = True
try:
self._exec_cli_command(to_bytes(json.dumps(cmd), errors='surrogate_or_strict'))
prompt = self._get_prompt()
if prompt is None or not prompt.strip().endswith(b'enable#'):
raise AnsibleConnectionFailure('failed to elevate privilege to enable mode still at prompt [%s]' % prompt)
except AnsibleConnectionFailure as e:
prompt = self._get_prompt()
raise AnsibleConnectionFailure('unable to elevate privilege to enable mode, at prompt [%s] with error: %s' % (prompt, e.message))
def on_unbecome(self):
prompt = self._get_prompt()
if prompt is None:
# if prompt is None most likely the terminal is hung up at a prompt
return
if b'(config' in prompt:
self._exec_cli_command('end')
self._exec_cli_command('exit')
elif prompt.endswith(b'enable#'):
self._exec_cli_command('exit')
def on_open_shell(self):
try:
for cmd in (b'terminal length 0', b'terminal width 511'):
for cmd in ('terminal length 0', 'terminal width 511'):
self._exec_cli_command(cmd)
except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to set terminal parameters')

View file

@ -0,0 +1,3 @@
---
testcase: "*"
test_items: []

View file

@ -0,0 +1,2 @@
dependencies:
- prepare_nxos_tests

View file

@ -0,0 +1,33 @@
---
- name: collect common cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
connection: local
register: test_cases
- name: collect cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
connection: local
register: cli_cases
- set_fact:
test_cases:
files: "{{ test_cases.files }} + {{ cli_cases.files }}"
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli connection={}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: run test case (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local connection={{ cli }}"
with_first_found: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

@ -0,0 +1,3 @@
---
- { include: cli.yaml, tags: ['cli'] }
#- { include: nxapi.yaml, tags: ['nxapi'] }

View file

@ -0,0 +1,27 @@
---
- name: collect common nxapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
connection: local
register: test_cases
- name: collect nxapi test cases
find:
paths: "{{ role_path }}/tests/nxapi"
patterns: "{{ testcase }}.yaml"
connection: local
register: nxapi_cases
- set_fact:
test_cases:
files: "{{ test_cases.files }} + {{ nxapi_cases.files }}"
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local connection={{ nxapi }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

@ -0,0 +1,39 @@
---
- debug: msg="START connection={{ ansible_connection }}/sanity.yaml"
- debug: msg="Using provider={{ connection.transport }}/sanity.yaml"
when: ansible_connection == "local"
- block:
- name: update role to priv-14
nxos_config:
lines:
- username admin role priv-14
- no username admin role priv-15
- enable secret 0 cisco
provider: "{{ cli }}"
- name: reset_connection
meta: reset_connection
- name: run commands with become
nxos_command:
commands: 'show privilege'
provider: "{{ cli }}"
become: yes
register: result
- assert:
that:
- "'Current privilege level: 15' in result['stdout'][0]"
always:
- name: teardown
nxos_config:
lines:
- username admin role priv-15
- no username admin role priv-14
- no enable secret
provider: "{{ cli }}"
ignore_errors: yes
- debug: msg="END connection={{ ansible_connection }}/sanity.yaml"

View file

@ -3,6 +3,7 @@
nxos_config:
lines:
- feature nxapi
- feature privilege
connection: network_cli
ignore_errors: yes