def identification_of_netconf_device(task): device_dict = NETCONF_URI_DICT[task["inputData"]["device_type"]] # Read data with netconf or uniconfig based on topology result_dict = {"version": task["inputData"]["sw_version"]} for _ in range(20): for field, uri in device_dict['uri'].items(): if field not in result_dict: task["inputData"]["uri"] = uri response = netconf_worker.read_structured_data(task) if response['status'] == 'COMPLETED' and response["output"]["response_code"] == 200: result_dict[field] = list(response["output"]["response_body"].values())[0] if device_dict['uri'].keys() == result_dict.keys(): break time.sleep(2) netconf_worker.execute_unmount_netconf({"inputData": {"device_id": task["inputData"]["device_id"]}}) response_body = { "device_name": result_dict.get("hostname", ""), "device_sw": device_dict["details"]["sw"], "device_version": result_dict.get("version", ""), "device_vendor": device_dict["details"]["vendor"], "device_model": result_dict.get("model", "") } return util.completed_response({"response_body": response_body})
def read_and_parse_rpc_cli_saos_6_and_8(task): """ Parse RPC output from Ciena Saos6/8 device, check it's LLDP neighbors, extract and return relevant LLDP data. Args: task (dict): Has to contain key device_name. Returns: dict: Standard worker response with operation status along with list of dicts containing LLDP data. """ rpc_input = task["inputData"]["rpc_input"] lldp_config = [] interfaces_pattern_matching = list( filter(re.compile(r"^\|[0-9]").match, rpc_input.split("\r\n"))) device_pattern_matching = list( filter( re.compile(r"^\|.*\| System Name").match, rpc_input.split("\r\n"))) for interfaces, name in zip(interfaces_pattern_matching, device_pattern_matching): lldp_info = copy.deepcopy(lldp_info_template) ( lldp_info["local_interface"], lldp_info["neighbor_interface"], ) = interfaces.replace(" ", "").split("|")[1:-2] lldp_info["neighbor_device_name"] = name[name.find(":") + 1:-1].replace(" ", "") lldp_config.append(lldp_info) return util.completed_response({"lldp_config": lldp_config})
def mount_netconf_device_identification(task): devices = {"cisco-ios-xr-653": {"device_id": task["inputData"]["device_id"] + "cisco653", "config": {"blacklist": ",".join(SCHEMA_BLACKLIST["cisco-ios-xr"]), "schema-cache-directory": "cisco-iosxr-653"}}, "cisco-ios-xr-663": {"device_id": task["inputData"]["device_id"] + "cisco663", "config": {"blacklist": ",".join(SCHEMA_BLACKLIST["cisco-ios-xr"]), "schema-cache-directory": "cisco-iosxr-663"}}, "juniper": {"device_id": task["inputData"]["device_id"] + "juniper", "config": {"schema-cache-directory": "junos-16-2021"}} } task["inputData"].update(NETCONF_MOUNT_BODY) mounted_device = {} for device_type, device in devices.items(): updated_task = copy.deepcopy(task) updated_task["inputData"]["device_id"] = device["device_id"] if "config" in device: updated_task["inputData"].update(device["config"]) mount_res = netconf_worker.execute_mount_netconf(updated_task) if mount_res["status"] == util.COMPLETED_STATUS: device_dict = NETCONF_URI_DICT[device_type] response = netconf_worker.read_structured_data({"inputData": {"device_id": device["device_id"], "uri": device_dict['uri']['version']}}) if response['status'] == 'COMPLETED' and response["output"]["response_code"] == 200: sw_version = list(response["output"]["response_body"].values())[0] mounted_device = {"mounted_device_id": device["device_id"], "device_type": device_type, "sw_version": sw_version} break return util.completed_response(mounted_device)
def validate_input_parameters_device_identification(task): """ Validate user inputs in WF :param task: a dict with the following structure: "inputData": { 'port': '10000', } :return: {"response_body": "Input parameters are valid"} """ input_parameters = task["inputData"] schema = DeviceIdentificationSchema() try: schema.load(input_parameters) except ValidationError as err: return util.failed_response(err.messages) return util.completed_response( {"response_body": "Input parameters are valid"})
def lldp_input_validation(task): DEVICE_SOFTWARES = ["saos", "ios xr"] device_name = task["inputData"]["device_name"] device_software = task["inputData"]["device_software"] if not device_name: return util.failed_response({"Error": "Device name is missing"}) if device_software not in DEVICE_SOFTWARES: return util.failed_response({ "Error": "Wrong device software. Please select one of these device softwares [saos, ios xr]" }) return util.completed_response({ 'device_name': device_name, "sw": device_software })
def parse_netconf_data_iosxr(task): """ Parse LLDP structured data obtained from an IOS XR device. Parse the neighbors of the device, return interfaces Args: task (dict): Has to contain key netconf_data Returns: dict: List of interfaces """ netconf_data = task["inputData"]["netconf_data"] lldp_entries = netconf_data['lldp']['nodes']['node'] lldp_config = [] for entry in lldp_entries: neighbor_key = "neighbors" if neighbor_key in entry: neighbors = entry["neighbors"]["details"]["detail"] else: continue for neighbor in neighbors: for lldp_neighbor in neighbor["lldp-neighbor"]: lldp_info = copy.deepcopy(lldp_info_template) try: lldp_info["neighbor_device_name"] = lldp_neighbor[ 'device-id'] lldp_info["neighbor_interface"] = lldp_neighbor[ 'port-id-detail'] lldp_info["local_interface"] = lldp_neighbor[ 'receiving-parent-interface-name'] lldp_config.append(lldp_info) except: pass return util.completed_response({"lldp_config": lldp_config})
def create_unique_device_name(task): device_name = "Device" + str(uuid1().hex) return util.completed_response({'device_name': device_name})
def ip_address_identification(task): device_data = task["inputData"]["device_data"] device_name = "" device_version = "" device_sw = "" device_vendor = "" device_model = "" cisco_has_role = False device_data = device_data.split("\r\n") for line in device_data: ciena_device_regex = re.search(r"! SW Package:", str(line)) ciena_device_name_regex = re.search(r"! Host Name:\s+(\S+)", str(line)) cisco_device_regex = re.search(r"^Cisco", str(line)) cisco_device_name_regex = re.search(r"hostname (\S+)", str(line)) juniper_device_name_regex = re.search(r"Hostname: (\S+)", str(line)) juniper_sw_version_regex = re.search(r"Junos: (\d\S+)", str(line)) if not device_model or device_model.endswith("x"): device_model = get_device_model(line, device_model) if juniper_sw_version_regex: device_version = juniper_sw_version_regex.group(1) device_sw = "juniper" device_vendor = "juniper" if juniper_device_name_regex: device_name = juniper_device_name_regex.group(1) if ciena_device_name_regex: device_name = ciena_device_name_regex.group(1) elif ciena_device_regex and not device_version: device_sw = "saos" device_vendor = "ciena" is_saos8 = re.search(r"! SW Package:\s+rel_saos8700", str(line)) is_saos8_2 = re.search(r"! SW Package:\s+rel_saos5170", str(line)) is_saos6 = re.search(r"! SW Package:\s+Slot 1 - saos-06", str(line)) if is_saos6: device_version = "6" elif is_saos8 or is_saos8_2: device_version = "8" elif cisco_device_regex and not cisco_has_role: device_vendor = "cisco" device_version_regex = re.search(r"Version (\d+\.\d+\.\d+|\d+\.\d+)", str(line)) device_version = device_version_regex.group(1) is_ios_xr = re.search(r"Cisco IOS XR Software", str(line)) is_ios_xe = re.search(r"Cisco IOS XE Software", str(line)) is_ios = re.search(r"Cisco IOS Software", str(line)) cisco_has_role = True if is_ios: device_sw = "ios" elif is_ios_xe: device_sw = "ios xe" elif is_ios_xr: device_sw = "ios xr" elif cisco_device_name_regex: device_name = cisco_device_name_regex.group(1) response_body = { "device_name": device_name, "device_sw": device_sw, "device_version": device_version, "device_vendor": device_vendor, "device_model": device_model } return util.completed_response({"response_body": response_body})