def update_vlan(self, vlan_obj=None, device_obj=None): vlan_id = vlan_obj.id logger.info("Updating vlan {vlan_obj.id} on {device_obj.hostname}") # validate vlan is in the database db_vlan_result = self.get_vlans_from_db(device_obj=device_obj) db_vlans = db_vlan_result.data logger.info(db_vlans.keys()) if vlan_id not in db_vlans: logger.error(f"Vlan {vlan_id} is not in databse. cannot update") return action_result( success=0, error=1, errmsg=f"Vlan {vlan_id} can't be updated it doesn't exist") synced_result = self.check_sync(device_obj=device_obj) if not synced_result.success or not synced_result.data['synced']: logger.error(f"Device out of sync.") return action_result(success=0, error=1, errmsg="Devices not in sync during update") logger.info(f"Updating vlan {vlan_id} in database") db_helper = VlanDatabaseHelper(db_name=self.database_name) update_result = db_helper.update_vlan_in_db( vlan_id=vlan_id, vlan_name=vlan_obj.name, description=vlan_obj.description) if update_result.success == 0: logger.error(f"Failure updating vlan {vlan_id}") return update_result else: logger.info("updating vlan in router") vlans_to_add = [vlan_obj] cfg = render_vlan_config(vlans_to_delete=[], vlans_to_add=vlans_to_add) cfg_set = cfg.split("\n") try: conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) op = conn.send_config_set(cfg_set) logger.debug(op) return action_result(success=1, error=0) except Exception as err: logger.error(f"Error updating vlan on device") return action_result(success=0, error=1, errmsg=repr(err))
def add_vlan(self, vlan_obj: vlan = None, device_obj=None): """ add a vlan to the db and then to the device :param input_args: :return: """ in_sync_result = self.check_sync(device_obj=device_obj) logger.info(in_sync_result.data) if in_sync_result.error or not in_sync_result.data['synced']: res = action_result(success=0, error=1, errmsg=f"Device not in sync for vlan add") in_sync = in_sync_result.data['synced'] logger.info(f"Device in sync = {in_sync}") if in_sync: vlanid = vlan_obj.id name = vlan_obj.name desc = vlan_obj.description logger.info(f"Adding vlan {vlanid} to the database") # add it to the database db_helper = VlanDatabaseHelper(db_name=self.database_name) add_result = db_helper.add_vlan_to_db(vlan_id=vlanid, vlan_name=name, description=desc) if not add_result.success: return add_result # now update the template logger.info(f"Updating device with new vlan {vlanid}") cfg = render_vlan_config(vlans_to_add=[{ 'id': vlanid, 'name': name }]) cfg_set = cfg.split("\n") conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) op = conn.send_config_set(cfg_set) logger.debug(op) result = action_result(success=1, error=0) result.data = op return result else: logger.error("Device is not in sync with database") return action_result(error=1, success=0, errmsg="Device out of sync with db.")
def del_vlan(self, vlan_id: int = None, device_obj=None): """ Delete the vlan from the db and the device. :param self: :param vlan_id: :param device_obj: :return: """ logger.info(f"Attempting to delete vlan {vlan_id}") # validate vlan is in the database db_vlans_result = self.get_vlans_from_db(device_obj=device_obj) db_vlans = db_vlans_result.data logger.info(db_vlans.keys()) if vlan_id not in db_vlans.keys(): logger.error( f"Vlan {vlan_id} type: {type(vlan_id)} is not in databse. cannot delete" ) return action_result( success=0, error=1, errmsg=f"Vlan {vlan_id} can't be deleted it doesn't exist") synced_result = self.check_sync(device_obj=device_obj) if not synced_result.success or not synced_result.data['synced']: logger.error(f"Device out of sync.") return action_result( success=0, error=1, errmsg="Devices not in sync during delete vlan") logger.info(f"Deleting vlan {vlan_id} to database") db_helper = VlanDatabaseHelper(db_name=self.database_name) del_result = db_helper.delete_vlan_from_db(vlan_id=vlan_id) if not del_result.success: logger.error(f"Unable to delete vlan {vlan_id} from database") return del_result # now delete from the device cfg = render_vlan_config(vlans_to_delete=[vlan_id]) cfg_set = cfg.split("\n") conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) op = conn.send_config_set(cfg_set) logger.debug(op) return action_result(success=1, error=0)
def merge_to_device(self, device_obj, vlans: Optional[List] = None): """ Get a list of vlans that are in the device but not in the router. Then render the template and add them to the router :param device_obj: :return: """ logging.info("merge to device called") # now get list of vlans that are missing from the device. device_vlan_result = self.get_vlans_from_device(device_obj=device_obj) db_helper = VlanDatabaseHelper(db_name=self.database_name) db_vlan_result = db_helper.get_all_vlans_from_db() db_vlans = db_vlan_result.data device_vlans = device_vlan_result.data missing_from_device = [] merge_vlans = [] if vlans and len(vlans) > 0: for vid, vobj in db_vlans.items(): if vid in vlans: merge_vlans.append(vobj) else: for vid, vobj in db_vlans.items(): if vid not in device_vlans.keys(): merge_vlans.append(vobj) #import ipdb; ipdb.set_trace() if len(merge_vlans) == 0: logger.info("No vlans to merge from db to device") return action_result(success=1, error=0) cfg = render_vlan_config(vlans_to_add=merge_vlans) cfg_set = cfg.split("\n") conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) op = conn.send_config_set(cfg_set) logger.debug(op) result = action_result(success=1, error=0) return result
def sync_to(self, device_obj=None): """" Sync the database vlans to the device. They will match after this """ # get the vlans from the device configured_vlans_result = self.get_vlans_from_device( device_obj=device_obj) # now delete the vlans from database db_helper = VlanDatabaseHelper(db_name=self.database_name) intended_vlan_result = db_helper.get_all_vlans_from_db() configured_vlans = configured_vlans_result.data intended_vlans = intended_vlan_result.data # get a list of vlans to delete vlans_to_delete = [] for vlanid in configured_vlans.keys(): if vlanid not in intended_vlans: logger.info("Adding vlan {vlanid} to delete list") vlans_to_delete.append(vlanid) vlans_to_add = [] for vlanid, vlan_obj in intended_vlans.items(): if vlanid not in configured_vlans or vlan_obj != configured_vlans[ vlanid]: logger.info( f"Adding vlan {vlanid} to the add list on the device") vlans_to_add.append({"id": vlanid, "name": vlan_obj.name}) cfg = render_vlan_config(vlans_to_delete=vlans_to_delete, vlans_to_add=vlans_to_add) print(cfg) hostname = os.getenv("MANAGED_HOST", None) usr = os.getenv("ROUTER_USR") psswd = os.getenv("ROUTER_PSSWD") device_type = os.getenv("DEVICE_TYPE") conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) op = conn.send_config_set(cfg.split("\n")) print(op) res = action_result(success=1, error=0) return res
def get_vlans_from_device(self, device_obj=None): """ Get the vlans from the device :param self: :param device_obj: :return: """ logger.info("Getting vlans from device") vlan_command_dict = { "cisco_nxos": { "cmd": "show vlan", "textfsm_template": "textfsm_templates/cisco_nxos_show_vlan.textfsm" }, "cisco_ios": { "cmd": "show vlans", "textfsm_template": "textfsm_templates/cisco_ios_show_vlan.textfsm" } } try: conn = get_device_driver(host_name=device_obj.hostname, username=device_obj.user, psswd=device_obj.psswd, device_type=device_obj.platform) cmd_detail = vlan_command_dict[device_obj.platform] cmd = cmd_detail['cmd'] templ = cmd_detail['textfsm_template'] c_path = os.path.dirname( os.path.abspath(sys.modules[self.__module__].__file__)) pth = pathlib.Path(c_path) newpath = pth / templ logger.info(f"Current path = {c_path}") op = conn.send_command(cmd, use_textfsm=True, textfsm_template=newpath) logging.info(op) # hack. the nxos is parsed as a dict instead of a list if thre # is only 1 vlan if isinstance(op, dict): op = [op] logger.info(op) configured_vlans = {} for vlandict in op: if isinstance(vlandict, dict): configured_vlans[int(vlandict['vlan_id'])] = vlan( id=int(vlandict['vlan_id']), name=vlandict['name']) res = action_result( success=1, error=0, ) res.data = configured_vlans return res except Exception as err: logger.error(f"Excpetion getting vlans from device: {repr(err)}") return action_result(success=0, error=1, errmsg=repr(err))