1# -*- coding: utf-8 -*- 2# Copyright 2020 Red Hat 3# GNU General Public License v3.0+ 4# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 6from __future__ import absolute_import, division, print_function 7 8__metaclass__ = type 9 10from copy import deepcopy 11import re 12 13from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.rm_templates.ospfv3 import ( 14 Ospfv3Template, 15) 16from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( 17 utils, 18) 19from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.argspec.ospfv3.ospfv3 import ( 20 Ospfv3Args, 21) 22from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import ( 23 NetworkTemplate, 24) 25 26 27class Ospfv3Facts(object): 28 """ The iosxr snmp fact class 29 """ 30 31 def __init__(self, module, subspec="config", options="options"): 32 self._module = module 33 self.argument_spec = Ospfv3Args.argument_spec 34 35 spec = deepcopy(self.argument_spec) 36 if subspec: 37 if options: 38 facts_argument_spec = spec[subspec][options] 39 else: 40 facts_argument_spec = spec[subspec] 41 else: 42 facts_argument_spec = spec 43 44 self.generated_spec = utils.generate_dict(facts_argument_spec) 45 46 def get_ospfv3_data(self, connection): 47 return connection.get("show running-config router ospfv3") 48 49 def populate_facts(self, connection, ansible_facts, data=None): 50 """ Populate the facts for interfaces 51 :param connection: the device connection 52 :param ansible_facts: Facts dictionary 53 :param data: previously collected conf 54 :rtype: dictionary 55 :returns: facts 56 """ 57 58 if not data: 59 data = self.get_ospfv3_data(connection) 60 end_flag, end_mark, count, v_read = 0, 0, 0, False 61 areas, config_commands = [], [] 62 area_str, process, curr_process = "", "", "" 63 data = data.splitlines() 64 for line in data: 65 if ( 66 line.startswith("router ospfv3") 67 and curr_process != "" 68 and curr_process != line 69 ): 70 end_mark, count, end_flag, area_str = 0, 0, 0, "" 71 if ( 72 end_mark == 0 73 and count == 0 74 and line.startswith("router ospfv3") 75 ): 76 curr_process = line 77 process = re.sub("\n", "", line) 78 count += 1 79 config_commands.append(process) 80 else: 81 if line.startswith(" area") or line.startswith(" vrf"): 82 area_str = process + re.sub("\n", "", line) 83 config_commands.append(area_str.replace(" ", " ")) 84 end_flag += 1 85 elif line.startswith(" virtual-link"): 86 virtual_str = area_str + re.sub("\n", "", line) 87 config_commands.append(virtual_str.replace(" ", " ")) 88 v_read = True 89 elif v_read: 90 if "!" not in line: 91 command = virtual_str.replace(" ", " ") + re.sub( 92 "\n", "", line 93 ) 94 config_commands.append(command.replace(" ", " ")) 95 else: 96 v_read = False 97 elif end_flag > 0 and "!" not in line: 98 command = area_str + re.sub("\n", "", line) 99 config_commands.append(command.replace(" ", " ")) 100 elif "!" in line: 101 end_flag = 0 102 end_mark += 1 103 if end_mark == 3: 104 end_mark, count = 0, 0 105 area_str = "" 106 else: 107 command = process + line 108 command.replace(" ", " ") 109 config_commands.append(re.sub("\n", "", command)) 110 areas.append(re.sub("\n", "", command)) 111 data = config_commands 112 ipv4 = {"processes": []} 113 rmmod = NetworkTemplate( 114 lines=data, tmplt=Ospfv3Template(), module=self._module 115 ) 116 current = rmmod.parse() 117 118 # convert some of the dicts to lists 119 for key, sortv in [("processes", "process_id")]: 120 if key in current and current[key]: 121 current[key] = current[key].values() 122 current[key] = sorted( 123 current[key], key=lambda k, sk=sortv: k[sk] 124 ) 125 126 for process in current.get("processes", []): 127 if "areas" in process: 128 process["areas"] = list(process["areas"].values()) 129 process["areas"] = sorted( 130 process["areas"], key=lambda k, sk="area_id": k[sk] 131 ) 132 for area in process["areas"]: 133 if "ranges" in area: 134 area["ranges"] = sorted( 135 area["ranges"], key=lambda k, s="ranges": k[s] 136 ) 137 if "virtual_link" in area: 138 area["virtual_link"] = list( 139 area["virtual_link"].values() 140 ) 141 area["virtual_link"] = sorted( 142 area["virtual_link"], key=lambda k, sk="id": k[sk] 143 ) 144 ipv4["processes"].append(process) 145 146 ansible_facts["ansible_network_resources"].pop("ospfv3", None) 147 facts = {} 148 if current: 149 params = rmmod.validate_config( 150 self.argument_spec, {"config": ipv4}, redact=True 151 ) 152 params = utils.remove_empties(params) 153 154 facts["ospfv3"] = params["config"] 155 156 ansible_facts["ansible_network_resources"].update(facts) 157 return ansible_facts 158