def map_config_to_obj(module): config = get_config(module) intfobj = get_intf_info(module) blocks = config.split("!") vrfs = [] for block in blocks: if re.search(r"ip vrf (\w+) \d", block, re.M): vrfs.append(block) if len(vrfs) == 0: return list() instances = list() interfaces = parse_interfaces(module, intfobj) for item in set(vrfs): name = re.search(r"ip vrf (\w+) \d", item, re.M).group(1) obj = { "name": name, "state": "present", "description": parse_description(item), "rd": parse_rd(item), "interfaces": interfaces.get(name), "route_import": parse_import(item), "route_export": parse_export(item), "route_both": parse_both(item), } instances.append(obj) return instances
def has_vrf(module, vrf): global _CONFIGURED_VRFS if _CONFIGURED_VRFS is not None: return vrf in _CONFIGURED_VRFS config = get_config(module) _CONFIGURED_VRFS = re.findall(r"vrf definition (\S+)", config) return vrf in _CONFIGURED_VRFS
def get_running_config(module, current_config=None, flags=None): running = module.params["running_config"] if not running: if not module.params["defaults"] and current_config: running = current_config else: running = get_config(module, flags=flags) return running
def get_running_config(module, current_config=None): """ gets the current configuration of the device """ running = module.params["running_config"] if not running: if current_config: running = current_config else: running = get_config(module) return running
def map_config_to_obj(module): config = get_config(module, flags=[" router rip"]) obj = { "network": parse_network(config), "passive-int": parse_passive_int(config), } return obj
def get_existing_config(module): config = (get_config(module, flags=[" router ospf"]), ) existing_config = set() ospf = None for item in config: for line in item.splitlines(): s = line.strip() existing_config.add(s) if "router ospf" in s: ospf = s return ospf, existing_config
def map_config_to_obj(module): config = get_config(module) return { "hostname": parse_hostname(config), "domain_name": parse_domain_name(config), "domain_list": parse_domain_list(config), "lookup_enabled": "no ip domain-lookup" not in config and "no ip domain-lookup" not in config, "name_servers": parse_name_servers(config), }
def map_config_to_obj(module): objs = list() config = get_config(module) for line in config.split("\n"): line = line.strip() match = re.search(r"interface po(\d+)", line, re.M) if match: obj = {} group = match.group(1) obj["group"] = group obj.update(get_channel(module, config, group)) objs.append(obj) return objs
def get_existing(module, args, warnings): existing = {} netcfg = CustomNetworkConfig(indent=2, contents=get_config(module, flags=["bgp"])) asn_re = re.compile(r"router bgp (?P<existing_asn>\d+)", re.S) asn_match = asn_re.match(str(netcfg)) if asn_match: existing_asn = asn_match.group("existing_asn") bgp_parent = "router bgp {0}".format(existing_asn) if module.params["vrf"] != "default": parents = [ bgp_parent, "address-family ipv4 vrf {0}".format(module.params["vrf"]), ] else: parents = [bgp_parent] config = netcfg.get_section(parents) if config: for arg in args: if arg != "asn" and ( module.params["vrf"] == "default" or arg not in GLOBAL_PARAMS ): existing[arg] = get_value(arg, config) existing["asn"] = existing_asn if module.params["vrf"] == "default": existing["vrf"] = "default" if ( not existing and module.params["vrf"] != "default" and module.params["state"] == "present" ): msg = "VRF {0} doesn't exist.".format(module.params["vrf"]) module.fail_json(msg=msg) warnings.append(msg) return existing
def map_config_to_obj(module): """ This function gets the banner config without stripping any whitespaces, and then fetches the required banner from it. :param module: :return: banner config dict object. """ out = get_config(module, flags="| begin banner %s" % module.params["banner"]) if out: regex = "banner " + module.params["banner"] + " (.+)" match = re.search(regex, out, re.M) if match: output = match.group(1).strip() else: output = None else: output = None obj = {"banner": module.params["banner"], "state": "absent"} if output: obj["text"] = output obj["state"] = "present" return obj
def map_config_to_obj(module): data = get_config(module, flags=["| include username"]) match = re.findall(r"(?:^(?:u|\s{2}u))sername (\S+)", data, re.M) if not match: return list() instances = list() for user in set(match): regex = r"username %s .+$" % user cfg = re.findall(regex, data, re.M) cfg = "\n".join(cfg) obj = { "name": user, "state": "present", "configured_password": None, "hashed_password": None, "privilege": parse_privilege(cfg), } instances.append(obj) return instances
def map_config_to_obj(module): obj = [] route = {} out = get_config(module, flags="ip route") for line in out.splitlines(): # Split by whitespace but do not split quotes, needed for name parameter splitted_line = findall(r'[^"\s]\S*|".+?"', line) if len(splitted_line) <= 1: continue if splitted_line[2] == "vrf": route = {"vrf": splitted_line[3]} del splitted_line[:4] # Removes the words ip route vrf vrf_name else: route = {} del splitted_line[:2] # Removes the words ip route prefix_mask = splitted_line[0] prefix_mask_list = prefix_mask.split("/") prefix = prefix_mask_list[0] mask = prefix_mask_list[1] route.update({"prefix": prefix, "mask": mask, "admin_distance": "1"}) for word in splitted_line[1:]: if validate_ip_address(word): route.update(next_hop=word) elif word.isdigit(): route.update(admin_distance=word) else: route.update(interface=word) obj.append(route) return obj
def map_config_to_obj(module): obj_dict = {} obj = [] server_list = [] config = get_config(module, flags=["| include ntp"]) for line in config.splitlines(): match = re.search(r"ntp (\S+)", line, re.M) if match: dest = match.group(1) server = parse_server(line, dest) source_int = parse_source_int(line, dest) restrict = parse_restrict(line, dest) auth = parse_auth(dest) key_id, auth_key = parse_auth_key(line, dest) if server: server_list.append(server) if source_int: obj_dict["source_int"] = source_int if restrict: obj_dict["restrict"] = restrict if auth: obj_dict["auth"] = auth if auth_key: obj_dict["auth_key"] = auth_key if key_id: obj_dict["key_id"] = key_id obj_dict["server"] = server_list obj.append(obj_dict) return obj
def main(): """ main entry point for module execution """ backup_spec = dict(filename=dict(default="awplus"), dir_path=dict(type="path", default="./backup")) 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"]), multiline_delimiter=dict(default="@"), running_config=dict(aliases=["config"]), intended_config=dict(), backup=dict(type="bool", default=False), backup_options=dict(type="dict", options=backup_spec), save_when=dict(choices=["always", "never", "modified", "changed"], default="never"), diff_against=dict(choices=["startup", "intended", "running"]), diff_ignore_lines=dict(type="list"), ) argument_spec.update(awplus_argument_spec) mutually_exclusive = [("lines", "src"), ("parents", "src")] required_if = [ ("match", "strict", ["lines"]), ("match", "exact", ["lines"]), ("replace", "block", ["lines"]), ("diff_against", "intended", ["intended_config"]), ] module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_if=required_if, supports_check_mode=True, ) result = {"changed": False} warnings = list() check_args(module, warnings) result["warnings"] = warnings diff_ignore_lines = module.params["diff_ignore_lines"] config = None contents = None connection = get_connection(module) if module.params["backup"] or (module._diff and module.params["diff_against"] == "running"): contents = get_config(module) config = NetworkConfig(indent=1, contents=contents) if module.params["backup"]: result["__backup__"] = contents backup_options = module.params["backup_options"] if backup_options: dir_path = backup_options["dir_path"] filename = backup_options["filename"] else: dir_path = "./backup" filename = "awplus" write_backup(contents, dir_path, filename) result["filename"] = filename result["backup_path"] = dir_path if any((module.params["lines"], module.params["src"])): match = module.params["match"] replace = module.params["replace"] path = module.params["parents"] candidate = get_candidate_config(module) running = get_running_config(module, contents) try: response = connection.get_diff( candidate=candidate, running=running, diff_match=match, diff_ignore_lines=diff_ignore_lines, path=path, diff_replace=replace, ) except ConnectionError as exc: module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) config_diff = response["config_diff"] banner_diff = response["banner_diff"] if config_diff or banner_diff: commands = config_diff.split("\n") if module.params["before"]: commands[:0] = module.params["before"] if module.params["after"]: commands.extend(module.params["after"]) result["commands"] = commands result["banners"] = banner_diff # send the configuration commands to the device and merge # them with the current running config if not module.check_mode: if commands: edit_runconfig(connection, commands) if banner_diff: connection.edit_banner( candidate=json.dumps(banner_diff), multiline_delimiter=module. params["multiline_delimiter"], ) 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) if module._diff: if not running_config: output = run_commands(module, "show running-config") contents = output[0] else: contents = running_config # recreate the object in order to process diff_ignore_lines running_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if module.params["diff_against"] == "running": if module.check_mode: module.warn( "unable to perform diff against running-config due to check mode" ) contents = None else: contents = config.config_text elif module.params["diff_against"] == "startup": if not startup_config: output = run_commands(module, "show startup-config") contents = output[0] else: contents = startup_config.config_text elif module.params["diff_against"] == "intended": contents = module.params["intended_config"] if contents is not None: base_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if running_config.sha1 != base_config.sha1: if module.params["diff_against"] == "intended": before = running_config after = base_config elif module.params["diff_against"] in ("startup", "running"): before = base_config after = running_config result.update({ "changed": True, "diff": { "before": str(before), "after": str(after) }, }) module.exit_json(**result)