def map_config_to_obj(module): obj = {'state': 'absent'} netconf_config = get_config(module, config_filter='netconf-yang agent') 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: if 'netconf port' in config: obj.update({'netconf_port': parse_port(config)}) if 'netconf vrf' in config: obj['netconf_vrf'].append(parse_vrf(config)) 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: obj.update({'netconf_port': 830}) return obj
def main(): """main entry point for module execution """ backup_spec = dict(filename=dict(), dir_path=dict(type='path')) argument_spec = dict( src=dict(type='path'), lines=dict(aliases=['commands'], type='list'), parents=dict(type='list'), before=dict(type='list'), after=dict(type='list'), match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), replace=dict(default='line', choices=['line', 'block', 'config']), # this argument is deprecated in favor of setting match: none # it will be removed in a future version force=dict(default=False, type='bool'), config=dict(), backup=dict(type='bool', default=False), backup_options=dict(type='dict', options=backup_spec), comment=dict(default=DEFAULT_COMMIT_COMMENT), admin=dict(type='bool', default=False), exclusive=dict(type='bool', default=False), label=dict()) argument_spec.update(iosxr_argument_spec) mutually_exclusive = [('lines', 'src'), ('parents', 'src')] required_if = [('match', 'strict', ['lines']), ('match', 'exact', ['lines']), ('replace', 'block', ['lines']), ('replace', 'config', ['src'])] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_if=required_if, supports_check_mode=True) if module.params['force'] is True: module.params['match'] = 'none' warnings = list() check_args(module, warnings) result = dict(changed=False, warnings=warnings) if module.params['backup']: result['__backup__'] = get_config(module) if any((module.params['src'], module.params['lines'])): run(module, result) module.exit_json(**result)
def map_config_to_obj(self): cli_filter = 'banner {0!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)
def map_config_to_obj(self): config = get_config(self._module) self._have.update({ 'hostname': self.parse_hostname(config), 'domain_name': self.parse_domain_name(config), 'domain_search': re.findall(r'^domain list (\S+)', config, re.M), 'lookup_source': self.parse_lookup_source(config), 'lookup_enabled': 'domain lookup disable' not in config, 'name_servers': re.findall(r'^domain name-server (\S+)', config, re.M) })
def map_obj_to_xml_rpc(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['xml'] = [] if opcode: _edit_filter = build_xml('banners', xmap=self._banners_meta, params=self._module.params, opcode=opcode) if _edit_filter is not None: commit = not self._module.check_mode diff = load_config(self._module, _edit_filter, commit=commit, running=running, nc_get_filter=_get_filter) if diff: self._result['xml'] = _edit_filter if self._module._diff: self._result['diff'] = dict(prepared=diff) self._result['changed'] = True
def map_config_to_obj(self): data = get_config(self._module, config_filter='interface') data_lines = data.splitlines() start_indexes = [ i for i, e in enumerate(data_lines) if e.startswith('interface') ] end_indexes = [i for i, e in enumerate(data_lines) if e == '!'] intf_configs = list() for start_index, end_index in zip(start_indexes, end_indexes): intf_configs.append( [i.strip() for i in data_lines[start_index:end_index]]) if not intf_configs: return list() for intf_config in intf_configs: name = intf_config[0].strip().split()[1] active = 'act' if name == 'preconfigure': active = 'pre' name = intf_config[0].strip().split()[2] obj = { 'name': name, 'description': self.parse_config_argument(intf_config, 'description'), 'speed': self.parse_config_argument(intf_config, 'speed'), 'duplex': self.parse_config_argument(intf_config, 'duplex'), 'mtu': self.parse_config_argument(intf_config, 'mtu'), 'enabled': not bool(self.parse_shutdown(intf_config)), 'active': active, 'state': 'present' } self._have.append(obj)
def map_config_to_obj(self): data = get_config(self._module, config_filter='username') users = data.strip().rstrip('!').split('!') for user in users: user_config = user.strip().splitlines() name = user_config[0].strip().split()[1] group = None if len(user_config) > 1: group_or_secret = user_config[1].strip().split() if group_or_secret[0] == 'group': group = group_or_secret[1] obj = { 'name': name, 'state': 'present', 'configured_password': None, 'group': group } self._have.append(obj)
def map_config_to_obj(self): data = get_config(self._module, config_filter='logging') lines = data.split("\n") for line in lines: match = re.search(r'logging (\S+)', line, re.M) if match: dest = self.parse_dest(line, match.group(1)) name = self.parse_name(line, dest) if dest == 'host' and name is not None: self._host_list.add(name) if dest == 'file' and name is not None: self._file_list.add(name) self._have.append({ 'dest': dest, 'name': name, 'size': self.parse_size(line, dest), 'facility': self.parse_facility(line), 'level': self.parse_level(line, dest), 'vrf': self.parse_vrf(line, dest), 'hostnameprefix': self.parse_hostnameprefix(line), })
def map_obj_to_xml_rpc(self): self._locald_meta.update([ ('aaa_locald', { 'xpath': 'aaa/usernames', 'tag': True, 'ns': True }), ('username', { 'xpath': 'aaa/usernames/username', 'tag': True, 'attrib': "operation" }), ('a:name', { 'xpath': 'aaa/usernames/username/name' }), ('a:configured_password', { 'xpath': 'aaa/usernames/username/secret', 'operation': 'edit' }), ]) self._locald_group_meta.update([ ('aaa_locald', { 'xpath': 'aaa/usernames', 'tag': True, 'ns': True }), ('username', { 'xpath': 'aaa/usernames/username', 'tag': True, 'attrib': "operation" }), ('a:name', { 'xpath': 'aaa/usernames/username/name' }), ('usergroups', { 'xpath': 'aaa/usernames/username/usergroup-under-usernames', 'tag': True, 'operation': 'edit' }), ('usergroup', { 'xpath': 'aaa/usernames/username/usergroup-under-usernames/usergroup-under-username', 'tag': True, 'operation': 'edit' }), ('a:group', { 'xpath': 'aaa/usernames/username/usergroup-under-usernames/usergroup-under-username/name', 'operation': 'edit' }), ]) state = self._module.params['state'] _get_filter = build_xml('aaa', opcode="filter") running = get_config(self._module, source='running', config_filter=_get_filter) elements = etree_findall(running, 'username') users = list() for element in elements: name_list = etree_findall(element, 'name') users.append(name_list[0].text) list_size = len(name_list) if list_size == 1: self._have.append({ 'name': name_list[0].text, 'group': None, 'groups': None }) elif list_size == 2: self._have.append({ 'name': name_list[0].text, 'group': name_list[1].text, 'groups': None }) elif list_size > 2: name_iter = iter(name_list) next(name_iter) tmp_list = list() for name in name_iter: tmp_list.append(name.text) self._have.append({ 'name': name_list[0].text, 'group': None, 'groups': tmp_list }) locald_params = list() locald_group_params = list() opcode = None if state == 'absent': opcode = "delete" for want_item in self._want: if want_item['name'] in users: want_item['configured_password'] = None locald_params.append(want_item) elif state == 'present': opcode = "merge" for want_item in self._want: if want_item['name'] not in users: want_item['configured_password'] = self.generate_md5_hash( want_item['configured_password']) locald_params.append(want_item) if want_item['group'] is not None: locald_group_params.append(want_item) if want_item['groups'] is not None: for group in want_item['groups']: want_item['group'] = group locald_group_params.append(want_item.copy()) else: if self._module.params[ 'update_password'] == 'always' and want_item[ 'configured_password'] is not None: want_item[ 'configured_password'] = self.generate_md5_hash( want_item['configured_password']) locald_params.append(want_item) else: want_item['configured_password'] = None obj_in_have = search_obj_in_list(want_item['name'], self._have) if want_item['group'] is not None and want_item[ 'group'] != obj_in_have['group']: locald_group_params.append(want_item) elif want_item['groups'] is not None: for group in want_item['groups']: want_item['group'] = group locald_group_params.append(want_item.copy()) purge_params = list() if self._module.params['purge']: want_users = [x['name'] for x in self._want] have_users = [x['name'] for x in self._have] for item in set(have_users).difference(set(want_users)): if item != 'admin': purge_params.append({'name': item}) self._result['xml'] = [] _edit_filter_list = list() if opcode is not None: if locald_params: _edit_filter_list.append( build_xml('aaa', xmap=self._locald_meta, params=locald_params, opcode=opcode)) if locald_group_params: _edit_filter_list.append( build_xml('aaa', xmap=self._locald_group_meta, params=locald_group_params, opcode=opcode)) if purge_params: _edit_filter_list.append( build_xml('aaa', xmap=self._locald_meta, params=purge_params, opcode="delete")) diff = None if _edit_filter_list: commit = not self._module.check_mode diff = load_config(self._module, _edit_filter_list, commit=commit, running=running, nc_get_filter=_get_filter) if diff: if self._module._diff: self._result['diff'] = dict(prepared=diff) self._result['xml'] = _edit_filter_list self._result['changed'] = True
def get_running_config(module): contents = module.params['config'] if not contents: contents = get_config(module) return contents
def map_obj_to_xml_rpc(self): self._intf_meta.update([ ('interface-configuration', { 'xpath': 'interface-configurations/interface-configuration', 'tag': True, 'attrib': 'operation' }), ('a:active', { 'xpath': 'interface-configurations/interface-configuration/active', 'operation': 'edit' }), ('a:name', { 'xpath': 'interface-configurations/interface-configuration/interface-name' }), ('a:description', { 'xpath': 'interface-configurations/interface-configuration/description', 'operation': 'edit' }), ('mtus', { 'xpath': 'interface-configurations/interface-configuration/mtus', 'tag': True, 'operation': 'edit' }), ('mtu', { 'xpath': 'interface-configurations/interface-configuration/mtus/mtu', 'tag': True, 'operation': 'edit' }), ('a:owner', { 'xpath': 'interface-configurations/interface-configuration/mtus/mtu/owner', 'operation': 'edit' }), ('a:mtu', { 'xpath': 'interface-configurations/interface-configuration/mtus/mtu/mtu', 'operation': 'edit' }), ('CEthernet', { 'xpath': 'interface-configurations/interface-configuration/ethernet', 'tag': True, 'operation': 'edit', 'ns': True }), ('a:speed', { 'xpath': 'interface-configurations/interface-configuration/ethernet/speed', 'operation': 'edit' }), ('a:duplex', { 'xpath': 'interface-configurations/interface-configuration/ethernet/duplex', 'operation': 'edit' }), ]) self._shut_meta.update([ ('interface-configuration', { 'xpath': 'interface-configurations/interface-configuration', 'tag': True }), ('a:active', { 'xpath': 'interface-configurations/interface-configuration/active', 'operation': 'edit' }), ('a:name', { 'xpath': 'interface-configurations/interface-configuration/interface-name' }), ('shutdown', { 'xpath': 'interface-configurations/interface-configuration/shutdown', 'tag': True, 'operation': 'edit', 'attrib': 'operation' }), ]) state = self._module.params['state'] _get_filter = build_xml('interface-configurations', xmap=self._intf_meta, params=self._want, opcode="filter") running = get_config(self._module, source='running', config_filter=_get_filter) intfcfg_nodes = etree_findall(running, 'interface-configuration') intf_list = set() shut_list = set() for item in intfcfg_nodes: intf_name = etree_find(item, 'interface-name').text if intf_name is not None: intf_list.add(intf_name) if etree_find(item, 'shutdown') is not None: shut_list.add(intf_name) intf_params = list() shut_params = list() noshut_params = list() for index, item in enumerate(self._want): if item['name'] in intf_list: intf_params.append(item) if not item['enabled']: shut_params.append(item) if item['name'] in shut_list and item['enabled']: noshut_params.append(item) opcode = None if state == 'absent': if intf_params: opcode = "delete" elif state in ('present', 'up', 'down'): intf_params = self._want opcode = 'merge' self._result['xml'] = [] _edit_filter_list = list() if opcode: _edit_filter_list.append( build_xml('interface-configurations', xmap=self._intf_meta, params=intf_params, opcode=opcode)) if opcode == 'merge': if len(shut_params): _edit_filter_list.append( build_xml('interface-configurations', xmap=self._shut_meta, params=shut_params, opcode='merge')) if len(noshut_params): _edit_filter_list.append( build_xml('interface-configurations', xmap=self._shut_meta, params=noshut_params, opcode='delete')) diff = None if len(_edit_filter_list): commit = not self._module.check_mode diff = load_config(self._module, _edit_filter_list, commit=commit, running=running, nc_get_filter=_get_filter) if diff: if self._module._diff: self._result['diff'] = dict(prepared=diff) self._result['xml'] = _edit_filter_list self._result['changed'] = True
def map_obj_to_xml_rpc(self): self._log_file_meta.update([ ('files', {'xpath': 'syslog/files', 'tag': True, 'operation': 'edit'}), ('file', {'xpath': 'syslog/files/file', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:name', {'xpath': 'syslog/files/file/file-name', 'operation': 'edit'}), ('file-attrib', {'xpath': 'syslog/files/file/file-log-attributes', 'tag': True, 'operation': 'edit'}), ('a:size', {'xpath': 'syslog/files/file/file-log-attributes/max-file-size', 'operation': 'edit'}), ('a:level', {'xpath': 'syslog/files/file/file-log-attributes/severity', 'operation': 'edit'}), ]) self._log_host_meta.update([ ('host-server', {'xpath': 'syslog/host-server', 'tag': True, 'operation': 'edit'}), ('vrfs', {'xpath': 'syslog/host-server/vrfs', 'tag': True, 'operation': 'edit'}), ('vrf', {'xpath': 'syslog/host-server/vrfs/vrf', 'tag': True, 'operation': 'edit'}), ('a:vrf', {'xpath': 'syslog/host-server/vrfs/vrf/vrf-name', 'operation': 'edit'}), ('ipv4s', {'xpath': 'syslog/host-server/vrfs/vrf/ipv4s', 'tag': True, 'operation': 'edit'}), ('ipv4', {'xpath': 'syslog/host-server/vrfs/vrf/ipv4s/ipv4', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:name', {'xpath': 'syslog/host-server/vrfs/vrf/ipv4s/ipv4/address', 'operation': 'edit'}), ('ipv4-sev', {'xpath': 'syslog/host-server/vrfs/vrf/ipv4s/ipv4/ipv4-severity-port', 'tag': True, 'operation': 'edit'}), ('a:level', {'xpath': 'syslog/host-server/vrfs/vrf/ipv4s/ipv4/ipv4-severity-port/severity', 'operation': 'edit'}), ]) self._log_console_meta.update([ ('a:enable-console', {'xpath': 'syslog/enable-console-logging', 'operation': 'edit', 'attrib': "operation"}), ('console', {'xpath': 'syslog/console-logging', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:console-level', {'xpath': 'syslog/console-logging/logging-level', 'operation': 'edit'}), ]) self._log_monitor_meta.update([ ('monitor', {'xpath': 'syslog/monitor-logging', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:monitor-level', {'xpath': 'syslog/monitor-logging/logging-level', 'operation': 'edit'}), ]) self._log_buffered_size_meta.update([ ('buffered', {'xpath': 'syslog/buffered-logging', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:size', {'xpath': 'syslog/buffered-logging/buffer-size', 'operation': 'edit'}), ]) self._log_buffered_level_meta.update([ ('buffered', {'xpath': 'syslog/buffered-logging', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:level', {'xpath': 'syslog/buffered-logging/logging-level', 'operation': 'edit'}), ]) self._log_facility_meta.update([ ('facility', {'xpath': 'syslog/logging-facilities', 'tag': True, 'operation': 'edit', 'attrib': "operation"}), ('a:facility', {'xpath': 'syslog/logging-facilities/facility-level', 'operation': 'edit'}), ]) self._log_prefix_meta.update([ ('a:hostnameprefix', {'xpath': 'syslog/host-name-prefix', 'operation': 'edit', 'attrib': "operation"}), ]) state = self._module.params['state'] _get_filter = build_xml('syslog', opcode="filter") running = get_config(self._module, source='running', config_filter=_get_filter) file_ele = etree_findall(running, 'file') file_list = list() if len(file_ele): for file in file_ele: file_name = etree_find(file, 'file-name') file_list.append(file_name.text if file_name is not None else None) vrf_ele = etree_findall(running, 'vrf') host_list = list() for vrf in vrf_ele: host_ele = etree_findall(vrf, 'ipv4') for host in host_ele: host_name = etree_find(host, 'address') host_list.append(host_name.text if host_name is not None else None) console_ele = etree_find(running, 'console-logging') console_level = etree_find(console_ele, 'logging-level') if console_ele is not None else None have_console = console_level.text if console_level is not None else None monitor_ele = etree_find(running, 'monitor-logging') monitor_level = etree_find(monitor_ele, 'logging-level') if monitor_ele is not None else None have_monitor = monitor_level.text if monitor_level is not None else None buffered_ele = etree_find(running, 'buffered-logging') buffered_size = etree_find(buffered_ele, 'buffer-size') if buffered_ele is not None else None have_buffered = buffered_size.text if buffered_size is not None else None facility_ele = etree_find(running, 'logging-facilities') facility_level = etree_find(facility_ele, 'facility-level') if facility_ele is not None else None have_facility = facility_level.text if facility_level is not None else None prefix_ele = etree_find(running, 'host-name-prefix') have_prefix = prefix_ele.text if prefix_ele is not None else None file_params = list() host_params = list() console_params = dict() monitor_params = dict() buffered_params = dict() facility_params = dict() prefix_params = dict() opcode = None if state == 'absent': opcode = "delete" for item in self._want: if item['dest'] == 'file' and item['name'] in file_list: item['level'] = severity_level[item['level']] file_params.append(item) elif item['dest'] == 'host' and item['name'] in host_list: item['level'] = severity_level[item['level']] host_params.append(item) elif item['dest'] == 'console' and have_console: console_params.update({'console-level': item['level']}) elif item['dest'] == 'monitor' and have_monitor: monitor_params.update({'monitor-level': item['level']}) elif item['dest'] == 'buffered' and have_buffered: buffered_params['size'] = str(item['size']) if item['size'] else None buffered_params['level'] = item['level'] if item['level'] else None elif item['dest'] is None and item['hostnameprefix'] is None and \ item['facility'] is not None and have_facility: facility_params.update({'facility': item['facility']}) elif item['dest'] is None and item['hostnameprefix'] is not None and have_prefix: prefix_params.update({'hostnameprefix': item['hostnameprefix']}) elif state == 'present': opcode = 'merge' for item in self._want: if item['dest'] == 'file': item['level'] = severity_level[item['level']] file_params.append(item) elif item['dest'] == 'host': item['level'] = severity_level[item['level']] host_params.append(item) elif item['dest'] == 'console': console_params.update({'console-level': item['level']}) elif item['dest'] == 'monitor': monitor_params.update({'monitor-level': item['level']}) elif item['dest'] == 'buffered': buffered_params['size'] = str(item['size']) if item['size'] else None buffered_params['level'] = item['level'] if item['level'] else None elif item['dest'] is None and item['hostnameprefix'] is None and \ item['facility'] is not None: facility_params.update({'facility': item['facility']}) elif item['dest'] is None and item['hostnameprefix'] is not None: prefix_params.update({'hostnameprefix': item['hostnameprefix']}) self._result['xml'] = [] _edit_filter_list = list() if opcode: if len(file_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_file_meta, params=file_params, opcode=opcode)) if len(host_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_host_meta, params=host_params, opcode=opcode)) if len(console_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_console_meta, params=console_params, opcode=opcode)) if len(monitor_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_monitor_meta, params=monitor_params, opcode=opcode)) if len(buffered_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_buffered_size_meta, params=buffered_params, opcode=opcode)) _edit_filter_list.append(build_xml('syslog', xmap=self._log_buffered_level_meta, params=buffered_params, opcode=opcode)) if len(facility_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_facility_meta, params=facility_params, opcode=opcode)) if len(prefix_params): _edit_filter_list.append(build_xml('syslog', xmap=self._log_prefix_meta, params=prefix_params, opcode=opcode)) diff = None if len(_edit_filter_list): commit = not self._module.check_mode diff = load_config(self._module, _edit_filter_list, commit=commit, running=running, nc_get_filter=_get_filter) if diff: if self._module._diff: self._result['diff'] = dict(prepared=diff) self._result['xml'] = _edit_filter_list self._result['changed'] = True
def map_obj_to_xml_rpc(self): self._system_meta.update([ ('vrfs', { 'xpath': 'ip-domain/vrfs', 'tag': True, 'operation': 'edit' }), ('vrf', { 'xpath': 'ip-domain/vrfs/vrf', 'tag': True, 'operation': 'edit' }), ('a:vrf', { 'xpath': 'ip-domain/vrfs/vrf/vrf-name', 'operation': 'edit' }), ('a:domain_name', { 'xpath': 'ip-domain/vrfs/vrf/name', 'operation': 'edit', 'attrib': "operation" }), ]) self._system_domain_meta.update([ ('vrfs', { 'xpath': 'ip-domain/vrfs', 'tag': True, 'operation': 'edit' }), ('vrf', { 'xpath': 'ip-domain/vrfs/vrf', 'tag': True, 'operation': 'edit' }), ('a:vrf', { 'xpath': 'ip-domain/vrfs/vrf/vrf-name', 'operation': 'edit' }), ('lists', { 'xpath': 'ip-domain/vrfs/vrf/lists', 'tag': True, 'operation': 'edit' }), ('list', { 'xpath': 'ip-domain/vrfs/vrf/lists/list', 'tag': True, 'operation': 'edit', 'attrib': "operation" }), ('a:order', { 'xpath': 'ip-domain/vrfs/vrf/lists/list/order', 'operation': 'edit' }), ('a:domain_search', { 'xpath': 'ip-domain/vrfs/vrf/lists/list/list-name', 'operation': 'edit' }), ]) self._system_server_meta.update([ ('vrfs', { 'xpath': 'ip-domain/vrfs', 'tag': True, 'operation': 'edit' }), ('vrf', { 'xpath': 'ip-domain/vrfs/vrf', 'tag': True, 'operation': 'edit' }), ('a:vrf', { 'xpath': 'ip-domain/vrfs/vrf/vrf-name', 'operation': 'edit' }), ('servers', { 'xpath': 'ip-domain/vrfs/vrf/servers', 'tag': True, 'operation': 'edit' }), ('server', { 'xpath': 'ip-domain/vrfs/vrf/servers/server', 'tag': True, 'operation': 'edit', 'attrib': "operation" }), ('a:order', { 'xpath': 'ip-domain/vrfs/vrf/servers/server/order', 'operation': 'edit' }), ('a:name_servers', { 'xpath': 'ip-domain/vrfs/vrf/servers/server/server-address', 'operation': 'edit' }), ]) self._hostname_meta.update([ ('a:hostname', { 'xpath': 'host-names/host-name', 'operation': 'edit', 'attrib': "operation" }), ]) self._lookup_source_meta.update([ ('vrfs', { 'xpath': 'ip-domain/vrfs', 'tag': True, 'operation': 'edit' }), ('vrf', { 'xpath': 'ip-domain/vrfs/vrf', 'tag': True, 'operation': 'edit' }), ('a:vrf', { 'xpath': 'ip-domain/vrfs/vrf/vrf-name', 'operation': 'edit' }), ('a:lookup_source', { 'xpath': 'ip-domain/vrfs/vrf/source-interface', 'operation': 'edit', 'attrib': "operation" }), ]) self._lookup_meta.update([ ('vrfs', { 'xpath': 'ip-domain/vrfs', 'tag': True, 'operation': 'edit' }), ('vrf', { 'xpath': 'ip-domain/vrfs/vrf', 'tag': True, 'operation': 'edit' }), ('a:vrf', { 'xpath': 'ip-domain/vrfs/vrf/vrf-name', 'operation': 'edit' }), ('lookup', { 'xpath': 'ip-domain/vrfs/vrf/lookup', 'tag': True, 'operation': 'edit', 'attrib': "operation" }), ]) state = self._module.params['state'] _get_filter = build_xml('ip-domain', opcode="filter") running = get_config(self._module, source='running', config_filter=_get_filter) _get_filter = build_xml('host-names', opcode="filter") hostname_runn = get_config(self._module, source='running', config_filter=_get_filter) hostname_ele = etree_find(hostname_runn, 'host-name') hostname = hostname_ele.text if hostname_ele is not None else None vrf_ele = etree_findall(running, 'vrf') vrf_map = {} for vrf in vrf_ele: name_server_list = list() domain_list = list() vrf_name_ele = etree_find(vrf, 'vrf-name') vrf_name = vrf_name_ele.text if vrf_name_ele is not None else None domain_name_ele = etree_find(vrf, 'name') domain_name = domain_name_ele.text if domain_name_ele is not None else None domain_ele = etree_findall(vrf, 'list-name') for domain in domain_ele: domain_list.append(domain.text) server_ele = etree_findall(vrf, 'server-address') for server in server_ele: name_server_list.append(server.text) lookup_source_ele = etree_find(vrf, 'source-interface') lookup_source = lookup_source_ele.text if lookup_source_ele is not None else None lookup_enabled = False if etree_find( vrf, 'lookup') is not None else True vrf_map[vrf_name] = { 'domain_name': domain_name, 'domain_search': domain_list, 'name_servers': name_server_list, 'lookup_source': lookup_source, 'lookup_enabled': lookup_enabled } opcode = None hostname_param = {} lookup_param = {} system_param = {} sys_server_params = list() sys_domain_params = list() add_domain_params = list() del_domain_params = list() add_server_params = list() del_server_params = list() lookup_source_params = {} try: sys_node = vrf_map[self._want['vrf']] except KeyError: sys_node = { 'domain_name': None, 'domain_search': [], 'name_servers': [], 'lookup_source': None, 'lookup_enabled': True } if state == 'absent': opcode = "delete" def needs_update(x): return self._want[x] is not None and self._want[x] == sys_node[ x] if needs_update('domain_name'): system_param = { 'vrf': self._want['vrf'], 'domain_name': self._want['domain_name'] } if needs_update('hostname'): hostname_param = {'hostname': hostname} if not self._want['lookup_enabled'] and not sys_node[ 'lookup_enabled']: lookup_param['vrf'] = self._want['vrf'] if needs_update('lookup_source'): lookup_source_params['vrf'] = self._want['vrf'] lookup_source_params['lookup_source'] = self._want[ 'lookup_source'] if self._want['domain_search']: domain_param = {} domain_param['domain_name'] = self._want['domain_name'] domain_param['vrf'] = self._want['vrf'] domain_param['order'] = '0' for domain in self._want['domain_search']: if domain in sys_node['domain_search']: domain_param['domain_search'] = domain sys_domain_params.append(domain_param.copy()) if self._want['name_servers']: server_param = {} server_param['vrf'] = self._want['vrf'] server_param['order'] = '0' for server in self._want['name_servers']: if server in sys_node['name_servers']: server_param['name_servers'] = server sys_server_params.append(server_param.copy()) elif state == 'present': opcode = "merge" def needs_update(x): return self._want[x] is not None and ( sys_node[x] is None or (sys_node[x] is not None and self._want[x] != sys_node[x])) if needs_update('domain_name'): system_param = { 'vrf': self._want['vrf'], 'domain_name': self._want['domain_name'] } if self._want['hostname'] is not None and self._want[ 'hostname'] != hostname: hostname_param = {'hostname': self._want['hostname']} if not self._want['lookup_enabled'] and sys_node['lookup_enabled']: lookup_param['vrf'] = self._want['vrf'] if needs_update('lookup_source'): lookup_source_params['vrf'] = self._want['vrf'] lookup_source_params['lookup_source'] = self._want[ 'lookup_source'] if self._want['domain_search']: domain_adds, domain_removes = diff_list( self._want['domain_search'], sys_node['domain_search']) domain_param = {} domain_param['domain_name'] = self._want['domain_name'] domain_param['vrf'] = self._want['vrf'] domain_param['order'] = '0' for domain in domain_adds: if domain not in sys_node['domain_search']: domain_param['domain_search'] = domain add_domain_params.append(domain_param.copy()) for domain in domain_removes: if domain in sys_node['domain_search']: domain_param['domain_search'] = domain del_domain_params.append(domain_param.copy()) if self._want['name_servers']: server_adds, server_removes = diff_list( self._want['name_servers'], sys_node['name_servers']) server_param = {} server_param['vrf'] = self._want['vrf'] server_param['order'] = '0' for domain in server_adds: if domain not in sys_node['name_servers']: server_param['name_servers'] = domain add_server_params.append(server_param.copy()) for domain in server_removes: if domain in sys_node['name_servers']: server_param['name_servers'] = domain del_server_params.append(server_param.copy()) self._result['xml'] = [] _edit_filter_list = list() if opcode: if hostname_param: _edit_filter_list.append( build_xml('host-names', xmap=self._hostname_meta, params=hostname_param, opcode=opcode)) if system_param: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_meta, params=system_param, opcode=opcode)) if lookup_source_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._lookup_source_meta, params=lookup_source_params, opcode=opcode)) if lookup_param: _edit_filter_list.append( build_xml('ip-domain', xmap=self._lookup_meta, params=lookup_param, opcode=opcode)) if opcode == 'delete': if sys_domain_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_domain_meta, params=sys_domain_params, opcode=opcode)) if sys_server_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_server_meta, params=sys_server_params, opcode=opcode)) if self._want['vrf'] != 'default': self._result['warnings'] = [ "name-servers delete operation with non-default vrf is a success, " "but with rpc-error. Recommended to use 'ignore_errors' option with the task as a workaround" ] elif opcode == 'merge': if add_domain_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_domain_meta, params=add_domain_params, opcode=opcode)) if del_domain_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_domain_meta, params=del_domain_params, opcode="delete")) if add_server_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_server_meta, params=add_server_params, opcode=opcode)) if del_server_params: _edit_filter_list.append( build_xml('ip-domain', xmap=self._system_server_meta, params=del_server_params, opcode="delete")) diff = None if _edit_filter_list: commit = not self._module.check_mode diff = load_config(self._module, _edit_filter_list, commit=commit, running=running, nc_get_filter=_get_filter) if diff: if self._module._diff: self._result['diff'] = dict(prepared=diff) self._result['xml'] = _edit_filter_list self._result['changed'] = True