mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
First implementation of 'fallback' parameter
Implemented & documented for EOS & NXOS
This commit is contained in:
parent
2e55b3567b
commit
dbc49ad95b
5 changed files with 68 additions and 33 deletions
|
@ -516,6 +516,18 @@ def is_executable(path):
|
|||
or stat.S_IXOTH & os.stat(path)[stat.ST_MODE])
|
||||
|
||||
|
||||
class AnsibleFallbackNotFound(Exception):
|
||||
pass
|
||||
|
||||
def env_fallback(*args, **kwargs):
|
||||
''' Load value from environment '''
|
||||
for arg in args:
|
||||
if arg in os.environ:
|
||||
return os.environ[arg]
|
||||
else:
|
||||
raise AnsibleFallbackNotFound
|
||||
|
||||
|
||||
class AnsibleModule(object):
|
||||
def __init__(self, argument_spec, bypass_checks=False, no_log=False,
|
||||
check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
|
||||
|
@ -550,6 +562,7 @@ class AnsibleModule(object):
|
|||
|
||||
self._load_constants()
|
||||
self._load_params()
|
||||
self._set_fallbacks()
|
||||
|
||||
# append to legal_inputs and then possibly check against them
|
||||
try:
|
||||
|
@ -1421,6 +1434,23 @@ class AnsibleModule(object):
|
|||
if k not in self.params:
|
||||
self.params[k] = default
|
||||
|
||||
def _set_fallbacks(self):
|
||||
for k,v in self.argument_spec.items():
|
||||
fallback = v.get('fallback', (None,))
|
||||
fallback_strategy = fallback[0]
|
||||
fallback_args = []
|
||||
fallback_kwargs = {}
|
||||
if k not in self.params and fallback_strategy is not None:
|
||||
for item in fallback[1:]:
|
||||
if isinstance(item, dict):
|
||||
fallback_kwargs = item
|
||||
else:
|
||||
fallback_args = item
|
||||
try:
|
||||
self.params[k] = fallback_strategy(*fallback_args, **fallback_kwargs)
|
||||
except AnsibleFallbackNotFound:
|
||||
continue
|
||||
|
||||
def _load_params(self):
|
||||
''' read the input and set the params attribute'''
|
||||
if MODULE_COMPLEX_ARGS is None:
|
||||
|
|
|
@ -20,7 +20,7 @@ import os
|
|||
|
||||
import re
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.basic import AnsibleModule, env_fallback
|
||||
from ansible.module_utils.shell import Shell, Command, HAS_PARAMIKO
|
||||
from ansible.module_utils.netcfg import parse
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
|
@ -30,24 +30,16 @@ NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I)
|
|||
NET_COMMON_ARGS = dict(
|
||||
host=dict(required=True),
|
||||
port=dict(type='int'),
|
||||
username=dict(required=True),
|
||||
password=dict(no_log=True),
|
||||
ssh_keyfile=dict(type='path'),
|
||||
authorize=dict(default=False, type='bool'),
|
||||
auth_pass=dict(no_log=True),
|
||||
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||
password=dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD'])),
|
||||
ssh_keyfile=dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'),
|
||||
authorize=dict(default=False, fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
|
||||
auth_pass=dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS'])),
|
||||
transport=dict(default='cli', choices=['cli', 'eapi']),
|
||||
use_ssl=dict(default=True, type='bool'),
|
||||
provider=dict(type='dict')
|
||||
)
|
||||
|
||||
NET_ENV_ARGS = dict(
|
||||
username='ANSIBLE_NET_USERNAME',
|
||||
password='ANSIBLE_NET_PASSWORD',
|
||||
ssh_keyfile='ANSIBLE_NET_SSH_KEYFILE',
|
||||
authorize='ANSIBLE_NET_AUTHORIZE',
|
||||
auth_pass='ANSIBLE_NET_AUTH_PASS',
|
||||
)
|
||||
|
||||
CLI_PROMPTS_RE = [
|
||||
re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"),
|
||||
re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$")
|
||||
|
@ -200,9 +192,6 @@ class NetworkModule(AnsibleModule):
|
|||
if key in NET_COMMON_ARGS:
|
||||
if self.params.get(key) is None and value is not None:
|
||||
self.params[key] = value
|
||||
for key, env_var in NET_ENV_ARGS.items():
|
||||
if self.params.get(key) is None and env_var in os.environ:
|
||||
self.params[key] = os.environ[env_var]
|
||||
|
||||
def connect(self):
|
||||
try:
|
||||
|
|
|
@ -21,7 +21,7 @@ import re
|
|||
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils.shell import Shell, HAS_PARAMIKO
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.basic import AnsibleModule, env_fallback
|
||||
from ansible.module_utils.netcfg import parse
|
||||
|
||||
NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I)
|
||||
|
@ -29,8 +29,9 @@ NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I)
|
|||
NET_COMMON_ARGS = dict(
|
||||
host=dict(required=True),
|
||||
port=dict(type='int'),
|
||||
username=dict(required=True),
|
||||
password=dict(no_log=True),
|
||||
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||
password=dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD'])),
|
||||
ssh_keyfile=dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'),
|
||||
transport=dict(default='cli', choices=['cli', 'nxapi']),
|
||||
use_ssl=dict(default=False, type='bool'),
|
||||
validate_certs=dict(default=True, type='bool'),
|
||||
|
@ -165,11 +166,11 @@ class Cli(object):
|
|||
|
||||
username = self.module.params['username']
|
||||
password = self.module.params['password']
|
||||
key_filename = self.module.params['ssh_keyfile']
|
||||
|
||||
try:
|
||||
self.shell = Shell(prompts_re=CLI_PROMPTS_RE, errors_re=CLI_ERRORS_RE,
|
||||
kickstart=False)
|
||||
self.shell.open(host, port=port, username=username, password=password)
|
||||
self.shell = Shell(prompts_re=CLI_PROMPTS_RE, errors_re=CLI_ERRORS_RE, kickstart=False)
|
||||
self.shell.open(host, port=port, username=username, password=password, key_filename=key_filename)
|
||||
except Exception, exc:
|
||||
msg = 'failed to connect to %s:%s - %s' % (host, port, str(exc))
|
||||
self.module.fail_json(msg=msg)
|
||||
|
|
|
@ -41,26 +41,31 @@ options:
|
|||
- Configures the usename to use to authenticate the connection to
|
||||
the remote device. The value of I(username) is used to authenticate
|
||||
either the CLI login or the eAPI authentication depending on which
|
||||
transport is used.
|
||||
required: true
|
||||
transport is used. If the value is not specified in the task, the
|
||||
value of environment variable ANSIBLE_NET_USERNAME will be used instead.
|
||||
required: false
|
||||
password:
|
||||
description:
|
||||
- Specifies the password to use to authenticate the connection to
|
||||
the remote device. This is a common argument used for either I(cli)
|
||||
or I(eapi) transports.
|
||||
or I(eapi) transports. If the value is not specified in the task, the
|
||||
value of environment variable ANSIBLE_NET_PASSWORD will be used instead.
|
||||
required: false
|
||||
default: null
|
||||
ssh_keyfile:
|
||||
description:
|
||||
- Specifies the SSH keyfile to use to authenticate the connection to
|
||||
the remote device. This argument is only used for I(cli) transports.
|
||||
If the value is not specified in the task, the value of environment
|
||||
variable ANSIBLE_NET_SSH_KEYFILE will be used instead.
|
||||
required: false
|
||||
default: null
|
||||
authorize:
|
||||
description:
|
||||
- Instructs the module to enter priviledged mode on the remote device
|
||||
before sending any commands. If not specified, the device will
|
||||
attempt to excecute all commands in non-priviledged mode.
|
||||
attempt to excecute all commands in non-priviledged mode. If the value
|
||||
is not specified in the task, the value of environment variable
|
||||
ANSIBLE_NET_AUTHORIZE will be used instead.
|
||||
required: false
|
||||
default: no
|
||||
choices: ['yes', 'no']
|
||||
|
@ -68,7 +73,8 @@ options:
|
|||
description:
|
||||
- Specifies the password to use if required to enter privileged mode
|
||||
on the remote device. If I(authorize) is false, then this argument
|
||||
does nothing
|
||||
does nothing. If the value is not specified in the task, the value of
|
||||
environment variable ANSIBLE_NET_AUTH_PASS will be used instead.
|
||||
required: false
|
||||
default: none
|
||||
transport:
|
||||
|
|
|
@ -41,15 +41,24 @@ options:
|
|||
- Configures the usename to use to authenticate the connection to
|
||||
the remote device. The value of I(username) is used to authenticate
|
||||
either the CLI login or the nxapi authentication depending on which
|
||||
transport is used.
|
||||
required: true
|
||||
transport is used. If the value is not specified in the task, the
|
||||
value of environment variable ANSIBLE_NET_USERNAME will be used instead.
|
||||
required: false
|
||||
password:
|
||||
description:
|
||||
- Specifies the password to use when authentication the connection to
|
||||
- Specifies the password to use to authenticate the connection to
|
||||
the remote device. This is a common argument used for either I(cli)
|
||||
or I(nxapi) transports.
|
||||
or I(nxapi) transports. If the value is not specified in the task, the
|
||||
value of environment variable ANSIBLE_NET_PASSWORD will be used instead.
|
||||
required: false
|
||||
default: null
|
||||
ssh_keyfile:
|
||||
description:
|
||||
- Specifies the SSH key to use to authenticate the connection to
|
||||
the remote device. This argument is only used for the I(cli)
|
||||
transport. If the value is not specified in the task, the
|
||||
value of environment variable ANSIBLE_NET_SSH_KEYFILE will be used instead.
|
||||
required: false
|
||||
transport:
|
||||
description:
|
||||
- Configures the transport connection to use when connecting to the
|
||||
|
|
Loading…
Reference in a new issue