def as3_post(task: Task, as3_tenant: str) -> Result: failover_status = task.run( name="Get failover status", task=bigip_cm_failover_status ).result if failover_status == "ACTIVE": task.run( name="AS3 POST", task=atc, atc_delay=0, atc_method="POST", atc_retries=3, atc_service="AS3", as3_tenant=as3_tenant, atc_declaration_file=task.host["appsvcs"][as3_tenant][ "atc_declaration_file" ], ) task.run( name="Synchronize the devices", task=bigip_cm_config_sync, delay=0, device_group=task.host["device_group"], retries=3, ) return Result( host=task.host, result="ACTIVE device, AS3 declaration successfully deployed.", ) else: return Result(host=task.host, result="STANDBY device, skipped.")
def set_loopbacks(task: Task, ): loopbacks = task.host.data['loopbacks'] for key in loopbacks: interface = 'interface loopback' + str(key) # ip_addr = 'ip address ' + loopbacks[key] + ' 255.255.255.255' ip_addr = f'ip address {loopbacks[key]} 255.255.255.255' config_cmds = [interface, ip_addr] task.run(task=netmiko_send_config, config_commands=config_cmds)
def run_backup( # pylint: disable=too-many-arguments task: Task, logger, global_settings, remove_regex_dict, replace_regex_dict) -> Result: r"""Backup configurations to disk. Args: task (Task): Nornir task individual object remove_regex_dict (dict): {'cisco_ios': ['^Building\\s+configuration.*\\n', '^Current\\s+configuration.*\\n', '^!\\s+Last\\s+configuration.*'], 'arista_eos': ['.s*']} replace_regex_dict (dict): {'cisco_ios': [{'regex_replacement': '<redacted_config>', 'regex_search': 'username\\s+\\S+\\spassword\\s+5\\s+(\\S+)\\s+role\\s+\\S+'}]} Returns: result (Result): Result from Nornir task """ obj = task.host.data["obj"] backup_obj = GoldenConfig.objects.filter(device=obj).first() if not backup_obj: backup_obj = GoldenConfig.objects.create(device=obj, ) backup_obj.backup_last_attempt_date = task.host.defaults.data["now"] backup_obj.save() backup_directory = get_repository_working_dir("backup", obj, logger, global_settings) backup_path_template_obj = render_jinja_template( obj, logger, global_settings.backup_path_template) backup_file = os.path.join(backup_directory, backup_path_template_obj) if global_settings.backup_test_connectivity is not False: task.run( task=dispatcher, name="TEST CONNECTIVITY", method="check_connectivity", obj=obj, logger=logger, default_drivers_mapping=get_dispatcher(), ) running_config = task.run( task=dispatcher, name="SAVE BACKUP CONFIGURATION TO FILE", method="get_config", obj=obj, logger=logger, backup_file=backup_file, remove_lines=remove_regex_dict.get(obj.platform.slug, []), substitute_lines=replace_regex_dict.get(obj.platform.slug, []), default_drivers_mapping=get_dispatcher(), )[1].result["config"] backup_obj.backup_last_success_date = task.host.defaults.data["now"] backup_obj.backup_config = running_config backup_obj.save() logger.log_success( obj, "Successfully extracted running configuration from device.") return Result(host=task.host, result=running_config)
def set_loopbacks(task: Task,): loopbacks = task.host.data['loopbacks'] task.run(task=netmiko_send_config, config_commands = ["interface loopback 99"]) # clock=task.run(task=netmiko_send_command, command_string="show clock") return Result( host=task.host, result=f"{task.host.name} loopbacks configured to - {loopbacks}" )
def upgrade_os(task: Task, version: str) -> Result: # we use task get_verion to retrieve current OS running result = task.run(task=get_version) # if the version matches what we want to install we are done! if result.result["full_version"] == version: return Result(host=task.host, result="nothing to do!!!") # otherwise we call install_os_version task to install the image task.run(task=install_os_version, version=version) return Result(host=task.host, changed=True, result="success!!!")
def run_backup(task: Task, logger, global_settings, backup_root_folder) -> Result: """Backup configurations to disk. Args: task (Task): Nornir task individual object Returns: result (Result): Result from Nornir task """ obj = task.host.data["obj"] backup_obj = GoldenConfiguration.objects.filter(device=obj).first() if not backup_obj: backup_obj = GoldenConfiguration.objects.create( device=obj, ) backup_obj.backup_last_attempt_date = task.host.defaults.data["now"] backup_obj.save() backup_path_template_obj = check_jinja_template(obj, logger, global_settings.backup_path_template) backup_file = os.path.join(backup_root_folder, backup_path_template_obj) substitute_lines = get_substitute_lines(global_settings.substitute_lines) if global_settings.backup_test_connectivity is not False: task.run( task=dispatcher, name="TEST CONNECTIVITY", method="check_connectivity", obj=obj, logger=logger, ) running_config = task.run( task=dispatcher, name="SAVE BACKUP CONFIGURATION TO FILE", method="get_config", obj=obj, logger=logger, backup_file=backup_file, remove_lines=global_settings.remove_lines.splitlines(), substitute_lines=substitute_lines, )[1].result["config"] backup_obj.backup_last_success_date = task.host.defaults.data["now"] backup_obj.backup_config = running_config backup_obj.save() logger.log_success(obj, "Successfully backed up device.") return Result(host=task.host, result=running_config)
def get_neighbors(task: Task) -> Result: """Get a list of neighbors from the device. Args: task (Task): Nornir Task Returns: Result: Nornir Result object with a dict as a result containing the neighbors The format of the result but must be similar to Neighbors defined in network_importer.processors.get_neighbors """ LOGGER.debug("Executing get_neighbor for %s (%s)", task.host.name, task.host.platform) if config.SETTINGS.main.import_cabling == "lldp": command = "show lldp neighbors detail" converter = convert_cisco_genie_lldp_neighbors_details cmd_type = "LLDP" elif config.SETTINGS.main.import_cabling == "cdp": command = "show cdp neighbors detail" converter = convert_cisco_genie_cdp_neighbors_details cmd_type = "CDP" else: return Result(host=task.host, failed=True) try: result = task.run(task=netmiko_send_command, command_string=command, use_genie=True) except NornirSubTaskError: LOGGER.debug("An exception occured while pulling %s data", cmd_type, exc_info=True) return Result(host=task.host, failed=True) if result[0].failed: return result results = converter(device_name=task.host.name, data=result[0].result) return Result(host=task.host, result=results.dict())
def get_vlans(task: Task) -> Result: """Get a list of vlans from the device using netmiko and genie parser. Args: task (Task): Nornir Task Returns: Result: Nornir Result object with a dict as a result containing the vlans The format of the result but must be similar to Vlans defined in network_importer.processors.get_vlans """ LOGGER.debug("Executing get_vlans for %s (%s)", task.host.name, task.host.platform) try: results = task.run(task=netmiko_send_command, command_string="show vlan", use_genie=True) except NornirSubTaskError: LOGGER.debug( "An exception occured while pulling the vlans information", exc_info=True, ) return Result(host=task.host, failed=True) if not isinstance(results[0].result, dict) or "vlans" not in results[0].result: LOGGER.warning("%s | No vlans information returned", task.host.name) return Result(host=task.host, result=False) results = convert_cisco_genie_vlans(device_name=task.host.name, data=results[0].result) return Result(host=task.host, result=results.dict())
def my_netmiko_command(task: Task) -> Result: result = task.run( task=netmiko_send_command, command_string = "show lldp neighbor", use_textfsm=True ) return Result( host=task.host, result=f'Task {task.name} on host {task.host} {"failed" if result.failed else "completed succesfully"}' )
def save_show(task: Task, command: str, filename_mark: str) -> Result: show_result = task.run(task=netmiko_send_command, command_string=command, enable=True, delay_factor=5, max_loops=6000) task.host['show_result'] = show_result.result isExist = os.path.exists(f"output/{command}-{filename_mark}") if not isExist: os.mkdir(f"output/{command}-{filename_mark}") task.run(task=write_file, filename=f"output/{command}-{filename_mark}/{task.host}.cfg", content=task.host['show_result']) return Result(host=task.host, result=f"output/{command}-{filename_mark}/{task.host}.cfg", severity_level=logging.WARNING)
def get_nxos_version(task: Task) -> dict: """ get the NX-OS version of a device """ result = task.run(task=netmiko_send_command, command_string="show version", use_genie=True) os = result.result["platform"]["os"] version = result.result["platform"]["software"]["system_version"] return {"os": os, "version": version}
def greet_and_count(task: Task, number: int): """This function is for learning of how to group tasks Args: task (Task): [description] number (int): count times Returns: Result: [description] """ task.run( name="Greeting is the polite thing to do", task=say, text="hi!", ) task.run( name="Counting beans", task=count, number=number, ) task.run( name="We should say bye too", task=say, text="bye!", ) # let's inform if we counted even or odd times even_or_odds = "even" if number % 2 == 1 else "odd" return Result( host=task.host, result=f"{task.host} counted {even_or_odds} times!", )
def get_ios_xe_version(task: Task) -> dict: """ get the IOS version of a device """ result = task.run(task=netmiko_send_command, command_string="show version", use_genie=True) os = result.result["version"]["os"] version = result.result["version"]["version"] return {"os": os, "version": version}
def bigip_shared_file_transfer_uploads( task: Task, local_file_path: str, destination_file_name: Optional[str] = None, dry_run: Optional[bool] = None, ) -> Result: """Upload a file to a BIG-IP system using the iControl REST API. Args: task: (Task): The Nornir task. local_file_path (str): The full path of the file to be uploaded. destination_file_name (Optional[str]): The name of the file to upload on the remote device. dry_run (Optional[bool]): Whether to apply changes or not. Returns: Result: The result of the task. """ host = f"{task.host.hostname}:{task.host.port}" uri = f"{FILE_TRANSFER_OPTIONS['file']['endpoints']['uploads']['uri']}" dry_run = task.is_dry_run(dry_run) if dry_run: return Result(host=task.host, result=None) task.run( name="Upload the file", task=_upload_file, destination_file_name=destination_file_name, local_file_path=local_file_path, url=f"https://{host}{uri}", ) return Result(host=task.host, changed=True, result="The file was uploaded successfully.")
def loadData(task: Task) -> Result: cwd = os.getcwd() data = task.run(name=f"{task.host.name} dataModel", task=load_yaml, file=f"{cwd}/data/{task.host.name}/interface.yaml") interfaces = data.result ifaces = [] for interface in interfaces['interfaces']: iface = InterfaceModel( name=interface['name'], description=interface['description'], ipv4=interface['ipv4']['address'], enabled=interface['enabled'] if 'enabled' in interface else False) ifaces.append(iface) interfaces = InterfacesModel(interfaces=ifaces) controller = vendorFabric(task=task, model=interfaces).controller return controller.testConfig()
def create_netbox_interfaces(task: Task, nb_interfaces: list, netbox: NetBox) -> Result: """Nornir task to create interfaces in Netbox obtained via napalm_get from live devices. Args: task (Task): This. nb_interfaces (list): List of netbox interfaces. netbox (NetBox): Netbox instance Returns: Result: Nornir task result """ task_result = task.run(task=napalm_get, getters=['interfaces'], severity_level=logging.FATAL) interfaces = task_result.result['interfaces'] changed:bool = False changed_items:list = [] for interface_name in interfaces.keys(): exists = is_interface_present(nb_interfaces=nb_interfaces, device_name=f"{task.host}", interface_name=interface_name) if not exists: print( f"* Creating Netbox Interface for device {task.host}, interface {interface_name}" ) device_id = get_device_id(device_name=f"{task.host}", netbox=netbox) print (f"Device ID: {device_id}") dcim_result = netbox.dcim.create_interface( device_id=device_id, name=f"{interface_name}", interface_type="1000base-t", enabled=interfaces[interface_name]['is_enabled'], mtu=interfaces[interface_name]['mtu'], description=interfaces[interface_name]['description'], mac_address=interfaces[interface_name]['mac_address'], ) changed_items.append(dcim_result) changed=True return Result(host=task.host,result=changed_items, changed=changed)
def update_netbox_interfaces(task: Task, nb_interfaces: list, netbox) -> Result: """Nornir task to update interfaces in Netbox obtained via napalm_get from live devices. Args: task (Task): This. nb_interfaces (list): List of netbox interfaces. netbox (NetBox): Netbox instance Returns: Result: Nornir task result """ task_result = task.run(task=napalm_get, getters=['interfaces'], severity_level=logging.FATAL) interfaces = task_result.result['interfaces'] changed:bool = False changed_items:list = [] for interface_name in interfaces.keys(): enabled=interfaces[interface_name]['is_enabled'] mtu=interfaces[interface_name]['mtu'] description=interfaces[interface_name]['description'] mac_address=interfaces[interface_name]['mac_address'] if (is_interface_present(nb_interfaces=nb_interfaces, device_name=f"{task.host}", interface_name=interface_name)): print( f"* Updating Netbox Interface for device {task.host}, interface {interface_name}" ) dcim_result = netbox.dcim.update_interface( device=f"{task.host}", interface=interface_name, description=description, enabled=enabled, mtu=mtu, mac_address=mac_address, ) changed=True changed_items.append(f"{task.host} : {interface_name} Updated: {dcim_result}") return Result(host=task.host, result=changed_items, changed=changed)
def dispatcher(task: Task, method: str) -> Result: """Helper Task to retrieve a given Nornir task for a given platform Args: task (Nornir Task): Nornir Task object task (Nornir Task): Nornir Task object Returns: Result: Nornir Task result """ LOGGER.debug("Executing dispatcher for %s (%s)", task.host.name, task.host.platform) # Get the platform specific driver, if not available, get the default driver driver = config.SETTINGS.drivers.mapping.get( task.host.platform, config.SETTINGS.drivers.mapping.get("default")) LOGGER.debug("Found driver %s", driver) if not driver: LOGGER.warning( "%s | Unable to find the driver for %s for platform : %s", task.host.name, method, task.host.platform) return Result(host=task.host, failed=True) driver_class = getattr(importlib.import_module(driver), "NetworkImporterDriver") if not driver_class: LOGGER.error("%s | Unable to locate the class %s", task.host.name, driver) return Result(host=task.host, failed=True) try: driver_task = getattr(driver_class, method) except AttributeError: LOGGER.error("%s | Unable to locate the method %s for %s", task.host.name, method, driver) return Result(host=task.host, failed=True) result = task.run(task=driver_task) return Result(host=task.host, result=result)