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])
|
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):
|
class AnsibleModule(object):
|
||||||
def __init__(self, argument_spec, bypass_checks=False, no_log=False,
|
def __init__(self, argument_spec, bypass_checks=False, no_log=False,
|
||||||
check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
|
check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
|
||||||
|
@ -550,6 +562,7 @@ class AnsibleModule(object):
|
||||||
|
|
||||||
self._load_constants()
|
self._load_constants()
|
||||||
self._load_params()
|
self._load_params()
|
||||||
|
self._set_fallbacks()
|
||||||
|
|
||||||
# append to legal_inputs and then possibly check against them
|
# append to legal_inputs and then possibly check against them
|
||||||
try:
|
try:
|
||||||
|
@ -1421,6 +1434,23 @@ class AnsibleModule(object):
|
||||||
if k not in self.params:
|
if k not in self.params:
|
||||||
self.params[k] = default
|
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):
|
def _load_params(self):
|
||||||
''' read the input and set the params attribute'''
|
''' read the input and set the params attribute'''
|
||||||
if MODULE_COMPLEX_ARGS is None:
|
if MODULE_COMPLEX_ARGS is None:
|
||||||
|
|
|
@ -20,7 +20,7 @@ import os
|
||||||
|
|
||||||
import re
|
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.shell import Shell, Command, HAS_PARAMIKO
|
||||||
from ansible.module_utils.netcfg import parse
|
from ansible.module_utils.netcfg import parse
|
||||||
from ansible.module_utils.urls import fetch_url
|
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(
|
NET_COMMON_ARGS = dict(
|
||||||
host=dict(required=True),
|
host=dict(required=True),
|
||||||
port=dict(type='int'),
|
port=dict(type='int'),
|
||||||
username=dict(required=True),
|
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||||
password=dict(no_log=True),
|
password=dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD'])),
|
||||||
ssh_keyfile=dict(type='path'),
|
ssh_keyfile=dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'),
|
||||||
authorize=dict(default=False, type='bool'),
|
authorize=dict(default=False, fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
|
||||||
auth_pass=dict(no_log=True),
|
auth_pass=dict(no_log=True, fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS'])),
|
||||||
transport=dict(default='cli', choices=['cli', 'eapi']),
|
transport=dict(default='cli', choices=['cli', 'eapi']),
|
||||||
use_ssl=dict(default=True, type='bool'),
|
use_ssl=dict(default=True, type='bool'),
|
||||||
provider=dict(type='dict')
|
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 = [
|
CLI_PROMPTS_RE = [
|
||||||
re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"),
|
re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"),
|
||||||
re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$")
|
re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$")
|
||||||
|
@ -200,9 +192,6 @@ class NetworkModule(AnsibleModule):
|
||||||
if key in NET_COMMON_ARGS:
|
if key in NET_COMMON_ARGS:
|
||||||
if self.params.get(key) is None and value is not None:
|
if self.params.get(key) is None and value is not None:
|
||||||
self.params[key] = value
|
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):
|
def connect(self):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -21,7 +21,7 @@ import re
|
||||||
|
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url
|
||||||
from ansible.module_utils.shell import Shell, HAS_PARAMIKO
|
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
|
from ansible.module_utils.netcfg import parse
|
||||||
|
|
||||||
NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I)
|
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(
|
NET_COMMON_ARGS = dict(
|
||||||
host=dict(required=True),
|
host=dict(required=True),
|
||||||
port=dict(type='int'),
|
port=dict(type='int'),
|
||||||
username=dict(required=True),
|
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||||
password=dict(no_log=True),
|
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']),
|
transport=dict(default='cli', choices=['cli', 'nxapi']),
|
||||||
use_ssl=dict(default=False, type='bool'),
|
use_ssl=dict(default=False, type='bool'),
|
||||||
validate_certs=dict(default=True, type='bool'),
|
validate_certs=dict(default=True, type='bool'),
|
||||||
|
@ -165,11 +166,11 @@ class Cli(object):
|
||||||
|
|
||||||
username = self.module.params['username']
|
username = self.module.params['username']
|
||||||
password = self.module.params['password']
|
password = self.module.params['password']
|
||||||
|
key_filename = self.module.params['ssh_keyfile']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.shell = Shell(prompts_re=CLI_PROMPTS_RE, errors_re=CLI_ERRORS_RE,
|
self.shell = Shell(prompts_re=CLI_PROMPTS_RE, errors_re=CLI_ERRORS_RE, kickstart=False)
|
||||||
kickstart=False)
|
self.shell.open(host, port=port, username=username, password=password, key_filename=key_filename)
|
||||||
self.shell.open(host, port=port, username=username, password=password)
|
|
||||||
except Exception, exc:
|
except Exception, exc:
|
||||||
msg = 'failed to connect to %s:%s - %s' % (host, port, str(exc))
|
msg = 'failed to connect to %s:%s - %s' % (host, port, str(exc))
|
||||||
self.module.fail_json(msg=msg)
|
self.module.fail_json(msg=msg)
|
||||||
|
|
|
@ -41,26 +41,31 @@ options:
|
||||||
- Configures the usename to use to authenticate the connection to
|
- Configures the usename to use to authenticate the connection to
|
||||||
the remote device. The value of I(username) is used to authenticate
|
the remote device. The value of I(username) is used to authenticate
|
||||||
either the CLI login or the eAPI authentication depending on which
|
either the CLI login or the eAPI authentication depending on which
|
||||||
transport is used.
|
transport is used. If the value is not specified in the task, the
|
||||||
required: true
|
value of environment variable ANSIBLE_NET_USERNAME will be used instead.
|
||||||
|
required: false
|
||||||
password:
|
password:
|
||||||
description:
|
description:
|
||||||
- Specifies the password to use to authenticate 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)
|
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
|
required: false
|
||||||
default: null
|
default: null
|
||||||
ssh_keyfile:
|
ssh_keyfile:
|
||||||
description:
|
description:
|
||||||
- Specifies the SSH keyfile to use to authenticate the connection to
|
- Specifies the SSH keyfile to use to authenticate the connection to
|
||||||
the remote device. This argument is only used for I(cli) transports.
|
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
|
required: false
|
||||||
default: null
|
|
||||||
authorize:
|
authorize:
|
||||||
description:
|
description:
|
||||||
- Instructs the module to enter priviledged mode on the remote device
|
- Instructs the module to enter priviledged mode on the remote device
|
||||||
before sending any commands. If not specified, the device will
|
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
|
required: false
|
||||||
default: no
|
default: no
|
||||||
choices: ['yes', 'no']
|
choices: ['yes', 'no']
|
||||||
|
@ -68,7 +73,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- Specifies the password to use if required to enter privileged mode
|
- Specifies the password to use if required to enter privileged mode
|
||||||
on the remote device. If I(authorize) is false, then this argument
|
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
|
required: false
|
||||||
default: none
|
default: none
|
||||||
transport:
|
transport:
|
||||||
|
|
|
@ -41,15 +41,24 @@ options:
|
||||||
- Configures the usename to use to authenticate the connection to
|
- Configures the usename to use to authenticate the connection to
|
||||||
the remote device. The value of I(username) is used to authenticate
|
the remote device. The value of I(username) is used to authenticate
|
||||||
either the CLI login or the nxapi authentication depending on which
|
either the CLI login or the nxapi authentication depending on which
|
||||||
transport is used.
|
transport is used. If the value is not specified in the task, the
|
||||||
required: true
|
value of environment variable ANSIBLE_NET_USERNAME will be used instead.
|
||||||
|
required: false
|
||||||
password:
|
password:
|
||||||
description:
|
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)
|
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
|
required: false
|
||||||
default: null
|
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:
|
transport:
|
||||||
description:
|
description:
|
||||||
- Configures the transport connection to use when connecting to the
|
- Configures the transport connection to use when connecting to the
|
||||||
|
|
Loading…
Reference in a new issue