def process_inventory(self, ctx): """ For ASR9K IOS-XR. There is only one chassis in this case. It most likely shows up last in the output of "admin show inventory". Example: NAME: "chassis ASR-9006-AC", DESCR: "ASR 9006 4 Line Card Slot Chassis with V1 AC PEM" PID: ASR-9006-AC, VID: V01, SN: FOX1523H7HA """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.search(inventory_data[idx]['name']) and \ (not self.REGEX_SATELLITE_CHASSIS.search(inventory_data[idx]['name'])) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception('Failed to find chassis in inventory output for host {}.'.format(ctx.host.hostname)) return
def process_inventory(self, ctx): """ For NCS1K, NCS5K and IOSXRv9K Chassis most likely shows up first in the output of "admin show inventory". Example for NCS1K: Name: Rack 0 Descr: Network Convergence System 1000 Controller PID: NCS1002 VID: V01 SN: CHANGE-ME- Example for NCS5K: Name: Rack 0 Descr: PID: NCS-5002 VID: V01 SN: FOC1946R0DH Example for IOSXRv: NAME: "Rack 0", DESCR: "Cisco XRv9K Virtual Router" PID: R-IOSXRV9000-CH , VID: V01, SN: DA55BD5FAC9 """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_RACK.match(inventory_data[idx]['name']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception('Failed to find chassis in inventory output for host {}.'.format(ctx.host.hostname)) return
def process_inventory(self, ctx): """ For ASR900 IOS. Example: NAME: "A901-6CZ-FT-A Chassis", DESCR: "A901-6CZ-FT-A Chassis" PID: A901-6CZ-FT-A , VID: V01 , SN: CAT1650U01P """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.match(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.match(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception('Failed to find chassis in inventory output for host {}.'.format(ctx.host.hostname)) return
def process_inventory(self, ctx): """ For CRS. There can be more than one chassis in this case. Example for CRS: NAME: "Rack 0 - Chassis", DESCR: "CRS 16 Slots Line Card Chassis for CRS-16/S-B" PID: CRS-16-LCC-B, VID: V03, SN: FXS1804Q576 """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.search(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception('Failed to find chassis in inventory output for host {}.'.format(ctx.host.hostname)) return
def process_inventory(self, ctx): """ For CRS. There can be more than one chassis in this case. Example for CRS: NAME: "Rack 0 - Chassis", DESCR: "CRS 16 Slots Line Card Chassis for CRS-16/S-B" PID: CRS-16-LCC-B, VID: V03, SN: FXS1804Q576 """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.search(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception( 'Failed to find chassis in inventory output for host {}.'.format( ctx.host.hostname)) return
def process_inventory(self, ctx): """ For ASR9K IOS-XR. There is only one chassis in this case. It most likely shows up last in the output of "admin show inventory". Example: NAME: "chassis ASR-9006-AC", DESCR: "ASR 9006 4 Line Card Slot Chassis with V1 AC PEM" PID: ASR-9006-AC, VID: V01, SN: FOX1523H7HA """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.search(inventory_data[idx]['name']) and \ (not self.REGEX_SATELLITE_CHASSIS.search(inventory_data[idx]['name'])) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception( 'Failed to find chassis in inventory output for host {}.'.format( ctx.host.hostname)) return
def process_inventory(self, ctx): """ For IOS-XE. There is only one chassis in this case. It most likely shows up first in the output of "show inventory". Example for IOS-XE: NAME: "Chassis", DESCR: "ASR 903 Series Router Chassis" PID: ASR-903 , VID: V01, SN: FOX1717P569 """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_CHASSIS.search(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception( 'Failed to find chassis in inventory output for host {}.'.format( ctx.host.hostname)) return
def start(self, ctx): pm = CSMPluginManager(ctx) try: pm.dispatch("run") except condoor.GeneralError as e: logger = get_db_session_logger(ctx.db_session) logger.error(str(e)) raise e
def store_inventory(self, ctx, inventory_data, chassis_indices): """ Store/update the processed inventory data in database :param ctx: context object :param inventory_data: parsed inventory data as a list of dictionaries :param chassis_indices: a list of index/indices of chassis inventory dictionary in inventory_data :return: None """ if len(chassis_indices ) == 0 or len(chassis_indices) > len(inventory_data): logger = get_db_session_logger(ctx.db_session) logger.exception( 'index/indices of chassis found in inventory output is out of range for host ' + '{}.'.format(ctx.host.hostname)) return # Assign the ordering or "position" of inventory in output from show inventory # to each inventory entry, but adjust the ordering so that chassis always have # negative position(s) (so as to mark corresponding inventory as chassis) # and non-chassis always have consecutive non-negative positions in ascending order, # It goes like this - if there is only one chassis, its position will be -1, # the non-chassis inventories will have positions starting from 0 # If there are multiple chassis, for example 3 chassis, chassis 0 will have position -3, # chassis 1 will have position -2, chassis 2 will have position -1, non-chassis will # still have positions starting from 0 chassis_position = 0 - len(chassis_indices) for chassis_idx in chassis_indices: inventory_data[chassis_idx]['position'] = chassis_position chassis_position += 1 idx = 0 position = 0 rack_number = 0 while idx < len(inventory_data): if rack_number < len(chassis_indices): if idx == chassis_indices[rack_number]: rack_number += 1 else: inventory_data[idx]['position'] = position position += 1 else: inventory_data[idx]['position'] = position position += 1 idx += 1 db_session = DBSession() # this is necessary for now because somewhere in the thread, can be # anywhere in the code, the db_session was not closed - to be found out later. db_session.close() if len(ctx.host.host_inventory) > 0: self.compare_and_update(ctx, db_session, inventory_data) else: self.store_new_inventory(db_session, inventory_data, ctx.host.id) db_session.close() return
def execute(self, ctx): try: self.start(ctx) self.post_processing(ctx) except Exception: # If there is no db_session, it is not important to log the exception if isinstance(ctx, ConnectionContext): logger = get_db_session_logger(ctx.db_session) logger.exception('execute() hit exception.')
def execute(self, ctx): try: self.start(ctx) self.post_processing(ctx) except Exception: # If there is no db_session, it is not important to log the exception if isinstance(ctx, ConnectionContext): logger = get_db_session_logger(ctx.db_session) logger.exception('BaseHandler.execute() hit exception - hostname = %s', ctx.hostname)
def store_inventory(self, ctx, inventory_data, chassis_indices): """ Store/update the processed inventory data in database :param ctx: context object :param inventory_data: parsed inventory data as a list of dictionaries :param chassis_indices: a list of index/indices of chassis inventory dictionary in inventory_data :return: None """ if len(chassis_indices) == 0 or len(chassis_indices) > len(inventory_data): logger = get_db_session_logger(ctx.db_session) logger.exception('index/indices of chassis found in inventory output is out of range for host ' + '{}.'.format(ctx.host.hostname)) return # Assign the ordering or "position" of inventory in output from show inventory # to each inventory entry, but adjust the ordering so that chassis always have # negative position(s) (so as to mark corresponding inventory as chassis) # and non-chassis always have consecutive non-negative positions in ascending order, # It goes like this - if there is only one chassis, its position will be -1, # the non-chassis inventories will have positions starting from 0 # If there are multiple chassis, for example 3 chassis, chassis 0 will have position -3, # chassis 1 will have position -2, chassis 2 will have position -1, non-chassis will # still have positions starting from 0 chassis_position = 0 - len(chassis_indices) for chassis_idx in chassis_indices: inventory_data[chassis_idx]['position'] = chassis_position chassis_position += 1 idx = 0 position = 0 rack_number = 0 while idx < len(inventory_data): if rack_number < len(chassis_indices): if idx == chassis_indices[rack_number]: rack_number += 1 else: inventory_data[idx]['position'] = position position += 1 else: inventory_data[idx]['position'] = position position += 1 idx += 1 db_session = DBSession() # this is necessary for now because somewhere in the thread, can be # anywhere in the code, the db_session was not closed - to be found out later. db_session.close() if len(ctx.host.host_inventory) > 0: self.compare_and_update(ctx, db_session, inventory_data) else: self.store_new_inventory(db_session, inventory_data, ctx.host.id) db_session.close() return
def post_processing(self, ctx): if isinstance(ctx, ConnectionContext): self.update_device_info(ctx) if isinstance(ctx, InstallContext): try: if ctx.requested_action == InstallAction.POST_UPGRADE: self.generate_post_upgrade_file_diff(ctx) except Exception: logger = get_db_session_logger(ctx.db_session) logger.exception('generate_post_upgrade_file_diff hit exception.')
def __init__(self, queue, *args, **kwds): """\param workq: Queue object to consume the work units from""" Process.__init__(self, *args, **kwds) self.queue = queue DATABASE_CONNECTION_INFO = URL(**db_settings) # Create the database engine engine = create_engine(DATABASE_CONNECTION_INFO, pool_size=20, pool_recycle=3600, convert_unicode=True, echo=ENABLE_DEBUG) self.db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))() self.logger = get_db_session_logger(self.db_session)
def __init__(self, queue, *args, **kwds): """\param workq: Queue object to consume the work units from""" Process.__init__(self, *args, **kwds) self.queue = queue DATABASE_CONNECTION_INFO = URL(**db_settings) # Create the database engine engine = create_engine(DATABASE_CONNECTION_INFO, pool_size=20, pool_recycle=3600, convert_unicode=True, encoding='latin1', echo=ENABLE_DEBUG) self.db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))() self.logger = get_db_session_logger(self.db_session)
def process_inventory(self, ctx): """ For ASR9K-64, NCS6K and NCS5500 Chassis most likely shows up first in the output of "admin show inventory". Example for ASR9K-64: Name: Rack 0 Descr: ASR-9904 AC Chassis PID: ASR-9904-AC VID: V01 SN: FOX1746GHJ9 Example for NCS6K: Name: Rack 0 Descr: NCS 6008 - 8-Slot Chassis PID: NCS-6008 VID: V01 SN: FLM17476JWA Example for NCS5500: Name: Rack 0 Descr: NCS5500 8 Slot Single Chassis PID: NCS-5508 VID: V01 SN: FGE194714QX """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_RACK.match(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception( 'Failed to find chassis in inventory output for host {}.'.format( ctx.host.hostname)) return
def post_processing(self, ctx): if isinstance(ctx, ConnectionContext): self.update_device_info(ctx) if isinstance(ctx, InventoryContext) or isinstance(ctx, InstallContext): self.get_inventory(ctx) if isinstance(ctx, InstallContext): try: if ctx.requested_action == InstallAction.POST_UPGRADE: self.generate_post_upgrade_file_diff(ctx) elif ctx.requested_action == InstallAction.MIGRATE_SYSTEM or \ ctx.requested_action == InstallAction.POST_MIGRATE: self.generate_post_migrate_file_diff(ctx) except Exception: logger = get_db_session_logger(ctx.db_session) if ctx.requested_action == InstallAction.POST_UPGRADE: msg = 'generate_post_upgrade_file_diff hit exception.' else: msg = 'generate_post_migrate_file_diff hit exception.' logger.exception(msg)
def process_inventory(self, ctx): """ For NCS1K, NCS5K and IOSXRv9K Chassis most likely shows up first in the output of "admin show inventory". Example for NCS1K: Name: Rack 0 Descr: Network Convergence System 1000 Controller PID: NCS1002 VID: V01 SN: CHANGE-ME- Example for NCS5K: Name: Rack 0 Descr: PID: NCS-5002 VID: V01 SN: FOC1946R0DH Example for IOSXRv: NAME: "Rack 0", DESCR: "Cisco XRv9K Virtual Router" PID: R-IOSXRV9000-CH , VID: V01, SN: DA55BD5FAC9 """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_RACK.match(inventory_data[idx]['name']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception( 'Failed to find chassis in inventory output for host {}.'.format( ctx.host.hostname)) return
def process_inventory(self, ctx): """ For ASR9K-64, NCS6K and NCS5500 Chassis most likely shows up first in the output of "admin show inventory". Example for ASR9K-64: Name: Rack 0 Descr: ASR-9904 AC Chassis PID: ASR-9904-AC VID: V01 SN: FOX1746GHJ9 Example for NCS6K: Name: Rack 0 Descr: NCS 6008 - 8-Slot Chassis PID: NCS-6008 VID: V01 SN: FLM17476JWA Example for NCS5500: Name: Rack 0 Descr: NCS5500 8 Slot Single Chassis PID: NCS-5508 VID: V01 SN: FGE194714QX """ if not ctx.load_data('cli_show_inventory'): return inventory_output = ctx.load_data('cli_show_inventory')[0] inventory_data = self.parse_inventory_output(inventory_output) chassis_indices = [] for idx in xrange(0, len(inventory_data)): if self.REGEX_RACK.match(inventory_data[idx]['name']) and \ self.REGEX_CHASSIS.search(inventory_data[idx]['description']): chassis_indices.append(idx) if chassis_indices: return self.store_inventory(ctx, inventory_data, chassis_indices) logger = get_db_session_logger(ctx.db_session) logger.exception('Failed to find chassis in inventory output for host {}.'.format(ctx.host.hostname)) return