mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-21 00:19:09 -07:00
IOS-XR NetConf and Cliconf plugin work (#33332)
* - Netconf plugin addition for iosxr - Utilities refactoring to support netconf and cliconf - iosx_banner refactoring for netconf and cliconf - Integration testcases changes to accomodate above changes * Fix sanity failures, shippable errors and review comments * fix pep8 issue * changes run_command method to send specific command args * - Review comment fixes - iosxr_command changes to remove ComplexDict based command_spec * - Move namespaces removal method from utils to netconf plugin * Minor refactoring in utils and change in deprecation message * rewrite build_xml logic and import changes for new utils dir structure * - Review comment changes and minor changes to documentation * * refactor common code and docs updates
This commit is contained in:
parent
4b6061ce3e
commit
2bc4c4f156
42 changed files with 1090 additions and 247 deletions
|
@ -16,32 +16,32 @@ DOCUMENTATION = """
|
|||
---
|
||||
module: iosxr_banner
|
||||
version_added: "2.4"
|
||||
author: "Trishna Guha (@trishnaguha)"
|
||||
author:
|
||||
- Trishna Guha (@trishnaguha)
|
||||
- Kedar Kekan (@kedarX)
|
||||
short_description: Manage multiline banners on Cisco IOS XR devices
|
||||
description:
|
||||
- This will configure both exec and motd banners on remote devices
|
||||
running Cisco IOS XR. It allows playbooks to add or remote
|
||||
banner text from the active running configuration.
|
||||
- This module will configure both exec and motd banners on remote device
|
||||
running Cisco IOS XR. It allows playbooks to add or remove
|
||||
banner text from the running configuration.
|
||||
extends_documentation_fragment: iosxr
|
||||
notes:
|
||||
- Tested against IOS XR 6.1.2
|
||||
- Tested against IOS XRv 6.1.2
|
||||
options:
|
||||
banner:
|
||||
description:
|
||||
- Specifies which banner that should be
|
||||
configured on the remote device.
|
||||
- Specifies the type of banner to configure on remote device.
|
||||
required: true
|
||||
default: null
|
||||
choices: ['login', 'motd']
|
||||
text:
|
||||
description:
|
||||
- The banner text that should be
|
||||
present in the remote device running configuration. This argument
|
||||
accepts a multiline string, with no empty lines. Requires I(state=present).
|
||||
- Banner text to be configured. Accepts multiline string,
|
||||
without empty lines. Requires I(state=present).
|
||||
default: null
|
||||
state:
|
||||
description:
|
||||
- Specifies whether or not the configuration is present in the current
|
||||
devices active running configuration.
|
||||
- Existential state of the configuration on the device.
|
||||
default: present
|
||||
choices: ['present', 'absent']
|
||||
"""
|
||||
|
@ -79,60 +79,130 @@ commands:
|
|||
"""
|
||||
|
||||
import re
|
||||
import collections
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config_diff, commit_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, discard_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import build_xml, is_cliconf, is_netconf
|
||||
from ansible.module_utils.network.iosxr.iosxr import etree_find, etree_findall
|
||||
|
||||
|
||||
def map_obj_to_commands(updates, module):
|
||||
commands = list()
|
||||
want, have = updates
|
||||
state = module.params['state']
|
||||
class ConfigBase(object):
|
||||
def __init__(self, module):
|
||||
self._module = module
|
||||
self._result = {'changed': False, 'warnings': []}
|
||||
self._want = {}
|
||||
self._have = {}
|
||||
|
||||
if state == 'absent':
|
||||
if have.get('state') != 'absent' and ('text' in have.keys() and have['text']):
|
||||
commands.append('no banner %s' % module.params['banner'])
|
||||
|
||||
elif state == 'present':
|
||||
if (want['text'] and
|
||||
want['text'].encode().decode('unicode_escape').strip("'") != have.get('text')):
|
||||
banner_cmd = 'banner %s ' % module.params['banner']
|
||||
banner_cmd += want['text'].strip()
|
||||
commands.append(banner_cmd)
|
||||
|
||||
return commands
|
||||
def map_params_to_obj(self):
|
||||
text = self._module.params['text']
|
||||
if text:
|
||||
text = "{!r}".format(str(text).strip())
|
||||
self._want.update({
|
||||
'banner': self._module.params['banner'],
|
||||
'text': text,
|
||||
'state': self._module.params['state']
|
||||
})
|
||||
|
||||
|
||||
def map_config_to_obj(module):
|
||||
flags = 'banner %s' % module.params['banner']
|
||||
output = get_config(module, flags=[flags])
|
||||
class CliConfiguration(ConfigBase):
|
||||
def __init__(self, module):
|
||||
super(CliConfiguration, self).__init__(module)
|
||||
|
||||
match = re.search(r'banner (\S+) (.*)', output, re.DOTALL)
|
||||
if match:
|
||||
text = match.group(2).strip("'")
|
||||
else:
|
||||
text = None
|
||||
def map_obj_to_commands(self):
|
||||
commands = list()
|
||||
state = self._module.params['state']
|
||||
if state == 'absent':
|
||||
if self._have.get('state') != 'absent' and ('text' in self._have.keys() and self._have['text']):
|
||||
commands.append('no banner {!s}'.format(self._module.params['banner']))
|
||||
elif state == 'present':
|
||||
if (self._want['text'] and
|
||||
self._want['text'].encode().decode('unicode_escape').strip("'") != self._have.get('text')):
|
||||
banner_cmd = 'banner {!s} '.format(self._module.params['banner'])
|
||||
banner_cmd += self._want['text'].strip()
|
||||
commands.append(banner_cmd)
|
||||
self._result['commands'] = commands
|
||||
if commands:
|
||||
if not self._module.check_mode:
|
||||
load_config(self._module, commands, self._result['warnings'], commit=True)
|
||||
self._result['changed'] = True
|
||||
|
||||
obj = {'banner': module.params['banner'], 'state': 'absent'}
|
||||
def map_config_to_obj(self):
|
||||
cli_filter = 'banner {!s}'.format(self._module.params['banner'])
|
||||
output = get_config(self._module, config_filter=cli_filter)
|
||||
match = re.search(r'banner (\S+) (.*)', output, re.DOTALL)
|
||||
if match:
|
||||
text = match.group(2).strip("'")
|
||||
else:
|
||||
text = None
|
||||
obj = {'banner': self._module.params['banner'], 'state': 'absent'}
|
||||
if output:
|
||||
obj['text'] = text
|
||||
obj['state'] = 'present'
|
||||
self._have.update(obj)
|
||||
|
||||
if output:
|
||||
obj['text'] = text
|
||||
obj['state'] = 'present'
|
||||
def run(self):
|
||||
self.map_params_to_obj()
|
||||
self.map_config_to_obj()
|
||||
self.map_obj_to_commands()
|
||||
|
||||
return obj
|
||||
return self._result
|
||||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
text = module.params['text']
|
||||
if text:
|
||||
text = "%r" % (str(text).strip())
|
||||
class NCConfiguration(ConfigBase):
|
||||
def __init__(self, module):
|
||||
super(NCConfiguration, self).__init__(module)
|
||||
self._banners_meta = collections.OrderedDict()
|
||||
self._banners_meta.update([
|
||||
('banner', {'xpath': 'banners/banner', 'tag': True, 'attrib': "operation"}),
|
||||
('a:banner', {'xpath': 'banner/banner-name'}),
|
||||
('a:text', {'xpath': 'banner/banner-text', 'operation': 'edit'})
|
||||
])
|
||||
|
||||
return {
|
||||
'banner': module.params['banner'],
|
||||
'text': text,
|
||||
'state': module.params['state']
|
||||
}
|
||||
def map_obj_to_commands(self):
|
||||
state = self._module.params['state']
|
||||
_get_filter = build_xml('banners', xmap=self._banners_meta, params=self._module.params, opcode="filter")
|
||||
|
||||
running = get_config(self._module, source='running', config_filter=_get_filter)
|
||||
|
||||
banner_name = None
|
||||
banner_text = None
|
||||
if etree_find(running, 'banner-text') is not None:
|
||||
banner_name = etree_find(running, 'banner-name').text
|
||||
banner_text = etree_find(running, 'banner-text').text
|
||||
|
||||
opcode = None
|
||||
if state == 'absent' and banner_name == self._module.params['banner'] and len(banner_text):
|
||||
opcode = "delete"
|
||||
elif state == 'present':
|
||||
opcode = 'merge'
|
||||
|
||||
self._result['commands'] = []
|
||||
if opcode:
|
||||
_edit_filter = build_xml('banners', xmap=self._banners_meta, params=self._module.params, opcode=opcode)
|
||||
|
||||
if _edit_filter is not None:
|
||||
if not self._module.check_mode:
|
||||
load_config(self._module, _edit_filter, self._result['warnings'])
|
||||
candidate = get_config(self._module, source='candidate', config_filter=_get_filter)
|
||||
|
||||
diff = get_config_diff(self._module, running, candidate)
|
||||
if diff:
|
||||
commit_config(self._module)
|
||||
self._result['changed'] = True
|
||||
self._result['commands'] = _edit_filter
|
||||
if self._module._diff:
|
||||
self._result['diff'] = {'prepared': diff}
|
||||
else:
|
||||
discard_config(self._module)
|
||||
|
||||
def run(self):
|
||||
self.map_params_to_obj()
|
||||
self.map_obj_to_commands()
|
||||
|
||||
return self._result
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -152,23 +222,13 @@ def main():
|
|||
required_if=required_if,
|
||||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False}
|
||||
result['warnings'] = warnings
|
||||
|
||||
want = map_params_to_obj(module)
|
||||
have = map_config_to_obj(module)
|
||||
|
||||
commands = map_obj_to_commands((want, have), module)
|
||||
result['commands'] = commands
|
||||
|
||||
if commands:
|
||||
if not module.check_mode:
|
||||
load_config(module, commands, result['warnings'], commit=True)
|
||||
result['changed'] = True
|
||||
if is_cliconf(module):
|
||||
module.deprecate("cli support for 'iosxr_banner' is deprecated. Use transport netconf instead', version='4 releases from v2.5")
|
||||
config_object = CliConfiguration(module)
|
||||
elif is_netconf(module):
|
||||
config_object = NCConfiguration(module)
|
||||
|
||||
result = config_object.run()
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ tasks:
|
|||
commands:
|
||||
- show version
|
||||
- show interfaces
|
||||
- [{ command: example command that prompts, prompt: expected prompt, answer: yes}]
|
||||
|
||||
- name: run multiple commands and evaluate the output
|
||||
iosxr_command:
|
||||
|
@ -125,9 +126,9 @@ failed_conditions:
|
|||
import time
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import run_commands, iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import run_command, iosxr_argument_spec
|
||||
from ansible.module_utils.network.iosxr.iosxr import command_spec
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.network.common.utils import ComplexList
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
@ -140,27 +141,27 @@ def to_lines(stdout):
|
|||
|
||||
|
||||
def parse_commands(module, warnings):
|
||||
command = ComplexList(dict(
|
||||
command=dict(key=True),
|
||||
prompt=dict(),
|
||||
answer=dict()
|
||||
), module)
|
||||
commands = command(module.params['commands'])
|
||||
|
||||
commands = module.params['commands']
|
||||
for item in list(commands):
|
||||
if module.check_mode and not item['command'].startswith('show'):
|
||||
try:
|
||||
command = item['command']
|
||||
except Exception:
|
||||
command = item
|
||||
if module.check_mode and not command.startswith('show'):
|
||||
warnings.append(
|
||||
'only show commands are supported when using check mode, not '
|
||||
'executing `%s`' % item['command']
|
||||
'executing `%s`' % command
|
||||
)
|
||||
commands.remove(item)
|
||||
elif item['command'].startswith('conf'):
|
||||
elif command.startswith('conf'):
|
||||
module.fail_json(
|
||||
msg='iosxr_command does not support running config mode '
|
||||
'commands. Please use iosxr_config instead'
|
||||
)
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
def main():
|
||||
spec = dict(
|
||||
commands=dict(type='list', required=True),
|
||||
|
@ -174,11 +175,12 @@ def main():
|
|||
|
||||
spec.update(iosxr_argument_spec)
|
||||
|
||||
spec.update(command_spec)
|
||||
|
||||
module = AnsibleModule(argument_spec=spec,
|
||||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
commands = parse_commands(module, warnings)
|
||||
|
||||
|
@ -190,7 +192,7 @@ def main():
|
|||
match = module.params['match']
|
||||
|
||||
while retries > 0:
|
||||
responses = run_commands(module, commands)
|
||||
responses = run_command(module, commands)
|
||||
|
||||
for item in list(conditionals):
|
||||
if item(responses):
|
||||
|
@ -210,7 +212,6 @@ def main():
|
|||
msg = 'One or more conditional statements have not be satisfied'
|
||||
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
||||
|
||||
|
||||
result = {
|
||||
'changed': False,
|
||||
'stdout': responses,
|
||||
|
|
|
@ -180,9 +180,8 @@ backup_path:
|
|||
sample: /playbooks/ansible/backup/iosxr01.2016-07-16@22:28:34
|
||||
"""
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import load_config,get_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import load_config, get_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
from ansible.module_utils.network.iosxr.iosxr import check_args as iosxr_check_args
|
||||
from ansible.module_utils.network.common.config import NetworkConfig, dumps
|
||||
|
||||
|
||||
|
@ -190,7 +189,6 @@ DEFAULT_COMMIT_COMMENT = 'configured by iosxr_config'
|
|||
|
||||
|
||||
def check_args(module, warnings):
|
||||
iosxr_check_args(module, warnings)
|
||||
if module.params['comment']:
|
||||
if len(module.params['comment']) > 60:
|
||||
module.fail_json(msg='comment argument cannot be more than 60 characters')
|
||||
|
@ -216,6 +214,7 @@ def get_candidate(module):
|
|||
candidate.add(module.params['lines'], parents=parents)
|
||||
return candidate
|
||||
|
||||
|
||||
def run(module, result):
|
||||
match = module.params['match']
|
||||
replace = module.params['replace']
|
||||
|
@ -231,7 +230,7 @@ def run(module, result):
|
|||
contents = get_running_config(module)
|
||||
configobj = NetworkConfig(contents=contents, indent=1)
|
||||
commands = candidate.difference(configobj, path=path, match=match,
|
||||
replace=replace)
|
||||
replace=replace)
|
||||
else:
|
||||
commands = candidate.items
|
||||
|
||||
|
@ -253,6 +252,7 @@ def run(module, result):
|
|||
result['diff'] = dict(prepared=diff)
|
||||
result['changed'] = True
|
||||
|
||||
|
||||
def main():
|
||||
"""main entry point for module execution
|
||||
"""
|
||||
|
|
|
@ -115,7 +115,7 @@ ansible_net_neighbors:
|
|||
import re
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args, run_commands
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, run_command
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.six.moves import zip
|
||||
|
||||
|
@ -166,7 +166,7 @@ class Hardware(FactsBase):
|
|||
results['dir /all'])
|
||||
|
||||
match = re.search(r'Physical Memory: (\d+)M total \((\d+)',
|
||||
results['show memory summary'])
|
||||
results['show memory summary'])
|
||||
if match:
|
||||
self.facts['memtotal_mb'] = match.group(1)
|
||||
self.facts['memfree_mb'] = match.group(2)
|
||||
|
@ -188,7 +188,7 @@ class Interfaces(FactsBase):
|
|||
|
||||
def commands(self):
|
||||
return(['show interfaces', 'show ipv6 interface',
|
||||
'show lldp', 'show lldp neighbors detail'])
|
||||
'show lldp', 'show lldp neighbors detail'])
|
||||
|
||||
def populate(self, results):
|
||||
self.facts['all_ipv4_addresses'] = list()
|
||||
|
@ -360,7 +360,6 @@ def main():
|
|||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
gather_subset = module.params['gather_subset']
|
||||
|
||||
|
@ -405,7 +404,7 @@ def main():
|
|||
try:
|
||||
for inst in instances:
|
||||
commands = inst.commands()
|
||||
responses = run_commands(module, commands)
|
||||
responses = run_command(module, commands)
|
||||
results = dict(zip(commands, responses))
|
||||
inst.populate(results)
|
||||
facts.update(inst.facts)
|
||||
|
|
|
@ -22,6 +22,7 @@ short_description: Manage Interface on Cisco IOS XR network devices
|
|||
description:
|
||||
- This module provides declarative management of Interfaces
|
||||
on Cisco IOS XR network devices.
|
||||
extends_documentation_fragment: iosxr
|
||||
notes:
|
||||
- Tested against IOS XR 6.1.2
|
||||
options:
|
||||
|
@ -142,7 +143,7 @@ from ansible.module_utils._text import to_text
|
|||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
from ansible.module_utils.network.common.utils import conditional, remove_default_spec
|
||||
|
||||
|
||||
|
@ -228,7 +229,7 @@ def map_params_to_obj(module):
|
|||
|
||||
|
||||
def map_config_to_obj(module):
|
||||
data = get_config(module, flags=['interface'])
|
||||
data = get_config(module, config_filter='interface')
|
||||
interfaces = data.strip().rstrip('!').split('!')
|
||||
|
||||
if not interfaces:
|
||||
|
@ -387,7 +388,6 @@ def main():
|
|||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False}
|
||||
|
||||
|
@ -402,7 +402,6 @@ def main():
|
|||
if commands:
|
||||
if not module.check_mode:
|
||||
load_config(module, commands, result['warnings'], commit=True)
|
||||
exec_command(module, 'exit')
|
||||
result['changed'] = True
|
||||
|
||||
failed_conditions = check_declarative_intent_params(module, want, result)
|
||||
|
|
|
@ -21,6 +21,7 @@ short_description: Manage logging on network devices
|
|||
description:
|
||||
- This module provides declarative management of logging
|
||||
on Cisco IOS XR devices.
|
||||
extends_documentation_fragment: iosxr
|
||||
notes:
|
||||
- Tested against IOS XR 6.1.2
|
||||
options:
|
||||
|
@ -114,7 +115,7 @@ from copy import deepcopy
|
|||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
from ansible.module_utils.network.common.utils import remove_default_spec
|
||||
|
||||
|
||||
|
@ -237,7 +238,7 @@ def map_config_to_obj(module):
|
|||
obj = []
|
||||
dest_group = ('console', 'hostnameprefix', 'monitor', 'buffered', 'on')
|
||||
|
||||
data = get_config(module, flags=['logging'])
|
||||
data = get_config(module, config_filter='logging')
|
||||
lines = data.split("\n")
|
||||
|
||||
for line in lines:
|
||||
|
@ -349,7 +350,6 @@ def main():
|
|||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ options:
|
|||
description:
|
||||
- netconf vrf name
|
||||
required: false
|
||||
default: none
|
||||
default: default
|
||||
state:
|
||||
description:
|
||||
- Specifies the state of the C(iosxr_netconf) resource on
|
||||
|
@ -75,7 +75,7 @@ import re
|
|||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.six import iteritems
|
||||
|
||||
|
@ -90,16 +90,12 @@ def map_obj_to_commands(updates, module):
|
|||
if have['state'] == 'present':
|
||||
commands.append('no netconf-yang agent ssh')
|
||||
|
||||
if 'netconf_port' in have:
|
||||
commands.append('no ssh server netconf port %s' % have['netconf_port'])
|
||||
if 'netconf_port' in have:
|
||||
commands.append('no ssh server netconf port %s' % have['netconf_port'])
|
||||
|
||||
if want['netconf_vrf']:
|
||||
for vrf in have['netconf_vrf']:
|
||||
if vrf == want['netconf_vrf']:
|
||||
commands.append('no ssh server netconf vrf %s' % vrf)
|
||||
else:
|
||||
for vrf in have['netconf_vrf']:
|
||||
commands.append('no ssh server netconf vrf %s' % vrf)
|
||||
if have['netconf_vrf']:
|
||||
for vrf in have['netconf_vrf']:
|
||||
commands.append('no ssh server netconf vrf %s' % vrf)
|
||||
else:
|
||||
if have['state'] == 'absent':
|
||||
commands.append('netconf-yang agent ssh')
|
||||
|
@ -131,9 +127,9 @@ def parse_port(config):
|
|||
def map_config_to_obj(module):
|
||||
obj = {'state': 'absent'}
|
||||
|
||||
netconf_config = get_config(module, flags=['netconf-yang agent'])
|
||||
netconf_config = get_config(module, config_filter='netconf-yang agent')
|
||||
|
||||
ssh_config = get_config(module, flags=['ssh server'])
|
||||
ssh_config = get_config(module, config_filter='ssh server')
|
||||
ssh_config = [config_line for config_line in (line.strip() for line in ssh_config.splitlines()) if config_line]
|
||||
obj['netconf_vrf'] = []
|
||||
for config in ssh_config:
|
||||
|
@ -141,7 +137,7 @@ def map_config_to_obj(module):
|
|||
obj.update({'netconf_port': parse_port(config)})
|
||||
if 'netconf vrf' in config:
|
||||
obj['netconf_vrf'].append(parse_vrf(config))
|
||||
if 'ssh' in netconf_config or 'netconf_port' in obj or obj['netconf_vrf']:
|
||||
if 'ssh' in netconf_config and ('netconf_port' in obj or obj['netconf_vrf']):
|
||||
obj.update({'state': 'present'})
|
||||
|
||||
if 'ssh' in netconf_config and 'netconf_port' not in obj:
|
||||
|
@ -176,7 +172,7 @@ def main():
|
|||
"""
|
||||
argument_spec = dict(
|
||||
netconf_port=dict(type='int', default=830, aliases=['listens_on']),
|
||||
netconf_vrf=dict(aliases=['vrf']),
|
||||
netconf_vrf=dict(aliases=['vrf'], default='default'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
)
|
||||
argument_spec.update(iosxr_argument_spec)
|
||||
|
@ -185,7 +181,6 @@ def main():
|
|||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False, 'warnings': warnings}
|
||||
|
||||
|
@ -197,10 +192,6 @@ def main():
|
|||
if commands:
|
||||
if not module.check_mode:
|
||||
diff = load_config(module, commands, result['warnings'], commit=True)
|
||||
if diff:
|
||||
if module._diff:
|
||||
result['diff'] = {'prepared': diff}
|
||||
exec_command(module, 'exit')
|
||||
result['changed'] = True
|
||||
|
||||
module.exit_json(**result)
|
||||
|
|
|
@ -108,18 +108,21 @@ import re
|
|||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
|
||||
|
||||
def diff_list(want, have):
|
||||
adds = set(want).difference(have)
|
||||
removes = set(have).difference(want)
|
||||
return (adds, removes)
|
||||
|
||||
|
||||
def map_obj_to_commands(want, have, module):
|
||||
commands = list()
|
||||
state = module.params['state']
|
||||
|
||||
needs_update = lambda x: want.get(x) and (want.get(x) != have.get(x))
|
||||
def needs_update(x):
|
||||
return want.get(x) and (want.get(x) != have.get(x))
|
||||
|
||||
if state == 'absent':
|
||||
if have['hostname'] != 'ios':
|
||||
|
@ -167,20 +170,24 @@ def map_obj_to_commands(want, have, module):
|
|||
|
||||
return commands
|
||||
|
||||
|
||||
def parse_hostname(config):
|
||||
match = re.search(r'^hostname (\S+)', config, re.M)
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_domain_name(config):
|
||||
match = re.search(r'^domain name (\S+)', config, re.M)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_lookup_source(config):
|
||||
match = re.search(r'^domain lookup source-interface (\S+)', config, re.M)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def map_config_to_obj(module):
|
||||
config = get_config(module)
|
||||
return {
|
||||
|
@ -192,6 +199,7 @@ def map_config_to_obj(module):
|
|||
'name_servers': re.findall(r'^domain name-server (\S+)', config, re.M)
|
||||
}
|
||||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
return {
|
||||
'hostname': module.params['hostname'],
|
||||
|
@ -202,6 +210,7 @@ def map_params_to_obj(module):
|
|||
'name_servers': module.params['name_servers']
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
""" Main entry point for Ansible module execution
|
||||
"""
|
||||
|
@ -223,7 +232,6 @@ def main():
|
|||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False, 'warnings': warnings}
|
||||
|
||||
|
@ -240,5 +248,6 @@ def main():
|
|||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -26,6 +26,7 @@ description:
|
|||
either individual usernames or the aggregate of usernames in the
|
||||
current running config. It also supports purging usernames from the
|
||||
configuration that are not explicitly defined.
|
||||
extends_documentation_fragment: iosxr
|
||||
notes:
|
||||
- Tested against IOS XR 6.1.2
|
||||
options:
|
||||
|
@ -166,7 +167,7 @@ from copy import deepcopy
|
|||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.common.utils import remove_default_spec
|
||||
from ansible.module_utils.network.iosxr.iosxr import get_config, load_config
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec, check_args
|
||||
from ansible.module_utils.network.iosxr.iosxr import iosxr_argument_spec
|
||||
|
||||
try:
|
||||
from base64 import b64decode
|
||||
|
@ -228,7 +229,7 @@ def map_obj_to_commands(updates, module):
|
|||
|
||||
|
||||
def map_config_to_obj(module):
|
||||
data = get_config(module, flags=['username'])
|
||||
data = get_config(module, config_filter='username')
|
||||
users = data.strip().rstrip('!').split('!')
|
||||
|
||||
if not users:
|
||||
|
@ -453,8 +454,6 @@ def main():
|
|||
'To set a user password use "configured_password" instead.'
|
||||
)
|
||||
|
||||
check_args(module, warnings)
|
||||
|
||||
result = {'changed': False}
|
||||
|
||||
want = map_params_to_obj(module)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue