Bug fixes- Dellos modules (#63272)
This commit is contained in:
parent
4745d45711
commit
2e65c1ebb7
10 changed files with 295 additions and 165 deletions
|
@ -29,12 +29,12 @@
|
|||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
import re
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.connection import Connection, ConnectionError, exec_command
|
||||
from ansible.module_utils.network.common.config import NetworkConfig, ConfigLine
|
||||
|
||||
_DEVICE_CONFIGS = {}
|
||||
|
@ -71,6 +71,35 @@ dellos10_top_spec = {
|
|||
dellos10_argument_spec.update(dellos10_top_spec)
|
||||
|
||||
|
||||
def get_provider_argspec():
|
||||
return dellos10_provider_spec
|
||||
|
||||
|
||||
def get_connection(module):
|
||||
if hasattr(module, '_dellos10_connection'):
|
||||
return module._dellos10_connection
|
||||
|
||||
capabilities = get_capabilities(module)
|
||||
network_api = capabilities.get('network_api')
|
||||
if network_api == 'cliconf':
|
||||
module._dellos10_connection = Connection(module._socket_path)
|
||||
else:
|
||||
module.fail_json(msg='Invalid connection type %s' % network_api)
|
||||
|
||||
return module._dellos10_connection
|
||||
|
||||
|
||||
def get_capabilities(module):
|
||||
if hasattr(module, '_dellos10_capabilities'):
|
||||
return module._dellos10_capabilities
|
||||
try:
|
||||
capabilities = Connection(module._socket_path).get_capabilities()
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
|
||||
module._dellos10_capabilities = json.loads(capabilities)
|
||||
return module._dellos10_capabilities
|
||||
|
||||
|
||||
def check_args(module, warnings):
|
||||
pass
|
||||
|
||||
|
@ -78,7 +107,7 @@ def check_args(module, warnings):
|
|||
def get_config(module, flags=None):
|
||||
flags = [] if flags is None else flags
|
||||
|
||||
cmd = 'show running-config '
|
||||
cmd = 'show running-configuration '
|
||||
cmd += ' '.join(flags)
|
||||
cmd = cmd.strip()
|
||||
|
||||
|
@ -93,26 +122,12 @@ def get_config(module, flags=None):
|
|||
return cfg
|
||||
|
||||
|
||||
def to_commands(module, commands):
|
||||
spec = {
|
||||
'command': dict(key=True),
|
||||
'prompt': dict(),
|
||||
'answer': dict()
|
||||
}
|
||||
transform = ComplexList(spec, module)
|
||||
return transform(commands)
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
responses = list()
|
||||
commands = to_commands(module, to_list(commands))
|
||||
for cmd in commands:
|
||||
cmd = module.jsonify(cmd)
|
||||
rc, out, err = exec_command(module, cmd)
|
||||
if check_rc and rc != 0:
|
||||
module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc)
|
||||
responses.append(to_text(out, errors='surrogate_or_strict'))
|
||||
return responses
|
||||
connection = get_connection(module)
|
||||
try:
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
|
||||
|
||||
def load_config(module, commands):
|
||||
|
|
|
@ -30,11 +30,12 @@
|
|||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
import re
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.connection import Connection, ConnectionError, exec_command
|
||||
from ansible.module_utils.network.common.config import NetworkConfig, ConfigLine, ignore_line
|
||||
|
||||
_DEVICE_CONFIGS = {}
|
||||
|
@ -71,6 +72,35 @@ dellos6_top_spec = {
|
|||
dellos6_argument_spec.update(dellos6_top_spec)
|
||||
|
||||
|
||||
def get_provider_argspec():
|
||||
return dellos6_provider_spec
|
||||
|
||||
|
||||
def get_connection(module):
|
||||
if hasattr(module, '_dellos6_connection'):
|
||||
return module._dellos6_connection
|
||||
|
||||
capabilities = get_capabilities(module)
|
||||
network_api = capabilities.get('network_api')
|
||||
if network_api == 'cliconf':
|
||||
module._dellos6_connection = Connection(module._socket_path)
|
||||
else:
|
||||
module.fail_json(msg='Invalid connection type %s' % network_api)
|
||||
|
||||
return module._dellos6_connection
|
||||
|
||||
|
||||
def get_capabilities(module):
|
||||
if hasattr(module, '_dellos6_capabilities'):
|
||||
return module._dellos6_capabilities
|
||||
try:
|
||||
capabilities = Connection(module._socket_path).get_capabilities()
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
|
||||
module._dellos6_capabilities = json.loads(capabilities)
|
||||
return module._dellos6_capabilities
|
||||
|
||||
|
||||
def check_args(module, warnings):
|
||||
pass
|
||||
|
||||
|
@ -93,26 +123,12 @@ def get_config(module, flags=None):
|
|||
return cfg
|
||||
|
||||
|
||||
def to_commands(module, commands):
|
||||
spec = {
|
||||
'command': dict(key=True),
|
||||
'prompt': dict(),
|
||||
'answer': dict()
|
||||
}
|
||||
transform = ComplexList(spec, module)
|
||||
return transform(commands)
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
responses = list()
|
||||
commands = to_commands(module, to_list(commands))
|
||||
for cmd in commands:
|
||||
cmd = module.jsonify(cmd)
|
||||
rc, out, err = exec_command(module, cmd)
|
||||
if check_rc and rc != 0:
|
||||
module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc)
|
||||
responses.append(to_text(out, errors='surrogate_or_strict'))
|
||||
return responses
|
||||
connection = get_connection(module)
|
||||
try:
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
|
||||
|
||||
def load_config(module, commands):
|
||||
|
@ -152,16 +168,16 @@ def os6_parse(lines, indent=None, comment_tokens=None):
|
|||
re.compile(r'datacenter-bridging.*$'),
|
||||
re.compile(r'line (console|telnet|ssh).*$'),
|
||||
re.compile(r'ip ssh !(server).*$'),
|
||||
re.compile(r'(ip|mac|management|arp) access-list.*$'),
|
||||
re.compile(r'ip dhcp pool.*$'),
|
||||
re.compile(r'ip vrf !(forwarding).*$'),
|
||||
re.compile(r'(ip|mac|management|arp) access-list.*$'),
|
||||
re.compile(r'ipv6 (dhcp pool|router).*$'),
|
||||
re.compile(r'mail-server.*$'),
|
||||
re.compile(r'vpc domain.*$'),
|
||||
re.compile(r'router.*$'),
|
||||
re.compile(r'route-map.*$'),
|
||||
re.compile(r'policy-map.*$'),
|
||||
re.compile(r'class-map match-all.*$'),
|
||||
re.compile(r'((class-map match-(all|any))|(class\s)).*$'),
|
||||
re.compile(r'captive-portal.*$'),
|
||||
re.compile(r'admin-profile.*$'),
|
||||
re.compile(r'link-dependency group.*$'),
|
||||
|
@ -172,7 +188,9 @@ def os6_parse(lines, indent=None, comment_tokens=None):
|
|||
re.compile(r'address-family.*$'),
|
||||
re.compile(r'spanning-tree mst configuration.*$'),
|
||||
re.compile(r'logging (?!.*(cli-command|buffered|console|email|facility|file|monitor|protocol|snmp|source-interface|traps|web-session)).*$'),
|
||||
re.compile(r'(radius-server|tacacs-server) host.*$')]
|
||||
re.compile(r'(radius-server|tacacs-server) host.*$'),
|
||||
re.compile(r'radius server (auth|acct).*$'),
|
||||
re.compile(r'aaa server radius dynamic-author.*$')]
|
||||
|
||||
childline = re.compile(r'^exit$')
|
||||
config = list()
|
||||
|
@ -184,8 +202,6 @@ def os6_parse(lines, indent=None, comment_tokens=None):
|
|||
cfg = ConfigLine(text)
|
||||
cfg.raw = line
|
||||
if not text or ignore_line(text, comment_tokens):
|
||||
parent = list()
|
||||
children = []
|
||||
continue
|
||||
|
||||
else:
|
||||
|
|
|
@ -29,12 +29,12 @@
|
|||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
import re
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.connection import Connection, ConnectionError, exec_command
|
||||
from ansible.module_utils.network.common.config import NetworkConfig, ConfigLine
|
||||
|
||||
_DEVICE_CONFIGS = {}
|
||||
|
@ -71,6 +71,35 @@ dellos9_top_spec = {
|
|||
dellos9_argument_spec.update(dellos9_top_spec)
|
||||
|
||||
|
||||
def get_provider_argspec():
|
||||
return dellos9_provider_spec
|
||||
|
||||
|
||||
def get_connection(module):
|
||||
if hasattr(module, '_dellos9_connection'):
|
||||
return module._dellos9_connection
|
||||
|
||||
capabilities = get_capabilities(module)
|
||||
network_api = capabilities.get('network_api')
|
||||
if network_api == 'cliconf':
|
||||
module._dellos9_connection = Connection(module._socket_path)
|
||||
else:
|
||||
module.fail_json(msg='Invalid connection type %s' % network_api)
|
||||
|
||||
return module._dellos9_connection
|
||||
|
||||
|
||||
def get_capabilities(module):
|
||||
if hasattr(module, '_dellos9_capabilities'):
|
||||
return module._dellos9_capabilities
|
||||
try:
|
||||
capabilities = Connection(module._socket_path).get_capabilities()
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
|
||||
module._dellos9_capabilities = json.loads(capabilities)
|
||||
return module._dellos9_capabilities
|
||||
|
||||
|
||||
def check_args(module, warnings):
|
||||
pass
|
||||
|
||||
|
@ -93,26 +122,12 @@ def get_config(module, flags=None):
|
|||
return cfg
|
||||
|
||||
|
||||
def to_commands(module, commands):
|
||||
spec = {
|
||||
'command': dict(key=True),
|
||||
'prompt': dict(),
|
||||
'answer': dict()
|
||||
}
|
||||
transform = ComplexList(spec, module)
|
||||
return transform(commands)
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
responses = list()
|
||||
commands = to_commands(module, to_list(commands))
|
||||
for cmd in commands:
|
||||
cmd = module.jsonify(cmd)
|
||||
rc, out, err = exec_command(module, cmd)
|
||||
if check_rc and rc != 0:
|
||||
module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc)
|
||||
responses.append(to_text(out, errors='surrogate_or_strict'))
|
||||
return responses
|
||||
connection = get_connection(module)
|
||||
try:
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
|
||||
|
||||
def load_config(module, commands):
|
||||
|
|
|
@ -35,7 +35,11 @@ options:
|
|||
configured provider. The resulting output from the command
|
||||
is returned. If the I(wait_for) argument is provided, the
|
||||
module is not returned until the condition is satisfied or
|
||||
the number of retries has expired.
|
||||
the number of retries has expired. If a command sent to the
|
||||
device requires answering a prompt, it is possible to pass
|
||||
a dict containing I(command), I(answer) and I(prompt).
|
||||
Common answers are 'yes' or "\\r" (carriage return, must be
|
||||
double quotes). See examples.
|
||||
type: list
|
||||
required: true
|
||||
wait_for:
|
||||
|
@ -43,7 +47,7 @@ options:
|
|||
- List of conditions to evaluate against the output of the
|
||||
command. The task will wait for each condition to be true
|
||||
before moving forward. If the conditional is not true
|
||||
within the configured number of I(retries), the task fails.
|
||||
within the configured number of retries, the task fails.
|
||||
See examples.
|
||||
type: list
|
||||
version_added: "2.2"
|
||||
|
@ -57,7 +61,7 @@ options:
|
|||
satisfied.
|
||||
type: str
|
||||
default: all
|
||||
choices: [ all, any ]
|
||||
choices: [ 'all', 'any' ]
|
||||
version_added: "2.5"
|
||||
retries:
|
||||
description:
|
||||
|
@ -102,6 +106,13 @@ tasks:
|
|||
wait_for:
|
||||
- result[0] contains OS10
|
||||
- result[1] contains Ethernet
|
||||
|
||||
- name: run commands that require answering a prompt
|
||||
dellos10_command:
|
||||
commands:
|
||||
- command: 'reload'
|
||||
prompt: '[confirm yes/no]: ?$'
|
||||
answer: 'no'
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -128,39 +139,26 @@ warnings:
|
|||
"""
|
||||
import time
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.network.common.utils import transform_commands, to_lines
|
||||
from ansible.module_utils.network.dellos10.dellos10 import run_commands
|
||||
from ansible.module_utils.network.dellos10.dellos10 import dellos10_argument_spec, check_args
|
||||
from ansible.module_utils.network.common.utils import ComplexList
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
|
||||
def to_lines(stdout):
|
||||
for item in stdout:
|
||||
if isinstance(item, string_types):
|
||||
item = str(item).split('\n')
|
||||
yield item
|
||||
|
||||
|
||||
def parse_commands(module, warnings):
|
||||
command = ComplexList(dict(
|
||||
command=dict(key=True),
|
||||
prompt=dict(),
|
||||
answer=dict()
|
||||
), module)
|
||||
commands = command(module.params['commands'])
|
||||
for index, item in enumerate(commands):
|
||||
if module.check_mode and not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'only show commands are supported when using check mode, not '
|
||||
'executing `%s`' % item['command']
|
||||
)
|
||||
elif item['command'].startswith('conf'):
|
||||
module.fail_json(
|
||||
msg='dellos10_command does not support running config mode '
|
||||
'commands. Please use dellos10_config instead'
|
||||
)
|
||||
commands = transform_commands(module)
|
||||
|
||||
if module.check_mode:
|
||||
for item in list(commands):
|
||||
if not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'Only show commands are supported when using check mode, not '
|
||||
'executing %s' % item['command']
|
||||
)
|
||||
commands.remove(item)
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
|
@ -191,8 +189,11 @@ def main():
|
|||
result['warnings'] = warnings
|
||||
|
||||
wait_for = module.params['wait_for'] or list()
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
|
||||
try:
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
except AttributeError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
retries = module.params['retries']
|
||||
interval = module.params['interval']
|
||||
match = module.params['match']
|
||||
|
@ -219,7 +220,6 @@ def main():
|
|||
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
||||
|
||||
result.update({
|
||||
'changed': False,
|
||||
'stdout': responses,
|
||||
'stdout_lines': list(to_lines(responses))
|
||||
})
|
||||
|
|
|
@ -34,7 +34,11 @@ options:
|
|||
configured provider. The resulting output from the command
|
||||
is returned. If the I(wait_for) argument is provided, the
|
||||
module is not returned until the condition is satisfied or
|
||||
the number of retries has expired.
|
||||
the number of retries has expired. If a command sent to the
|
||||
device requires answering a prompt, it is possible to pass
|
||||
a dict containing I(command), I(answer) and I(prompt).
|
||||
Common answers are 'yes' or "\\r" (carriage return, must be
|
||||
double quotes). See examples.
|
||||
type: list
|
||||
required: true
|
||||
wait_for:
|
||||
|
@ -42,7 +46,7 @@ options:
|
|||
- List of conditions to evaluate against the output of the
|
||||
command. The task will wait for each condition to be true
|
||||
before moving forward. If the conditional is not true
|
||||
within the configured number of I(retries), the task fails.
|
||||
within the configured number of retries, the task fails.
|
||||
See examples.
|
||||
type: list
|
||||
version_added: "2.2"
|
||||
|
@ -56,7 +60,7 @@ options:
|
|||
satisfied.
|
||||
type: str
|
||||
default: all
|
||||
choices: [ all, any ]
|
||||
choices: [ 'all', 'any' ]
|
||||
version_added: "2.5"
|
||||
retries:
|
||||
description:
|
||||
|
@ -101,6 +105,13 @@ tasks:
|
|||
wait_for:
|
||||
- result[0] contains Dell
|
||||
- result[1] contains Access
|
||||
|
||||
- name: run commands that require answering a prompt
|
||||
dellos6_command:
|
||||
commands:
|
||||
- command: 'copy running-config startup-config'
|
||||
prompt: '[confirm yes/no]: ?$'
|
||||
answer: 'yes'
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -128,39 +139,26 @@ warnings:
|
|||
|
||||
import time
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.network.common.utils import transform_commands, to_lines
|
||||
from ansible.module_utils.network.dellos6.dellos6 import run_commands
|
||||
from ansible.module_utils.network.dellos6.dellos6 import dellos6_argument_spec, check_args
|
||||
from ansible.module_utils.network.common.utils import ComplexList
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
|
||||
def to_lines(stdout):
|
||||
for item in stdout:
|
||||
if isinstance(item, string_types):
|
||||
item = str(item).split('\n')
|
||||
yield item
|
||||
|
||||
|
||||
def parse_commands(module, warnings):
|
||||
command = ComplexList(dict(
|
||||
command=dict(key=True),
|
||||
prompt=dict(),
|
||||
answer=dict()
|
||||
), module)
|
||||
commands = command(module.params['commands'])
|
||||
for index, item in enumerate(commands):
|
||||
if module.check_mode and not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'only show commands are supported when using check mode, not '
|
||||
'executing `%s`' % item['command']
|
||||
)
|
||||
elif item['command'].startswith('conf'):
|
||||
module.fail_json(
|
||||
msg='dellos6_command does not support running config mode '
|
||||
'commands. Please use dellos6_config instead'
|
||||
)
|
||||
commands = transform_commands(module)
|
||||
|
||||
if module.check_mode:
|
||||
for item in list(commands):
|
||||
if not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'Only show commands are supported when using check mode, not '
|
||||
'executing %s' % item['command']
|
||||
)
|
||||
commands.remove(item)
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
|
@ -190,8 +188,11 @@ def main():
|
|||
result['warnings'] = warnings
|
||||
|
||||
wait_for = module.params['wait_for'] or list()
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
|
||||
try:
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
except AttributeError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
retries = module.params['retries']
|
||||
interval = module.params['interval']
|
||||
match = module.params['match']
|
||||
|
@ -218,7 +219,6 @@ def main():
|
|||
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
||||
|
||||
result.update({
|
||||
'changed': False,
|
||||
'stdout': responses,
|
||||
'stdout_lines': list(to_lines(responses))
|
||||
})
|
||||
|
|
|
@ -35,7 +35,11 @@ options:
|
|||
configured provider. The resulting output from the command
|
||||
is returned. If the I(wait_for) argument is provided, the
|
||||
module is not returned until the condition is satisfied or
|
||||
the number of retries has expired.
|
||||
the number of retries has expired. If a command sent to the
|
||||
device requires answering a prompt, it is possible to pass
|
||||
a dict containing I(command), I(answer) and I(prompt).
|
||||
Common answers are 'yes' or "\\r" (carriage return, must be
|
||||
double quotes). See examples.
|
||||
type: list
|
||||
required: true
|
||||
wait_for:
|
||||
|
@ -43,7 +47,7 @@ options:
|
|||
- List of conditions to evaluate against the output of the
|
||||
command. The task will wait for each condition to be true
|
||||
before moving forward. If the conditional is not true
|
||||
within the configured number of I(retries), the task fails.
|
||||
within the configured number of retries, the task fails.
|
||||
See examples.
|
||||
type: list
|
||||
version_added: "2.2"
|
||||
|
@ -57,7 +61,7 @@ options:
|
|||
satisfied.
|
||||
type: str
|
||||
default: all
|
||||
choices: [ all, any ]
|
||||
choices: [ 'all', 'any' ]
|
||||
version_added: "2.5"
|
||||
retries:
|
||||
description:
|
||||
|
@ -111,6 +115,13 @@ tasks:
|
|||
wait_for:
|
||||
- result[0] contains OS9
|
||||
- result[1] contains Loopback
|
||||
|
||||
- name: run commands that require answering a prompt
|
||||
dellos9_command:
|
||||
commands:
|
||||
- command: 'copy running-config startup-config'
|
||||
prompt: '[confirm yes/no]: ?$'
|
||||
answer: 'yes'
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -137,39 +148,26 @@ warnings:
|
|||
"""
|
||||
import time
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.network.common.utils import transform_commands, to_lines
|
||||
from ansible.module_utils.network.dellos9.dellos9 import run_commands
|
||||
from ansible.module_utils.network.dellos9.dellos9 import dellos9_argument_spec, check_args
|
||||
from ansible.module_utils.network.common.utils import ComplexList
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
|
||||
def to_lines(stdout):
|
||||
for item in stdout:
|
||||
if isinstance(item, string_types):
|
||||
item = str(item).split('\n')
|
||||
yield item
|
||||
|
||||
|
||||
def parse_commands(module, warnings):
|
||||
command = ComplexList(dict(
|
||||
command=dict(key=True),
|
||||
prompt=dict(),
|
||||
answer=dict()
|
||||
), module)
|
||||
commands = command(module.params['commands'])
|
||||
for index, item in enumerate(commands):
|
||||
if module.check_mode and not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'only show commands are supported when using check mode, not '
|
||||
'executing `%s`' % item['command']
|
||||
)
|
||||
elif item['command'].startswith('conf'):
|
||||
module.fail_json(
|
||||
msg='dellos9_command does not support running config mode '
|
||||
'commands. Please use dellos9_config instead'
|
||||
)
|
||||
commands = transform_commands(module)
|
||||
|
||||
if module.check_mode:
|
||||
for item in list(commands):
|
||||
if not item['command'].startswith('show'):
|
||||
warnings.append(
|
||||
'Only show commands are supported when using check mode, not '
|
||||
'executing %s' % item['command']
|
||||
)
|
||||
commands.remove(item)
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
|
@ -200,8 +198,11 @@ def main():
|
|||
result['warnings'] = warnings
|
||||
|
||||
wait_for = module.params['wait_for'] or list()
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
|
||||
try:
|
||||
conditionals = [Conditional(c) for c in wait_for]
|
||||
except AttributeError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
retries = module.params['retries']
|
||||
interval = module.params['interval']
|
||||
match = module.params['match']
|
||||
|
@ -228,7 +229,6 @@ def main():
|
|||
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
||||
|
||||
result.update({
|
||||
'changed': False,
|
||||
'stdout': responses,
|
||||
'stdout_lines': list(to_lines(responses))
|
||||
})
|
||||
|
|
|
@ -36,7 +36,9 @@ import json
|
|||
|
||||
from itertools import chain
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
from ansible.module_utils.network.common.utils import to_list
|
||||
from ansible.plugins.cliconf import CliconfBase, enable_mode
|
||||
|
||||
|
@ -87,3 +89,27 @@ class Cliconf(CliconfBase):
|
|||
def get_capabilities(self):
|
||||
result = super(Cliconf, self).get_capabilities()
|
||||
return json.dumps(result)
|
||||
|
||||
def run_commands(self, commands=None, check_rc=True):
|
||||
if commands is None:
|
||||
raise ValueError("'commands' value is required")
|
||||
|
||||
responses = list()
|
||||
for cmd in to_list(commands):
|
||||
if not isinstance(cmd, Mapping):
|
||||
cmd = {'command': cmd}
|
||||
|
||||
output = cmd.pop('output', None)
|
||||
if output:
|
||||
raise ValueError("'output' value %s is not supported for run_commands" % output)
|
||||
|
||||
try:
|
||||
out = self.send_command(**cmd)
|
||||
except AnsibleConnectionFailure as e:
|
||||
if check_rc:
|
||||
raise
|
||||
out = getattr(e, 'err', to_text(e))
|
||||
|
||||
responses.append(out)
|
||||
|
||||
return responses
|
||||
|
|
|
@ -36,7 +36,9 @@ import json
|
|||
|
||||
from itertools import chain
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
from ansible.module_utils.network.common.utils import to_list
|
||||
from ansible.plugins.cliconf import CliconfBase, enable_mode
|
||||
|
||||
|
@ -58,7 +60,7 @@ class Cliconf(CliconfBase):
|
|||
if match:
|
||||
device_info['network_os_model'] = match.group(1)
|
||||
|
||||
reply = self.get('show running-config | grep hostname')
|
||||
reply = self.get('show running-config | include hostname')
|
||||
data = to_text(reply, errors='surrogate_or_strict').strip()
|
||||
match = re.search(r'^hostname (.+)', data, re.M)
|
||||
if match:
|
||||
|
@ -87,3 +89,27 @@ class Cliconf(CliconfBase):
|
|||
def get_capabilities(self):
|
||||
result = super(Cliconf, self).get_capabilities()
|
||||
return json.dumps(result)
|
||||
|
||||
def run_commands(self, commands=None, check_rc=True):
|
||||
if commands is None:
|
||||
raise ValueError("'commands' value is required")
|
||||
|
||||
responses = list()
|
||||
for cmd in to_list(commands):
|
||||
if not isinstance(cmd, Mapping):
|
||||
cmd = {'command': cmd}
|
||||
|
||||
output = cmd.pop('output', None)
|
||||
if output:
|
||||
raise ValueError("'output' value %s is not supported for run_commands" % output)
|
||||
|
||||
try:
|
||||
out = self.send_command(**cmd)
|
||||
except AnsibleConnectionFailure as e:
|
||||
if check_rc:
|
||||
raise
|
||||
out = getattr(e, 'err', to_text(e))
|
||||
|
||||
responses.append(out)
|
||||
|
||||
return responses
|
||||
|
|
|
@ -36,7 +36,9 @@ import json
|
|||
|
||||
from itertools import chain
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
from ansible.module_utils.network.common.utils import to_list
|
||||
from ansible.plugins.cliconf import CliconfBase, enable_mode
|
||||
|
||||
|
@ -87,3 +89,27 @@ class Cliconf(CliconfBase):
|
|||
def get_capabilities(self):
|
||||
result = super(Cliconf, self).get_capabilities()
|
||||
return json.dumps(result)
|
||||
|
||||
def run_commands(self, commands=None, check_rc=True):
|
||||
if commands is None:
|
||||
raise ValueError("'commands' value is required")
|
||||
|
||||
responses = list()
|
||||
for cmd in to_list(commands):
|
||||
if not isinstance(cmd, Mapping):
|
||||
cmd = {'command': cmd}
|
||||
|
||||
output = cmd.pop('output', None)
|
||||
if output:
|
||||
raise ValueError("'output' value %s is not supported for run_commands" % output)
|
||||
|
||||
try:
|
||||
out = self.send_command(**cmd)
|
||||
except AnsibleConnectionFailure as e:
|
||||
if check_rc:
|
||||
raise
|
||||
out = getattr(e, 'err', to_text(e))
|
||||
|
||||
responses.append(out)
|
||||
|
||||
return responses
|
||||
|
|
|
@ -55,6 +55,12 @@ class TerminalModule(TerminalBase):
|
|||
|
||||
terminal_inital_prompt_newline = False
|
||||
|
||||
def on_open_shell(self):
|
||||
try:
|
||||
self._exec_cli_command(b'terminal length 0')
|
||||
except AnsibleConnectionFailure:
|
||||
raise AnsibleConnectionFailure('unable to set terminal parameters')
|
||||
|
||||
def on_become(self, passwd=None):
|
||||
if self._get_prompt().endswith(b'#'):
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue