#!/usr/bin/env python import os import re import json from data import variables from collections import OrderedDict bmc_rec_pattern = '^=(.*)\n(.*)\n(.*)\n(.*)\n(.*)' bmc_prop_pattern = [r"\w+", r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", '443'] bmc_rec_prop = ['hostname', 'address', 'port', 'txt'] class Exception(Exception): def __init__(self, exc_value): self.exc_value = exc_value def __str__(self): return repr(self.exc_value) def Check_bmc_record_exists(bmc_records, bmc_ip): r""" Parse the BMC records to check for passed input. Description of arguments: bmc_records Contains the list of discoverd BMC records. bmc_ip BMC ip address. """ try: for bmc_key, bmc_val in bmc_records.items(): temp_ip = bmc_val.get('address', None) if bmc_ip.strip() == temp_ip.strip(): return True else: return False except Exception as exc_obj: return exc_obj def validate_bmc_properties(bmc_prop_pattern, bmc_prop, bmc_value, bmc_rec_valid): r""" This function is to check pattern match in bmc properties. Description of arguments: bmc_prop_pattern Regex pattern. bmc_prop BMC property (e.g. hostname, address, port). bmc_value BMC property value. bmc_rec_valid Contain BMC properties record. """ try: status = \ [lambda bmc_prop: re.search(bmc_prop_pattern, bmc_prob), bmc_value] if None in status: bmc_rec_valid[bmc_prop] = None except Exception as exc_obj: return exc_obj finally: return bmc_rec_valid def bmc_record_validation(bmc_rec_valid): r""" Parse the BMC records to validate the data is valid. Description of arguments: bmc_rec_valid Contain BMC properties record. """ try: for bmc_prop_key, bmc_pattern_val in \ zip(bmc_rec_prop, bmc_prop_pattern): bmc_prop_value = bmc_rec_valid.get(bmc_prop_key, False) if bmc_rec_valid[bmc_prop_key] is not False: valid_status = validate_bmc_properties(bmc_pattern_val, bmc_prop_key, bmc_prop_value, bmc_rec_valid) if None not in bmc_rec_valid.values(): return bmc_rec_valid else: return None except Exception as exc_obj: return exc_obj def bmc_inventory(service_type, bmc_inv_record): r""" Parse single record of BMC inventory and pack to dictionary form. Description of arguments: service_type Service type (e.g. _obmc_rest._tcp, _obmc_redfish._tcp). bmc_inv_record Individual BMC inventory record. This function will return this variable i.e. bmc_inv in dictionary form as mention below. Below are the discovered BMC detail. [service]: _obmc_XXXX._tcp [hostname]: System Name [address]: XXX.XXX.XXX.XXX [port]: XXX [txt]: """ try: exc_obj = None bmc_inv = OrderedDict() service_count = 0 for line in bmc_inv_record.split('\n'): if line == "": pass elif service_type in line: bmc_inv['service'] = service_type service_count += 1 elif not line.startswith('=') and service_count == 1: bmc_inv[line.split('=')[0].strip()] = \ str(line.split('=')[-1].strip())[1:-1] except Exception as exc_obj: return exc_obj finally: valid_status = bmc_record_validation(bmc_inv) if valid_status is None: return None, exc_obj else: return valid_status, exc_obj def get_bmc_records(service_type, bmc_records): r""" Parse the string to filter BMC discovery. Description of arguments: service_type Service type (e.g. RESTService, RedfishService). bmc_records Contains the list of discoverd BMC records. This function will return this variable i.e. bmc_inv_list in dictionary form as mention below. Below are the list of discovered BMC details. [1]: [service]: _obmc_XXXX._tcp [hostname]: System Name [address]: XXX.XXX.XXX.XXX [port]: XXX [txt]: [2]: [service]: _obmc_XXXX._tcp [hostname]: System Name [address]: XXX.XXX.XXX.XXX [port]: XXX [txt]: """ try: count = 0 exe_obj = None bmc_inv_list = OrderedDict() for match in re.finditer(bmc_rec_pattern, bmc_records, re.MULTILINE): bmc_record, exc_msg = \ bmc_inventory(service_type, match.group()) if bmc_record is not None and exc_msg is None: count += 1 bmc_inv_list[count] = bmc_record except Exception as exe_obj: return exe_obj finally: if len(bmc_inv_list) == 0: '', exe_obj else: return bmc_inv_list, exe_obj