def run(module, result): match = module.params['match'] replace = module.params['replace'] replace_config = replace == 'config' diff_ignore_lines = module.params['diff_ignore_lines'] path = module.params['parents'] check_mode = module.check_mode candidate = get_candidate(module) if match != 'none' and replace != 'config': contents = get_running_config(module) configobj = NetworkConfig(contents=contents, indent=1) commands = candidate.difference(configobj, path=path, match=match, replace=replace) else: commands = candidate.items if commands: commands = dumps(commands, 'commands').split('\n') if any((module.params['lines'], module.params['src'])): if module.params['before']: commands[:0] = module.params['before'] if module.params['after']: commands.extend(module.params['after']) result['commands'] = commands diff = load_config(module, commands) if diff: result['diff'] = dict(prepared=diff) result['changed'] = True running_config = module.params['running_config'] startup_config = None if module.params['save_when'] == 'always': save_config(module, result) elif module.params['save_when'] == 'modified': output = run_commands(module, ['show running-config', 'show startup-config']) running_config = NetworkConfig(indent=1, contents=output[0], ignore_lines=diff_ignore_lines) startup_config = NetworkConfig(indent=1, contents=output[1], ignore_lines=diff_ignore_lines) if running_config.sha1 != startup_config.sha1: save_config(module, result) elif module.params['save_when'] == 'changed' and result['changed']: save_config(module, result)
def get_diff( self, candidate=None, running=None, diff_match="line", diff_ignore_lines=None, path=None, diff_replace="line", ): diff = {} device_operations = self.get_device_operations() option_values = self.get_option_values() if candidate is None and device_operations["supports_generate_diff"]: raise ValueError( "candidate configuration is required to generate diff" ) if diff_match not in option_values["diff_match"]: raise ValueError( "'match' value %s in invalid, valid values are %s" % (diff_match, ", ".join(option_values["diff_match"])) ) if diff_replace not in option_values["diff_replace"]: raise ValueError( "'replace' value %s in invalid, valid values are %s" % (diff_replace, ", ".join(option_values["diff_replace"])) ) # prepare candidate configuration candidate_obj = NetworkConfig(indent=2) candidate_obj.load(candidate) if running and diff_match != "none" and diff_replace != "config": # running configuration running_obj = NetworkConfig( indent=2, contents=running, ignore_lines=diff_ignore_lines ) configdiffobjs = candidate_obj.difference( running_obj, path=path, match=diff_match, replace=diff_replace ) else: configdiffobjs = candidate_obj.items diff["config_diff"] = ( dumps(configdiffobjs, "commands") if configdiffobjs else "" ) return diff
def get_candidate_config(module): candidate = '' if module.params['src']: candidate_obj = NetworkConfig(indent=0) candidate_obj.loadfp(module.params['src']) candidate = dumps(candidate_obj, 'raw') elif module.params['lines']: candidate_obj = NetworkConfig(indent=4) parents = module.params['parents'] or list() candidate_obj.add(module.params['lines'], parents=parents) candidate = dumps(candidate_obj, 'raw') return candidate
def map_config_to_obj(module): compare = module.params['check_running_config'] config = get_config(module, flags=['| begin interface'], compare=compare) configobj = NetworkConfig(indent=1, contents=config) match = re.findall(r'^interface (\S+ \S+)', config, re.M) if not match: return list() instances = list() for item in set(match): ipv4 = parse_config_argument(configobj, item, 'ip address') if ipv4: address = ipv4.strip().split(' ') if len(address) == 2 and is_netmask(address[1]): ipv4 = '{0}/{1}'.format(address[0], to_text(to_masklen(address[1]))) obj = { 'name': item, 'ipv4': ipv4, 'ipv6': parse_config_argument(configobj, item, 'ipv6 address'), 'state': 'present' } instances.append(obj) return instances
def map_config_to_obj(module): config = get_config(module) configobj = NetworkConfig(indent=1, contents=config) match = re.findall(r'^interface (\S+)', config, re.M) if not match: return list() instances = list() for item in set(match): ipv4 = parse_config_argument(configobj, item, 'ip address') if ipv4: # eg. 192.168.2.10 255.255.255.0 -> 192.168.2.10/24 address = ipv4.strip().split(' ') if len(address) == 2 and is_netmask(address[1]): ipv4 = '{0}/{1}'.format(address[0], to_text(to_masklen(address[1]))) obj = { 'name': item, 'ipv4': ipv4, 'ipv6': parse_config_argument(configobj, item, 'ipv6 address'), 'state': 'present' } instances.append(obj) return instances
def map_config_to_obj(module): config = get_config(module) configobj = NetworkConfig(indent=1, contents=config) match = re.findall(r"^interface (\S+)", config, re.M) if not match: return list() instances = list() for item in set(match): ipv4 = parse_config_argument(configobj, item, "ip address") if ipv4: # eg. 192.168.2.10 255.255.255.0 -> 192.168.2.10/24 address = ipv4.strip().split(" ") if len(address) == 2 and is_netmask(address[1]): ipv4 = "{0}/{1}".format(address[0], to_text(to_masklen(address[1]))) obj = { "name": item, "ipv4": ipv4, "ipv6": parse_config_argument(configobj, item, "ipv6 address"), "state": "present", } instances.append(obj) return instances
def map_config_to_obj(module): config = get_config(module) configobj = NetworkConfig(indent=1, contents=config) match = re.findall("^vrf definition (\\S+)", config, re.M) if not match: return list() instances = list() interfaces = parse_interfaces(configobj) for item in set(match): obj = { "name": item, "state": "present", "description": parse_description(configobj, item), "rd": parse_rd(configobj, item), "interfaces": interfaces.get(item), "route_import": parse_import(configobj, item), "route_export": parse_export(configobj, item), "route_both": parse_both(configobj, item), "route_import_ipv4": parse_import_ipv4(configobj, item), "route_export_ipv4": parse_export_ipv4(configobj, item), "route_both_ipv4": parse_both(configobj, item, address_family="ipv4"), "route_import_ipv6": parse_import_ipv6(configobj, item), "route_export_ipv6": parse_export_ipv6(configobj, item), "route_both_ipv6": parse_both(configobj, item, address_family="ipv6"), } instances.append(obj) return instances
def run(module, result): match = module.params['match'] replace = module.params['replace'] replace_config = replace == 'config' path = module.params['parents'] comment = module.params['comment'] admin = module.params['admin'] check_mode = module.check_mode candidate = get_candidate(module) if match != 'none' and replace != 'config': contents = get_running_config(module) configobj = NetworkConfig(contents=contents, indent=1) commands = candidate.difference(configobj, path=path, match=match, replace=replace) else: commands = candidate.items if commands: commands = dumps(commands, 'commands').split('\n') if any((module.params['lines'], module.params['src'])): if module.params['before']: commands[:0] = module.params['before'] if module.params['after']: commands.extend(module.params['after']) result['commands'] = commands diff = load_config(module, commands) if diff: result['diff'] = dict(prepared=diff) result['changed'] = True
def map_config_to_obj(module): config = get_config(module) configobj = NetworkConfig(indent=1, contents=config) match = re.findall(r'^vrf definition (\S+)', config, re.M) if not match: return list() instances = list() interfaces = parse_interfaces(configobj) for item in set(match): obj = { 'name': item, 'state': 'present', 'description': parse_description(configobj, item), 'rd': parse_rd(configobj, item), 'interfaces': interfaces.get(item), 'route_import': parse_import(configobj, item), 'route_export': parse_export(configobj, item), 'route_both': parse_both(configobj, item), 'route_import_ipv4': parse_import_ipv4(configobj, item), 'route_export_ipv4': parse_export_ipv4(configobj, item), 'route_both_ipv4': parse_both(configobj, item, address_family='ipv4'), 'route_import_ipv6': parse_import_ipv6(configobj, item), 'route_export_ipv6': parse_export_ipv6(configobj, item), 'route_both_ipv6': parse_both(configobj, item, address_family='ipv6'), } instances.append(obj) return instances
def get_sublevel_config(running_config, module): contents = list() current_config_contents = list() running_config = NetworkConfig(contents=running_config, indent=1) obj = running_config.get_object(module.params['parents']) if obj: contents = obj.children parents = module.params['parents'] if parents[2:]: temp = 1 for count, item in enumerate(parents[2:], start=2): item = ' ' * temp + item temp = temp + 1 parents[count] = item contents[:0] = parents indent = 0 for c in contents: if isinstance(c, str): if c in parents: current_config_contents.append(c.rjust(len(c) + indent, ' ')) if c not in parents: c = ' ' * (len(parents) - 1) + c current_config_contents.append(c.rjust(len(c) + indent, ' ')) if isinstance(c, ConfigLine): current_config_contents.append(c.raw) indent = 1 sublevel_config = '\n'.join(current_config_contents) return sublevel_config
def load_running_config(running): running = running.strip().split('\n') running_obj = NetworkConfig(indent=4) # Transform running to running_obj index = 0 while index < len(running): # If line is empty, ignore it if running[index] == '': index += 1 continue parents = to_parents(running[index]) children = list() # If this line is parents, find it's children if is_parents(running[index]): index += 1 while index < len(running) and running[ index] != 'exit' and running[index] != '': children.append(running[index]) index += 1 if index < len(running) and running[index] != '': children.append(running[index]) # Add parents and children into running_obj running_obj.add(children, parents) index += 1 return running_obj
def get_candidate(module): candidate = NetworkConfig(indent=1) if module.params['src']: candidate.load(module.params['src']) elif module.params['lines']: candidate.add(module.params['lines']) return candidate
def get_section(self, config, section): if config is not None: netcfg = NetworkConfig(indent=2, contents=config) try: config = netcfg.get_block_config(to_list(section)) except ValueError: config = None return config
def get_candidate(module): candidate = NetworkConfig(indent=1) if module.params["src"]: candidate.load(module.params["src"]) elif module.params["lines"]: parents = module.params["parents"] or list() candidate.add(module.params["lines"], parents=parents) return candidate
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): diff = {} # prepare candidate configuration candidate_obj = NetworkConfig(indent=2) candidate_obj.load(candidate) if running and diff_match != 'none' and diff_replace != 'config': # running configuration running_obj = NetworkConfig(indent=2, contents=running, ignore_lines=diff_ignore_lines) configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace) else: configdiffobjs = candidate_obj.items diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else '' return diff
def get_running_config(module, current_config=None): contents = module.params['running_config'] if not contents: if current_config: contents = current_config.config_text else: contents = get_config(module) return NetworkConfig(indent=1, contents=contents)
def get_candidate(module): candidate = NetworkConfig(indent=1) if module.params['src']: candidate.load(module.params['src']) elif module.params['lines']: parents = module.params['parents'] or list() candidate.add(module.params['lines'], parents=parents) return candidate
def get_config(module, result): contents = module.params['config'] if not contents: defaults = module.params['defaults'] contents = module.config.get_config(include_defaults=defaults) contents, banners = extract_banners(contents) return NetworkConfig(indent=1, contents=contents), banners
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): diff = {} device_operations = self.get_device_operations() option_values = self.get_option_values() if candidate is None and device_operations['supports_generate_diff']: raise ValueError( "candidate configuration is required to generate diff") if diff_match not in option_values['diff_match']: raise ValueError( "'match' value %s in invalid, valid values are %s" % (diff_match, ', '.join(option_values['diff_match']))) if diff_replace not in option_values['diff_replace']: raise ValueError( "'replace' value %s in invalid, valid values are %s" % (diff_replace, ', '.join(option_values['diff_replace']))) # prepare candidate configuration candidate_obj = NetworkConfig(indent=1) candidate_obj.load(candidate) if running and diff_match != 'none': # running configuration running_obj = NetworkConfig(indent=1, contents=running, ignore_lines=diff_ignore_lines) configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace) else: configdiffobjs = candidate_obj.items diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else '' return diff
def get_running_config(module, config=None): contents = module.params['running_config'] if not contents: if config: contents = config else: contents = get_config(module) return NetworkConfig(contents=contents)
def get_config_context(self, config, path, indent=1): if config is not None: netcfg = NetworkConfig(indent=indent, contents=config) try: config = netcfg.get_block_config(to_list(path)) except ValueError: config = None return config
def get_candidate_config(module): candidate = '' if module.params['src']: candidate = module.params['src'] elif module.params['lines']: candidate_obj = NetworkConfig(indent=1) candidate_obj.add(module.params['lines']) candidate = dumps(candidate_obj, 'raw') return candidate
def get_candidate_config(module): candidate = "" if module.params["src"]: candidate = module.params["src"] elif module.params["lines"]: candidate_obj = NetworkConfig(indent=1) parents = module.params["parents"] or list() candidate_obj.add(module.params["lines"], parents=parents) candidate = dumps(candidate_obj, "raw") return candidate
def map_config_to_obj(module, warnings): config = get_config(module, flags=["| section interface"]) configobj = NetworkConfig(indent=3, contents=config) match = re.findall(r"^interface (\S+)", config, re.M) if not match: return list() instances = list() for item in set(match): command = { "command": "show interfaces {0} switchport | include Switchport".format(item), "output": "text", } command_result = run_commands(module, command, check_rc=False) if "Interface does not exist" in command_result[0]: warnings.append( "Could not gather switchport information for {0}: {1}".format( item, command_result[0])) continue if command_result[0]: switchport_cfg = command_result[0].split(":")[1].strip() if switchport_cfg == "Enabled": state = "present" else: state = "absent" obj = { "name": item.lower(), "state": state, "access_vlan": parse_config_argument(configobj, item, "switchport access vlan"), "native_vlan": parse_config_argument(configobj, item, "switchport trunk native vlan"), "trunk_allowed_vlans": parse_config_argument(configobj, item, "switchport trunk allowed vlan"), } if obj["access_vlan"]: obj["mode"] = "access" else: obj["mode"] = "trunk" instances.append(obj) return instances
def get_acl_config(module, acl_name): contents = module.params["config"] if not contents: contents = get_config(module) filtered_config = list() for item in contents.split("\n"): if item.startswith("access-list %s " % acl_name): filtered_config.append(item) return NetworkConfig(indent=1, contents="\n".join(filtered_config))
def map_config_to_obj(module): config = get_config(module) configobj = NetworkConfig(indent=2, contents=config) return { 'hostname': parse_hostname(config), 'lookup_enabled': 'no ip domain-lookup' not in config, 'domain_name': parse_domain_name(config), 'domain_search': parse_domain_search(config), 'name_servers': parse_name_servers(config), }
def get_acl_config(module, acl_name): contents = module.params['config'] if not contents: contents = get_config(module) filtered_config = list() for item in contents.split('\n'): if item.startswith('access-list %s ' % acl_name): filtered_config.append(item) return NetworkConfig(indent=1, contents='\n'.join(filtered_config))
def get_candidate(self): candidate = '' if self.want.src: candidate = self.want.src elif self.want.lines: candidate_obj = NetworkConfig(indent=1) parents = self.want.parents or list() candidate_obj.add(self.want.lines, parents=parents) candidate = dumps(candidate_obj, 'raw') return candidate
def get_sublevel_config(running_config, module): contents = list() current_config_contents = list() sublevel_config = NetworkConfig(indent=0) obj = running_config.get_object(module.params['parents']) if obj: contents = obj._children for c in contents: if isinstance(c, ConfigLine): current_config_contents.append(c.raw) sublevel_config.add(current_config_contents, module.params['parents']) return sublevel_config
def run(module, result): match = module.params["match"] replace = module.params["replace"] path = module.params["parents"] candidate = get_candidate(module) if match != "none": contents = module.params["config"] if not contents: contents = get_config(module) config = NetworkConfig(indent=1, contents=contents) configobjs = candidate.difference(config, path=path, match=match, replace=replace) else: configobjs = candidate.items if configobjs: commands = dumps(configobjs, "commands").split("\n") if module.params["lines"]: if module.params["before"]: commands[:0] = module.params["before"] if module.params["after"]: commands.extend(module.params["after"]) result["updates"] = commands # send the configuration commands to the device and merge # them with the current running config if not module.check_mode: load_config(module, commands) result["changed"] = True if module.params["save"]: module.warn( "module param save is deprecated, please use newer and updated param save_when instead which is released with more functionality!" ) save_config(module, result) if module.params["save_when"] == "always": save_config(module, result) elif module.params["save_when"] == "modified": running_config_checksum = run_commands( module, "show running-config | include checksum:") startup_config_checksum = run_commands( module, "show startup-config | include checksum:") if running_config_checksum != startup_config_checksum: save_config(module, result) elif module.params["save_when"] == "changed" and result["changed"]: save_config(module, result)