Revert "Remove top-level arguments from network modules (#62603)"

This reverts commit d5ac3f7e77.
This commit is contained in:
Matt Clay 2019-10-15 12:53:51 -07:00
parent e4eea0510c
commit 20be8693ba
41 changed files with 431 additions and 114 deletions

View file

@ -430,10 +430,12 @@ def validate_prefix(prefix):
def load_provider(spec, args): def load_provider(spec, args):
provider = args.get('provider') or {} provider = args.get('provider', {})
for key, value in iteritems(spec): for key, value in iteritems(spec):
if key not in provider: if key not in provider:
if 'fallback' in value: if key in args:
provider[key] = args[key]
elif 'fallback' in value:
provider[key] = _fallback(value['fallback']) provider[key] = _fallback(value['fallback'])
elif 'default' in value: elif 'default' in value:
provider[key] = value['default'] provider[key] = value['default']

View file

@ -36,6 +36,7 @@ from ansible.module_utils.basic import env_fallback
from ansible.module_utils.connection import Connection, ConnectionError from ansible.module_utils.connection import Connection, ConnectionError
from ansible.module_utils.network.common.config import NetworkConfig, dumps from ansible.module_utils.network.common.config import NetworkConfig, dumps
from ansible.module_utils.network.common.utils import to_list, ComplexList from ansible.module_utils.network.common.utils import to_list, ComplexList
from ansible.module_utils.six import iteritems
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
_DEVICE_CONNECTION = None _DEVICE_CONNECTION = None
@ -60,15 +61,41 @@ eos_provider_spec = {
eos_argument_spec = { eos_argument_spec = {
'provider': dict(type='dict', options=eos_provider_spec), 'provider': dict(type='dict', options=eos_provider_spec),
} }
eos_top_spec = {
'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'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'),
'transport': dict(removed_in_version=2.9, choices=['cli', 'eapi'])
}
eos_argument_spec.update(eos_top_spec)
def get_provider_argspec(): def get_provider_argspec():
return eos_provider_spec return eos_provider_spec
def load_params(module):
provider = module.params.get('provider') or dict()
for key, value in iteritems(provider):
if key in eos_argument_spec:
if module.params.get(key) is None and value is not None:
module.params[key] = value
def get_connection(module): def get_connection(module):
global _DEVICE_CONNECTION global _DEVICE_CONNECTION
if not _DEVICE_CONNECTION: if not _DEVICE_CONNECTION:
load_params(module)
if is_local_eapi(module): if is_local_eapi(module):
conn = LocalEapi(module) conn = LocalEapi(module)
else: else:
@ -183,24 +210,23 @@ class LocalEapi:
self._session_support = None self._session_support = None
self._device_configs = {} self._device_configs = {}
provider = module.params.get("provider") or {} host = module.params['provider']['host']
host = provider.get('host') port = module.params['provider']['port']
port = provider.get('port')
self._module.params['url_username'] = provider.get('username') self._module.params['url_username'] = self._module.params['username']
self._module.params['url_password'] = provider.get('password') self._module.params['url_password'] = self._module.params['password']
if provider.get('use_ssl'): if module.params['provider']['use_ssl']:
proto = 'https' proto = 'https'
else: else:
proto = 'http' proto = 'http'
module.params['validate_certs'] = provider.get('validate_certs') module.params['validate_certs'] = module.params['provider']['validate_certs']
self._url = '%s://%s:%s/command-api' % (proto, host, port) self._url = '%s://%s:%s/command-api' % (proto, host, port)
if provider.get("auth_pass"): if module.params['auth_pass']:
self._enable = {'cmd': 'enable', 'input': provider.get('auth_pass')} self._enable = {'cmd': 'enable', 'input': module.params['auth_pass']}
else: else:
self._enable = 'enable' self._enable = 'enable'
@ -225,7 +251,7 @@ class LocalEapi:
data = self._module.jsonify(body) data = self._module.jsonify(body)
headers = {'Content-Type': 'application/json-rpc'} headers = {'Content-Type': 'application/json-rpc'}
timeout = self._module.params['provider']['timeout'] timeout = self._module.params['timeout']
use_proxy = self._module.params['provider']['use_proxy'] use_proxy = self._module.params['provider']['use_proxy']
response, headers = fetch_url( response, headers = fetch_url(
@ -569,10 +595,12 @@ def is_json(cmd):
def is_local_eapi(module): def is_local_eapi(module):
transports = []
transports.append(module.params.get('transport', ""))
provider = module.params.get('provider') provider = module.params.get('provider')
if provider: if provider:
return provider.get('transport') == 'eapi' transports.append(provider.get('transport', ""))
return False return 'eapi' in transports
def to_command(module, commands): def to_command(module, commands):

View file

@ -48,6 +48,18 @@ ios_argument_spec = {
'provider': dict(type='dict', options=ios_provider_spec), 'provider': dict(type='dict', options=ios_provider_spec),
} }
ios_top_spec = {
'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
'auth_pass': dict(removed_in_version=2.9, no_log=True),
'timeout': dict(removed_in_version=2.9, type='int')
}
ios_argument_spec.update(ios_top_spec)
def get_provider_argspec(): def get_provider_argspec():
return ios_provider_spec return ios_provider_spec

View file

@ -90,6 +90,16 @@ command_spec = {
'answer': dict(default=None) 'answer': dict(default=None)
} }
iosxr_top_spec = {
'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'timeout': dict(removed_in_version=2.9, type='int'),
}
iosxr_argument_spec.update(iosxr_top_spec)
CONFIG_MISPLACED_CHILDREN = [ CONFIG_MISPLACED_CHILDREN = [
re.compile(r'^end-\s*(.+)$') re.compile(r'^end-\s*(.+)$')
] ]

View file

@ -10,8 +10,7 @@ calls the appropriate facts gathering function
""" """
from ansible.module_utils.network.common.facts.facts import FactsBase from ansible.module_utils.network.common.facts.facts import FactsBase
from ansible.module_utils.network.junos.junos import HAS_PYEZ from ansible.module_utils.network.junos.facts.legacy.base import Default, Hardware, Config, Interfaces, OFacts, HAS_PYEZ
from ansible.module_utils.network.junos.facts.legacy.base import Default, Hardware, Config, Interfaces, OFacts
from ansible.module_utils.network.junos.facts.interfaces.interfaces import InterfacesFacts from ansible.module_utils.network.junos.facts.interfaces.interfaces import InterfacesFacts
from ansible.module_utils.network.junos.facts.lacp.lacp import LacpFacts from ansible.module_utils.network.junos.facts.lacp.lacp import LacpFacts
from ansible.module_utils.network.junos.facts.lacp_interfaces.lacp_interfaces import Lacp_interfacesFacts from ansible.module_utils.network.junos.facts.lacp_interfaces.lacp_interfaces import Lacp_interfacesFacts

View file

@ -11,8 +11,8 @@ based on the configuration.
import platform import platform
from ansible.module_utils.network.common.netconf import exec_rpc from ansible.module_utils.network.common.netconf import exec_rpc
from ansible.module_utils.network.junos.junos import tostring from ansible.module_utils.network.junos.junos import get_param, tostring
from ansible.module_utils.network.junos.junos import get_configuration, get_capabilities, get_device from ansible.module_utils.network.junos.junos import get_configuration, get_capabilities
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
@ -21,6 +21,13 @@ try:
except ImportError: except ImportError:
from xml.etree.ElementTree import Element, SubElement from xml.etree.ElementTree import Element, SubElement
try:
from jnpr.junos import Device
from jnpr.junos.exception import ConnectError
HAS_PYEZ = True
except ImportError:
HAS_PYEZ = False
class FactsBase(object): class FactsBase(object):
@ -177,9 +184,33 @@ class Interfaces(FactsBase):
class OFacts(FactsBase): class OFacts(FactsBase):
def _connect(self, module):
host = get_param(module, 'host')
kwargs = {
'port': get_param(module, 'port') or 830,
'user': get_param(module, 'username')
}
if get_param(module, 'password'):
kwargs['passwd'] = get_param(module, 'password')
if get_param(module, 'ssh_keyfile'):
kwargs['ssh_private_key_file'] = get_param(module, 'ssh_keyfile')
kwargs['gather_facts'] = False
try:
device = Device(host, **kwargs)
device.open()
device.timeout = get_param(module, 'timeout') or 10
except ConnectError as exc:
module.fail_json('unable to connect to %s: %s' % (host, to_text(exc)))
return device
def populate(self): def populate(self):
device = get_device(self.module) device = self._connect(self.module)
facts = dict(device.facts) facts = dict(device.facts)
if '2RE' in facts: if '2RE' in facts:

View file

@ -33,13 +33,6 @@ except ImportError:
from xml.etree.ElementTree import Element, SubElement, tostring as xml_to_string from xml.etree.ElementTree import Element, SubElement, tostring as xml_to_string
HAS_LXML = False HAS_LXML = False
try:
from jnpr.junos import Device
from jnpr.junos.exception import ConnectError
HAS_PYEZ = True
except ImportError:
HAS_PYEZ = False
ACTIONS = frozenset(['merge', 'override', 'replace', 'update', 'set']) ACTIONS = frozenset(['merge', 'override', 'replace', 'update', 'set'])
JSON_ACTIONS = frozenset(['merge', 'override', 'update']) JSON_ACTIONS = frozenset(['merge', 'override', 'update'])
FORMATS = frozenset(['xml', 'text', 'json']) FORMATS = frozenset(['xml', 'text', 'json'])
@ -57,6 +50,16 @@ junos_provider_spec = {
junos_argument_spec = { junos_argument_spec = {
'provider': dict(type='dict', options=junos_provider_spec), 'provider': dict(type='dict', options=junos_provider_spec),
} }
junos_top_spec = {
'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'timeout': dict(removed_in_version=2.9, type='int'),
'transport': dict(removed_in_version=2.9)
}
junos_argument_spec.update(junos_top_spec)
def tostring(element, encoding='UTF-8'): def tostring(element, encoding='UTF-8'):
@ -98,33 +101,6 @@ def get_capabilities(module):
return module._junos_capabilities return module._junos_capabilities
def get_device(module):
provider = module.params.get("provider") or {}
host = provider.get('host')
kwargs = {
'port': provider.get('port') or 830,
'user': provider.get('username')
}
if 'password' in provider:
kwargs['passwd'] = provider.get('password')
if 'ssh_keyfile' in provider:
kwargs['ssh_private_key_file'] = provider.get('ssh_keyfile')
kwargs['gather_facts'] = False
try:
device = Device(host, **kwargs)
device.open()
device.timeout = provider.get('timeout') or 10
except ConnectError as exc:
module.fail_json('unable to connect to %s: %s' % (host, to_text(exc)))
return device
def is_netconf(module): def is_netconf(module):
capabilities = get_capabilities(module) capabilities = get_capabilities(module)
return True if capabilities.get('network_api') == 'netconf' else False return True if capabilities.get('network_api') == 'netconf' else False
@ -276,6 +252,16 @@ def load_config(module, candidate, warnings, action='merge', format='xml'):
return get_diff(module) return get_diff(module)
def get_param(module, key):
if module.params.get(key):
value = module.params[key]
elif module.params.get('provider'):
value = module.params['provider'].get(key)
else:
value = None
return value
def map_params_to_obj(module, param_to_xpath_map, param=None): def map_params_to_obj(module, param_to_xpath_map, param=None):
""" """
Creates a new dictionary with key as xpath corresponding Creates a new dictionary with key as xpath corresponding

View file

@ -83,15 +83,42 @@ nxos_provider_spec = {
nxos_argument_spec = { nxos_argument_spec = {
'provider': dict(type='dict', options=nxos_provider_spec), 'provider': dict(type='dict', options=nxos_provider_spec),
} }
nxos_top_spec = {
'host': dict(type='str', removed_in_version=2.9),
'port': dict(type='int', removed_in_version=2.9),
'username': dict(type='str', removed_in_version=2.9),
'password': dict(type='str', no_log=True, removed_in_version=2.9),
'ssh_keyfile': dict(type='str', removed_in_version=2.9),
'authorize': dict(type='bool', fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE'])),
'auth_pass': dict(type='str', no_log=True, removed_in_version=2.9),
'use_ssl': dict(type='bool', removed_in_version=2.9),
'validate_certs': dict(type='bool', removed_in_version=2.9),
'timeout': dict(type='int', removed_in_version=2.9),
'transport': dict(type='str', choices=['cli', 'nxapi'], removed_in_version=2.9)
}
nxos_argument_spec.update(nxos_top_spec)
def get_provider_argspec(): def get_provider_argspec():
return nxos_provider_spec return nxos_provider_spec
def load_params(module):
provider = module.params.get('provider') or dict()
for key, value in iteritems(provider):
if key in nxos_provider_spec:
if module.params.get(key) is None and value is not None:
module.params[key] = value
def get_connection(module): def get_connection(module):
global _DEVICE_CONNECTION global _DEVICE_CONNECTION
if not _DEVICE_CONNECTION: if not _DEVICE_CONNECTION:
load_params(module)
if is_local_nxapi(module): if is_local_nxapi(module):
conn = LocalNxapi(module) conn = LocalNxapi(module)
else: else:
@ -251,14 +278,13 @@ class LocalNxapi:
self._device_configs = {} self._device_configs = {}
self._module_context = {} self._module_context = {}
provider = self._module.params.get("provider") or {} self._module.params['url_username'] = self._module.params['username']
self._module.params['url_username'] = provider.get('username') self._module.params['url_password'] = self._module.params['password']
self._module.params['url_password'] = provider.get('password')
host = provider.get('host') host = self._module.params['host']
port = provider.get('port') port = self._module.params['port']
if provider.get('use_ssl'): if self._module.params['use_ssl']:
proto = 'https' proto = 'https'
port = port or 443 port = port or 443
else: else:
@ -1148,10 +1174,10 @@ def is_text(cmd):
def is_local_nxapi(module): def is_local_nxapi(module):
transport = module.params.get('transport')
provider = module.params.get('provider') provider = module.params.get('provider')
if provider: provider_transport = provider['transport'] if provider else None
return provider.get("transport") == 'nxapi' return 'nxapi' in (transport, provider_transport)
return False
def to_command(module, commands): def to_command(module, commands):

View file

@ -46,6 +46,17 @@ vyos_provider_spec = {
vyos_argument_spec = { vyos_argument_spec = {
'provider': dict(type='dict', options=vyos_provider_spec), 'provider': dict(type='dict', options=vyos_provider_spec),
} }
vyos_top_spec = {
'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'timeout': dict(removed_in_version=2.9, type='int'),
}
vyos_argument_spec.update(vyos_top_spec)
def get_provider_argspec(): def get_provider_argspec():

View file

@ -89,7 +89,7 @@ session_name:
""" """
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.eos.eos import load_config, run_commands from ansible.module_utils.network.eos.eos import load_config, run_commands
from ansible.module_utils.network.eos.eos import eos_argument_spec, is_local_eapi from ansible.module_utils.network.eos.eos import eos_argument_spec
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
@ -129,7 +129,7 @@ def map_config_to_obj(module):
output = run_commands(module, ['show banner %s' % module.params['banner']]) output = run_commands(module, ['show banner %s' % module.params['banner']])
obj = {'banner': module.params['banner'], 'state': 'absent'} obj = {'banner': module.params['banner'], 'state': 'absent'}
if output: if output:
if is_local_eapi(module): if module.params['transport'] == 'eapi':
# On EAPI we need to extract the banner text from dict key # On EAPI we need to extract the banner text from dict key
# 'loginBanner' # 'loginBanner'
if module.params['banner'] == 'login': if module.params['banner'] == 'login':

View file

@ -101,12 +101,6 @@ options:
type: bool type: bool
default: 'no' default: 'no'
aliases: ['enable_socket'] aliases: ['enable_socket']
timeout:
description:
- The time (in seconds) to wait for the eAPI configuration to be
reflected in the running-config.
type: int
default: 30
vrf: vrf:
description: description:
- The C(vrf) argument will configure eAPI to listen for connections - The C(vrf) argument will configure eAPI to listen for connections
@ -184,9 +178,10 @@ from ansible.module_utils.network.eos.eos import eos_argument_spec
def check_transport(module): def check_transport(module):
transport = (module.params['provider'] or {}).get('transport') transport = module.params['transport']
provider_transport = (module.params['provider'] or {}).get('transport')
if transport == 'eapi': if 'eapi' in (transport, provider_transport):
module.fail_json(msg='eos_eapi module is only supported over cli transport') module.fail_json(msg='eos_eapi module is only supported over cli transport')
@ -339,7 +334,7 @@ def verify_state(updates, module):
('local_http', 'localHttpServer'), ('local_http', 'localHttpServer'),
('socket', 'unixSocketServer')] ('socket', 'unixSocketServer')]
timeout = module.params["timeout"] timeout = module.params['timeout'] or 30
state = module.params['state'] state = module.params['state']
while invalid_state: while invalid_state:
@ -386,7 +381,6 @@ def main():
local_http_port=dict(type='int'), local_http_port=dict(type='int'),
socket=dict(aliases=['enable_socket'], type='bool'), socket=dict(aliases=['enable_socket'], type='bool'),
timeout=dict(type="int", default=30),
vrf=dict(default='default'), vrf=dict(default='default'),

View file

@ -361,6 +361,11 @@ def main():
supports_check_mode=True) supports_check_mode=True)
warnings = list() warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
result = {'changed': False} result = {'changed': False}
if warnings: if warnings:

View file

@ -505,7 +505,15 @@ def main():
supports_check_mode=True) supports_check_mode=True)
warnings = list() warnings = list()
result = {'changed': False, 'warnings': warnings} if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
result = {'changed': False}
if warnings:
result['warnings'] = warnings
want = map_params_to_obj(module) want = map_params_to_obj(module)
have = map_config_to_obj(module) have = map_config_to_obj(module)

View file

@ -251,18 +251,12 @@ class PublicKeyManager(object):
def copy_key_to_node(self, base64keyfile): def copy_key_to_node(self, base64keyfile):
""" Copy key to IOS-XR node. We use SFTP because older IOS-XR versions don't handle SCP very well. """ Copy key to IOS-XR node. We use SFTP because older IOS-XR versions don't handle SCP very well.
""" """
provider = self._module.params.get("provider") or {} if (self._module.params['host'] is None or self._module.params['provider']['host'] is None):
node = provider.get('host')
if node is None:
return False return False
user = provider.get('username') if (self._module.params['username'] is None or self._module.params['provider']['username'] is None):
if user is None:
return False return False
password = provider.get('password')
ssh_keyfile = provider.get('ssh_keyfile')
if self._module.params['aggregate']: if self._module.params['aggregate']:
name = 'aggregate' name = 'aggregate'
else: else:
@ -271,6 +265,11 @@ class PublicKeyManager(object):
src = base64keyfile src = base64keyfile
dst = '/harddisk:/publickey_%s.b64' % (name) dst = '/harddisk:/publickey_%s.b64' % (name)
user = self._module.params['username'] or self._module.params['provider']['username']
node = self._module.params['host'] or self._module.params['provider']['host']
password = self._module.params['password'] or self._module.params['provider']['password']
ssh_keyfile = self._module.params['ssh_keyfile'] or self._module.params['provider']['ssh_keyfile']
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if not ssh_keyfile: if not ssh_keyfile:
@ -285,17 +284,16 @@ class PublicKeyManager(object):
def addremovekey(self, command): def addremovekey(self, command):
""" Add or remove key based on command """ Add or remove key based on command
""" """
provider = self._module.params.get("provider") or {} if (self._module.params['host'] is None or self._module.params['provider']['host'] is None):
node = provider.get('host')
if node is None:
return False return False
user = provider.get('username') if (self._module.params['username'] is None or self._module.params['provider']['username'] is None):
if user is None:
return False return False
password = provider.get('password') user = self._module.params['username'] or self._module.params['provider']['username']
ssh_keyfile = provider.get('ssh_keyfile') node = self._module.params['host'] or self._module.params['provider']['host']
password = self._module.params['password'] or self._module.params['provider']['password']
ssh_keyfile = self._module.params['ssh_keyfile'] or self._module.params['provider']['ssh_keyfile']
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
@ -697,6 +695,11 @@ def main():
) )
result = {'changed': False, 'warnings': []} result = {'changed': False, 'warnings': []}
if module.params['password'] and not module.params['configured_password']:
result['warnings'].append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
config_object = None config_object = None
if is_cliconf(module): if is_cliconf(module):

View file

@ -114,15 +114,44 @@ EXAMPLES = """
reboot: no reboot: no
""" """
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.junos.junos import junos_argument_spec, get_device from ansible.module_utils.network.junos.junos import junos_argument_spec, get_param
from ansible.module_utils._text import to_native
try: try:
from jnpr.junos import Device
from jnpr.junos.utils.sw import SW from jnpr.junos.utils.sw import SW
from jnpr.junos.exception import ConnectError
HAS_PYEZ = True HAS_PYEZ = True
except ImportError: except ImportError:
HAS_PYEZ = False HAS_PYEZ = False
def connect(module):
host = get_param(module, 'host')
kwargs = {
'port': get_param(module, 'port') or 830,
'user': get_param(module, 'username')
}
if get_param(module, 'password'):
kwargs['passwd'] = get_param(module, 'password')
if get_param(module, 'ssh_keyfile'):
kwargs['ssh_private_key_file'] = get_param(module, 'ssh_keyfile')
kwargs['gather_facts'] = False
try:
device = Device(host, **kwargs)
device.open()
device.timeout = get_param(module, 'timeout') or 10
except ConnectError as exc:
module.fail_json(msg='unable to connect to %s: %s' % (host, to_native(exc)))
return device
def install_package(module, device): def install_package(module, device):
junos = SW(device) junos = SW(device)
package = module.params['src'] package = module.params['src']
@ -179,7 +208,7 @@ def main():
do_upgrade = module.params['force'] or False do_upgrade = module.params['force'] or False
device = get_device(module) device = connect(module)
if not module.params['force']: if not module.params['force']:
device.facts_refresh() device.facts_refresh()

View file

@ -82,16 +82,44 @@ changed:
type: bool type: bool
""" """
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.junos.junos import junos_argument_spec, get_device from ansible.module_utils.network.junos.junos import junos_argument_spec, get_param
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
try: try:
from jnpr.junos import Device
from jnpr.junos.utils.scp import SCP from jnpr.junos.utils.scp import SCP
from jnpr.junos.exception import ConnectError
HAS_PYEZ = True HAS_PYEZ = True
except ImportError: except ImportError:
HAS_PYEZ = False HAS_PYEZ = False
def connect(module):
host = get_param(module, 'host')
kwargs = {
'port': get_param(module, 'port') or 830,
'user': get_param(module, 'username')
}
if get_param(module, 'password'):
kwargs['passwd'] = get_param(module, 'password')
if get_param(module, 'ssh_keyfile'):
kwargs['ssh_private_key_file'] = get_param(module, 'ssh_keyfile')
kwargs['gather_facts'] = False
try:
device = Device(host, **kwargs)
device.open()
device.timeout = get_param(module, 'timeout') or 10
except ConnectError as exc:
module.fail_json('unable to connect to %s: %s' % (host, to_native(exc)))
return device
def transfer_files(module, device): def transfer_files(module, device):
dest = module.params['dest'] dest = module.params['dest']
recursive = module.params['recursive'] recursive = module.params['recursive']
@ -134,7 +162,7 @@ def main():
if not module.check_mode: if not module.check_mode:
# open pyez connection and transfer files via SCP # open pyez connection and transfer files via SCP
try: try:
device = get_device(module) device = connect(module)
transfer_files(module, device) transfer_files(module, device)
except Exception as ex: except Exception as ex:
module.fail_json( module.fail_json(

View file

@ -76,6 +76,7 @@ EXAMPLES = r'''
priority: 150 priority: 150
interface: vlan10 interface: vlan10
preempt: enabled preempt: enabled
host: 68.170.147.165
- name: Ensure HSRP is configured with following params on a SVI - name: Ensure HSRP is configured with following params on a SVI
with clear text authentication with clear text authentication
@ -85,6 +86,7 @@ EXAMPLES = r'''
priority: 150 priority: 150
interface: vlan10 interface: vlan10
preempt: enabled preempt: enabled
host: 68.170.147.165
auth_type: text auth_type: text
auth_string: CISCO auth_string: CISCO
@ -96,6 +98,7 @@ EXAMPLES = r'''
priority: 150 priority: 150
interface: vlan10 interface: vlan10
preempt: enabled preempt: enabled
host: 68.170.147.165
auth_type: md5 auth_type: md5
auth_string: "0 1234" auth_string: "0 1234"
@ -107,6 +110,7 @@ EXAMPLES = r'''
priority: 150 priority: 150
interface: vlan10 interface: vlan10
preempt: enabled preempt: enabled
host: 68.170.147.165
auth_type: md5 auth_type: md5
auth_string: "7 1234" auth_string: "7 1234"
@ -115,6 +119,7 @@ EXAMPLES = r'''
group: 10 group: 10
interface: vlan10 interface: vlan10
vip: 10.1.1.1 vip: 10.1.1.1
host: 68.170.147.165
state: absent state: absent
''' '''

View file

@ -306,7 +306,15 @@ def main():
supports_check_mode=True) supports_check_mode=True)
warnings = list() warnings = list()
result = {'changed': False, 'warnings': warnings} if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
result = {'changed': False}
if warnings:
result['warnings'] = warnings
want = map_params_to_obj(module) want = map_params_to_obj(module)
have = config_to_dict(module) have = config_to_dict(module)

View file

@ -9,6 +9,32 @@ class ModuleDocFragment(object):
# Standard files documentation fragment # Standard files documentation fragment
DOCUMENTATION = r''' DOCUMENTATION = r'''
options: options:
authorize:
description:
- B(Deprecated)
- "Starting with Ansible 2.5 we recommend using C(connection: network_cli) and C(become: yes)."
- This option is only required if you are using eAPI.
- For more information please see the L(EOS Platform Options guide, ../network/user_guide/platform_eos.html).
- HORIZONTALLINE
- Instructs the module to enter privileged mode on the remote device
before sending any commands. If not specified, the device will
attempt to execute all commands in non-privileged mode. If the value
is not specified in the task, the value of environment variable
C(ANSIBLE_NET_AUTHORIZE) will be used instead.
type: bool
default: no
auth_pass:
description:
- B(Deprecated)
- "Starting with Ansible 2.5 we recommend using C(connection: network_cli) and C(become: yes) with C(become_pass)."
- This option is only required if you are using eAPI.
- For more information please see the L(EOS Platform Options guide, ../network/user_guide/platform_eos.html).
- HORIZONTALLINE
- 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. If the value is not specified in the task, the value of
environment variable C(ANSIBLE_NET_AUTH_PASS) will be used instead.
type: str
provider: provider:
description: description:
- B(Deprecated) - B(Deprecated)

View file

@ -9,6 +9,30 @@ class ModuleDocFragment(object):
# Standard files documentation fragment # Standard files documentation fragment
DOCUMENTATION = r''' DOCUMENTATION = r'''
options: options:
authorize:
description:
- B(Deprecated)
- "Starting with Ansible 2.5 we recommend using C(connection: network_cli) and C(become: yes)."
- For more information please see the L(IOS Platform Options guide, ../network/user_guide/platform_ios.html).
- HORIZONTALLINE
- Instructs the module to enter privileged mode on the remote device
before sending any commands. If not specified, the device will
attempt to execute all commands in non-privileged mode. If the value
is not specified in the task, the value of environment variable
C(ANSIBLE_NET_AUTHORIZE) will be used instead.
type: bool
default: no
auth_pass:
description:
- B(Deprecated)
- "Starting with Ansible 2.5 we recommend using C(connection: network_cli) and C(become: yes) with C(become_pass)."
- For more information please see the L(IOS Platform Options guide, ../network/user_guide/platform_ios.html).
- HORIZONTALLINE
- 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. If the value is not specified in the task, the value of
environment variable C(ANSIBLE_NET_AUTH_PASS) will be used instead.
type: str
provider: provider:
description: description:
- B(Deprecated) - B(Deprecated)

View file

@ -12,6 +12,7 @@
state: up state: up
tx_rate: ge(0) tx_rate: ge(0)
rx_rate: ge(0) rx_rate: ge(0)
authorize: yes
become: yes become: yes
register: result register: result

View file

@ -17,6 +17,7 @@
state: up state: up
tx_rate: ge(0) tx_rate: ge(0)
rx_rate: ge(0) rx_rate: ge(0)
authorize: yes
become: yes become: yes
register: result register: result

View file

@ -6,6 +6,7 @@
lines: lines:
- no interface port-channel 20 - no interface port-channel 20
- no interface port-channel 100 - no interface port-channel 100
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -13,6 +14,7 @@
eos_config: eos_config:
lines: lines:
- no channel-group 20 - no channel-group 20
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
parents: "{{ item }}" parents: "{{ item }}"
loop: loop:
@ -24,6 +26,7 @@
eos_linkagg: &create eos_linkagg: &create
group: 20 group: 20
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -49,6 +52,7 @@
members: members:
- Ethernet1 - Ethernet1
- Ethernet2 - Ethernet2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -76,6 +80,7 @@
mode: active mode: active
members: members:
- Ethernet2 - Ethernet2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -99,6 +104,7 @@
eos_linkagg: &remove eos_linkagg: &remove
group: 20 group: 20
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -122,6 +128,7 @@
aggregate: aggregate:
- { group: 20, min_links: 3 } - { group: 20, min_links: 3 }
- { group: 100, min_links: 4 } - { group: 100, min_links: 4 }
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -148,6 +155,7 @@
aggregate: aggregate:
- { group: 20, min_links: 3 } - { group: 20, min_links: 3 }
- { group: 100, min_links: 4 } - { group: 100, min_links: 4 }
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
state: absent state: absent
become: yes become: yes
@ -173,6 +181,7 @@
lines: lines:
- no interface port-channel 20 - no interface port-channel 20
- no interface port-channel 100 - no interface port-channel 100
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -180,6 +189,7 @@
eos_config: eos_config:
lines: lines:
- no channel-group 20 - no channel-group 20
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
parents: "{{ item }}" parents: "{{ item }}"
become: yes become: yes

View file

@ -14,11 +14,9 @@
with_items: "{{ test_items }}" with_items: "{{ test_items }}"
loop_control: loop_control:
loop_var: test_case_to_run loop_var: test_case_to_run
tags: network_cli
- name: run test cases (connection=local) - name: run test cases (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local ansible_become=no" include: "{{ test_case_to_run }} ansible_connection=local ansible_become=no"
with_items: "{{ test_items }}" with_items: "{{ test_items }}"
loop_control: loop_control:
loop_var: test_case_to_run loop_var: test_case_to_run
tags: local

View file

@ -3,8 +3,8 @@
find: find:
paths: "{{ role_path }}/tests/eapi" paths: "{{ role_path }}/tests/eapi"
patterns: "{{ testcase }}.yaml" patterns: "{{ testcase }}.yaml"
register: test_cases
delegate_to: localhost delegate_to: localhost
register: test_cases
- name: set test_items - name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
@ -14,11 +14,9 @@
with_items: "{{ test_items }}" with_items: "{{ test_items }}"
loop_control: loop_control:
loop_var: test_case_to_run loop_var: test_case_to_run
tags: httpapi
- name: run test cases (connection=local) - name: run test case (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local" include: "{{ test_case_to_run }} ansible_connection=local"
with_items: "{{ test_items }}" with_items: "{{ test_items }}"
loop_control: loop_control:
loop_var: test_case_to_run loop_var: test_case_to_run
tags: local

View file

@ -10,6 +10,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -18,6 +19,7 @@
address: 192.168.3.0/24 address: 192.168.3.0/24
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -32,6 +34,7 @@
address: 192.168.3.0/250 address: 192.168.3.0/250
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -45,6 +48,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -61,6 +65,7 @@
state: up state: up
tx_rate: ge(0) tx_rate: ge(0)
rx_rate: ge(0) rx_rate: ge(0)
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result

View file

@ -10,6 +10,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ eapi }}" provider: "{{ eapi }}"
become: yes become: yes
@ -18,6 +19,7 @@
address: 192.168.3.0/24 address: 192.168.3.0/24
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ eapi }}" provider: "{{ eapi }}"
become: yes become: yes
register: result register: result
@ -32,6 +34,7 @@
address: 192.168.3.0/250 address: 192.168.3.0/250
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ eapi }}" provider: "{{ eapi }}"
become: yes become: yes
register: result register: result
@ -45,6 +48,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ eapi }}" provider: "{{ eapi }}"
become: yes become: yes
@ -61,6 +65,7 @@
state: up state: up
tx_rate: ge(0) tx_rate: ge(0)
rx_rate: ge(0) rx_rate: ge(0)
authorize: yes
provider: "{{ eapi }}" provider: "{{ eapi }}"
become: yes become: yes
register: result register: result

View file

@ -7,6 +7,7 @@
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
- no ip route 192.168.4.0/24 192.168.0.1 - no ip route 192.168.4.0/24 192.168.0.1
- no ip route 192.168.5.0/24 192.168.0.1 - no ip route 192.168.5.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -15,6 +16,7 @@
address: 192.168.3.0/24 address: 192.168.3.0/24
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -38,6 +40,7 @@
address: 192.168.3.0/24 address: 192.168.3.0/24
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
state: absent state: absent
become: yes become: yes
@ -62,6 +65,7 @@
aggregate: aggregate:
- { address: 192.168.4.0/24, next_hop: 192.168.0.1 } - { address: 192.168.4.0/24, next_hop: 192.168.0.1 }
- { address: 192.168.5.0/24, next_hop: 192.168.0.1 } - { address: 192.168.5.0/24, next_hop: 192.168.0.1 }
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -86,6 +90,7 @@
aggregate: aggregate:
- { address: 192.168.4.0/24, next_hop: 192.168.0.1 } - { address: 192.168.4.0/24, next_hop: 192.168.0.1 }
- { address: 192.168.5.0/24, next_hop: 192.168.0.1 } - { address: 192.168.5.0/24, next_hop: 192.168.0.1 }
authorize: yes
state: absent state: absent
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -112,6 +117,7 @@
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
- no ip route 192.168.4.0/24 192.168.0.1 - no ip route 192.168.4.0/24 192.168.0.1
- no ip route 192.168.5.0/24 192.168.0.1 - no ip route 192.168.5.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes

View file

@ -8,6 +8,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -16,6 +17,7 @@
address: 192.168.3.0/24 address: 192.168.3.0/24
next_hop: 192.168.0.1 next_hop: 192.168.0.1
admin_distance: 2 admin_distance: 2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -29,6 +31,7 @@
eos_config: eos_config:
lines: lines:
- no ip route 192.168.3.0/24 192.168.0.1 - no ip route 192.168.3.0/24 192.168.0.1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes

View file

@ -6,6 +6,7 @@
privilege: 15 privilege: 15
role: network-operator role: network-operator
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
configured_password: pass123 configured_password: pass123
become: yes become: yes
@ -35,5 +36,6 @@
name: auth_user name: auth_user
state: absent state: absent
provider: "{{ cli }}" provider: "{{ cli }}"
authorize: yes
become: yes become: yes
register: result register: result

View file

@ -18,6 +18,7 @@
role: network-operator role: network-operator
state: present state: present
configured_password: test1 configured_password: test1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -36,6 +37,7 @@
privilege: 15 privilege: 15
state: present state: present
configured_password: test1 configured_password: test1
authorize: yes
update_password: on_create update_password: on_create
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -53,6 +55,7 @@
aggregate: aggregate:
- { name: ansibletest2, configured_password: test2 } - { name: ansibletest2, configured_password: test2 }
- { name: ansibletest3, configured_password: test3 } - { name: ansibletest3, configured_password: test3 }
authorize: yes
state: present state: present
role: network-operator role: network-operator
provider: "{{ cli }}" provider: "{{ cli }}"
@ -74,6 +77,7 @@
name: faileduser1 name: faileduser1
privilege: 15 privilege: 15
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
ignore_errors: yes ignore_errors: yes
@ -93,4 +97,5 @@
- no username ansibletest3 - no username ansibletest3
- no username ansibletest4 - no username ansibletest4
provider: "{{ cli }}" provider: "{{ cli }}"
authorize: yes
become: yes become: yes

View file

@ -18,6 +18,7 @@
role: network-operator role: network-operator
state: present state: present
configured_password: test1 configured_password: test1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result

View file

@ -6,6 +6,7 @@
- no vlan 4000 - no vlan 4000
- no vlan 4001 - no vlan 4001
- no vlan 4002 - no vlan 4002
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -15,6 +16,7 @@
- switchport - switchport
- no switchport access vlan 4000 - no switchport access vlan 4000
parents: interface Ethernet1 parents: interface Ethernet1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -24,6 +26,7 @@
- switchport - switchport
- no switchport access vlan 4000 - no switchport access vlan 4000
parents: interface Ethernet2 parents: interface Ethernet2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -32,6 +35,7 @@
vlan_id: 4000 vlan_id: 4000
name: vlan-4000 name: vlan-4000
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -49,6 +53,7 @@
vlan_id: 4000 vlan_id: 4000
name: vlan-4000 name: vlan-4000
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -65,6 +70,7 @@
vlan_id: 4000 vlan_id: 4000
name: vlan-4000-new name: vlan-4000-new
state: suspend state: suspend
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -83,6 +89,7 @@
vlan_id: 4000 vlan_id: 4000
name: vlan-4000-new name: vlan-4000-new
state: suspend state: suspend
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -98,6 +105,7 @@
eos_vlan: eos_vlan:
vlan_id: 4000 vlan_id: 4000
state: active state: active
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -120,6 +128,7 @@
associated_interfaces: associated_interfaces:
- Ethernet1 - Ethernet1
- Ethernet2 - Ethernet2
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -142,6 +151,7 @@
interfaces: interfaces:
- Ethernet 1 # interface name space scenario - Ethernet 1 # interface name space scenario
- Ethernet 2 # interface name space scenario - Ethernet 2 # interface name space scenario
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -159,6 +169,7 @@
state: present state: present
associated_interfaces: associated_interfaces:
- test - test
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -174,6 +185,7 @@
state: present state: present
interfaces: interfaces:
- Ethernet1 - Ethernet1
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -193,6 +205,7 @@
state: present state: present
interfaces: interfaces:
- Ethernet 1 # space scenario - Ethernet 1 # space scenario
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -210,6 +223,7 @@
- {vlan_id: 4000, state: absent} - {vlan_id: 4000, state: absent}
- {vlan_id: 4001, name: vlan-4001} - {vlan_id: 4001, name: vlan-4001}
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -229,6 +243,7 @@
- {vlan_id: 4000, state: absent} - {vlan_id: 4000, state: absent}
- {vlan_id: 4001, name: vlan-4001} - {vlan_id: 4001, name: vlan-4001}
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -247,6 +262,7 @@
name: vlan-4002 name: vlan-4002
state: present state: present
purge: yes purge: yes
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -267,6 +283,7 @@
name: vlan-4002 name: vlan-4002
state: present state: present
purge: yes purge: yes
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result

View file

@ -8,6 +8,7 @@
eos_config: eos_config:
lines: lines:
- no vlan 4000 - no vlan 4000
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -16,6 +17,7 @@
vlan_id: 4000 vlan_id: 4000
name: vlan-4000 name: vlan-4000
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -32,6 +34,7 @@
eos_config: eos_config:
lines: lines:
- no vlan 4000 - no vlan 4000
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes

View file

@ -4,6 +4,7 @@
eos_vrf: eos_vrf:
name: "{{ item }}" name: "{{ item }}"
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
with_items: with_items:
@ -19,6 +20,7 @@
name: test name: test
rd: 1:200 rd: 1:200
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -36,6 +38,7 @@
name: test name: test
rd: 1:200 rd: 1:200
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -52,6 +55,7 @@
name: test name: test
rd: 1:201 rd: 1:201
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -69,6 +73,7 @@
name: test name: test
rd: 1:201 rd: 1:201
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -85,6 +90,7 @@
name: test name: test
rd: 1:201 rd: 1:201
state: present state: present
authorize: yes
interfaces: interfaces:
- Ethernet2 - Ethernet2
associated_interfaces: associated_interfaces:
@ -106,6 +112,7 @@
name: test name: test
rd: 1:201 rd: 1:201
state: present state: present
authorize: yes
interfaces: interfaces:
- ethernet 2 # interface name modified to test case insensitive and space scenario - ethernet 2 # interface name modified to test case insensitive and space scenario
provider: "{{ cli }}" provider: "{{ cli }}"
@ -123,6 +130,7 @@
eos_vrf: eos_vrf:
name: test name: test
state: present state: present
authorize: yes
associated_interfaces: associated_interfaces:
- test - test
provider: "{{ cli }}" provider: "{{ cli }}"
@ -139,6 +147,7 @@
name: test1 name: test1
rd: 1:202 rd: 1:202
state: present state: present
authorize: yes
interfaces: interfaces:
- loopback10 - loopback10
- loopback11 - loopback11
@ -175,6 +184,7 @@
name: test1 name: test1
rd: 1:202 rd: 1:202
state: present state: present
authorize: yes
interfaces: interfaces:
- loopback10 - loopback10
- loopback11 - loopback11
@ -196,6 +206,7 @@
eos_vrf: eos_vrf:
name: "{{ item }}" name: "{{ item }}"
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
with_items: with_items:
@ -209,6 +220,7 @@
- { name: test2, rd: "1:202" } - { name: test2, rd: "1:202" }
- { name: test3, rd: "1:203" } - { name: test3, rd: "1:203" }
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -229,6 +241,7 @@
- { name: test2, rd: "1:202" } - { name: test2, rd: "1:202" }
- { name: test3, rd: "1:203" } - { name: test3, rd: "1:203" }
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -247,6 +260,7 @@
- { name: test5, rd: "1:205" } - { name: test5, rd: "1:205" }
state: present state: present
purge: yes purge: yes
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -268,6 +282,7 @@
eos_vrf: eos_vrf:
name: test name: test
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -275,6 +290,7 @@
eos_vrf: eos_vrf:
name: test name: test
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -287,6 +303,7 @@
- { name: test4 } - { name: test4 }
- { name: test5 } - { name: test5 }
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -299,6 +316,7 @@
- { name: test4 } - { name: test4 }
- { name: test5 } - { name: test5 }
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes

View file

@ -8,6 +8,7 @@
net_vrf: net_vrf:
name: test name: test
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
@ -16,6 +17,7 @@
name: test name: test
rd: 1:200 rd: 1:200
state: present state: present
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes
register: result register: result
@ -32,6 +34,7 @@
net_vrf: net_vrf:
name: test name: test
state: absent state: absent
authorize: yes
provider: "{{ cli }}" provider: "{{ cli }}"
become: yes become: yes

View file

@ -31,6 +31,7 @@
- name: unexpected unsuccessful ping - name: unexpected unsuccessful ping
ios_ping: &invalid_ip ios_ping: &invalid_ip
dest: '10.255.255.250' dest: '10.255.255.250'
timeout: 45
provider: "{{ cli }}" provider: "{{ cli }}"
register: uup register: uup
ignore_errors: yes ignore_errors: yes

View file

@ -22,9 +22,6 @@ from ansible.modules.network.eos import eos_banner
from units.modules.utils import set_module_args from units.modules.utils import set_module_args
from .eos_module import TestEosModule, load_fixture from .eos_module import TestEosModule, load_fixture
CLI = dict(transport="cli")
EAPI = dict(transport="eapi")
class TestEosBannerModule(TestEosModule): class TestEosBannerModule(TestEosModule):
@ -54,32 +51,34 @@ class TestEosBannerModule(TestEosModule):
self.load_config.return_value = dict(diff=None, session='session') self.load_config.return_value = dict(diff=None, session='session')
def test_eos_banner_create_with_cli_transport(self): def test_eos_banner_create_with_cli_transport(self):
set_module_args(dict(banner='login', text='test\nbanner\nstring', provider=CLI)) set_module_args(dict(banner='login', text='test\nbanner\nstring',
transport='cli'))
commands = ['banner login', 'test', 'banner', 'string', 'EOF'] commands = ['banner login', 'test', 'banner', 'string', 'EOF']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_banner_remove_with_cli_transport(self): def test_eos_banner_remove_with_cli_transport(self):
set_module_args(dict(banner='login', state='absent', provider=CLI)) set_module_args(dict(banner='login', state='absent', transport='cli'))
commands = ['no banner login'] commands = ['no banner login']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_banner_create_with_eapi_transport(self): def test_eos_banner_create_with_eapi_transport(self):
set_module_args(dict(banner='login', text='test\nbanner\nstring', provider=EAPI)) set_module_args(dict(banner='login', text='test\nbanner\nstring',
transport='eapi'))
commands = ['banner login'] commands = ['banner login']
inputs = ['test\nbanner\nstring'] inputs = ['test\nbanner\nstring']
self.execute_module(changed=True, commands=commands, inputs=inputs, transport='eapi') self.execute_module(changed=True, commands=commands, inputs=inputs, transport='eapi')
def test_eos_banner_remove_with_eapi_transport(self): def test_eos_banner_remove_with_eapi_transport(self):
set_module_args(dict(banner='login', state='absent', provider=EAPI)) set_module_args(dict(banner='login', state='absent', transport='eapi'))
commands = ['no banner login'] commands = ['no banner login']
self.execute_module(changed=True, commands=commands, transport='eapi') self.execute_module(changed=True, commands=commands, transport='eapi')
def test_eos_banner_nochange_with_cli_transport(self): def test_eos_banner_nochange_with_cli_transport(self):
banner_text = load_fixture('eos_banner_show_banner.txt').strip() banner_text = load_fixture('eos_banner_show_banner.txt').strip()
set_module_args(dict(banner='login', text=banner_text, provider=CLI)) set_module_args(dict(banner='login', text=banner_text, transport='cli'))
self.execute_module() self.execute_module()
def test_eos_banner_nochange_with_eapi_transport(self): def test_eos_banner_nochange_with_eapi_transport(self):
banner_text = load_fixture('eos_banner_show_banner.txt').strip() banner_text = load_fixture('eos_banner_show_banner.txt').strip()
set_module_args(dict(banner='login', text=banner_text, provider=EAPI)) set_module_args(dict(banner='login', text=banner_text, transport='eapi'))
self.execute_module(transport='eapi') self.execute_module(transport='eapi')

View file

@ -59,7 +59,7 @@ class TestIosPingModule(TestIosModule):
def test_ios_ping_expected_failure(self): def test_ios_ping_expected_failure(self):
''' Test for unsuccessful pings when destination should not be reachable ''' ''' Test for unsuccessful pings when destination should not be reachable '''
set_module_args(dict(count=2, dest="10.255.255.250", state="absent")) set_module_args(dict(count=2, dest="10.255.255.250", state="absent", timeout=45))
self.execute_module() self.execute_module()
def test_ios_ping_unexpected_success(self): def test_ios_ping_unexpected_success(self):
@ -69,5 +69,5 @@ class TestIosPingModule(TestIosModule):
def test_ios_ping_unexpected_failure(self): def test_ios_ping_unexpected_failure(self):
''' Test for unsuccessful pings when destination should be reachable - FAIL. ''' ''' Test for unsuccessful pings when destination should be reachable - FAIL. '''
set_module_args(dict(count=2, dest="10.255.255.250")) set_module_args(dict(count=2, dest="10.255.255.250", timeout=45))
self.execute_module(failed=True) self.execute_module(failed=True)

View file

@ -37,10 +37,16 @@ module_patcher.start()
from ansible.modules.network.junos import junos_package from ansible.modules.network.junos import junos_package
class TestJunosPackageModule(TestJunosModule): class TestJunosCommandModule(TestJunosModule):
module = junos_package module = junos_package
def setUp(self):
super(TestJunosCommandModule, self).setUp()
def tearDown(self):
super(TestJunosCommandModule, self).tearDown()
def test_junos_package_src(self): def test_junos_package_src(self):
set_module_args(dict(src='junos-vsrx-12.1X46-D10.2-domestic.tgz')) set_module_args(dict(src='junos-vsrx-12.1X46-D10.2-domestic.tgz'))
result = self.execute_module(changed=True) result = self.execute_module(changed=True)

View file

@ -55,7 +55,7 @@ class TestNxosHsrpModule(TestNxosModule):
priority='150', priority='150',
interface='Ethernet1/2', interface='Ethernet1/2',
preempt='enabled', preempt='enabled',
)) host='192.0.2.1'))
result = self.execute_module(changed=True) result = self.execute_module(changed=True)
self.assertEqual(sorted(result['commands']), sorted(['config t', self.assertEqual(sorted(result['commands']), sorted(['config t',
'interface ethernet1/2', 'interface ethernet1/2',