1e7e9171eSGeorge Keishing#!/usr/bin/env python3 28023a8cfSSushil Singh 320f38712SPatrick Williamsimport json 48023a8cfSSushil Singhimport os 58023a8cfSSushil Singhimport re 68023a8cfSSushil Singhfrom collections import OrderedDict 78023a8cfSSushil Singh 820f38712SPatrick Williamsbmc_rec_pattern = "^=(.*)\n(.*)\n(.*)\n(.*)\n(.*)" 920f38712SPatrick Williamsbmc_prop_pattern = [r"\w+", r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", "443"] 1020f38712SPatrick Williamsbmc_rec_prop = ["hostname", "address", "port", "txt"] 118023a8cfSSushil Singh 128023a8cfSSushil Singh 138023a8cfSSushil Singhclass Exception(Exception): 148023a8cfSSushil Singh def __init__(self, exc_value): 158023a8cfSSushil Singh self.exc_value = exc_value 168023a8cfSSushil Singh 178023a8cfSSushil Singh def __str__(self): 188023a8cfSSushil Singh return repr(self.exc_value) 198023a8cfSSushil Singh 208023a8cfSSushil Singh 21c5e9ebc6SSushil Singhdef Check_bmc_record_exists(bmc_records, bmc_ip): 22c5e9ebc6SSushil Singh r""" 23c5e9ebc6SSushil Singh Parse the BMC records to check for passed input. 24c5e9ebc6SSushil Singh 25c5e9ebc6SSushil Singh Description of arguments: 26*4ebb3281SGeorge Keishing bmc_records Contains the list of discovered BMC records. 27c5e9ebc6SSushil Singh bmc_ip BMC ip address. 28c5e9ebc6SSushil Singh """ 29c5e9ebc6SSushil Singh 30c5e9ebc6SSushil Singh try: 31c5e9ebc6SSushil Singh for bmc_key, bmc_val in bmc_records.items(): 3220f38712SPatrick Williams temp_ip = bmc_val.get("address", None) 33c5e9ebc6SSushil Singh if bmc_ip.strip() == temp_ip.strip(): 34c5e9ebc6SSushil Singh return True 35c5e9ebc6SSushil Singh else: 36c5e9ebc6SSushil Singh return False 37c5e9ebc6SSushil Singh except Exception as exc_obj: 38c5e9ebc6SSushil Singh return exc_obj 39c5e9ebc6SSushil Singh 40c5e9ebc6SSushil Singh 4120f38712SPatrick Williamsdef validate_bmc_properties( 4220f38712SPatrick Williams bmc_prop_pattern, bmc_prop, bmc_value, bmc_rec_valid 4320f38712SPatrick Williams): 448023a8cfSSushil Singh r""" 458023a8cfSSushil Singh This function is to check pattern match in bmc properties. 468023a8cfSSushil Singh 478023a8cfSSushil Singh Description of arguments: 488023a8cfSSushil Singh bmc_prop_pattern Regex pattern. 498023a8cfSSushil Singh bmc_prop BMC property (e.g. hostname, address, port). 508023a8cfSSushil Singh bmc_value BMC property value. 518023a8cfSSushil Singh bmc_rec_valid Contain BMC properties record. 528023a8cfSSushil Singh """ 538023a8cfSSushil Singh 548023a8cfSSushil Singh try: 5520f38712SPatrick Williams status = [ 5620f38712SPatrick Williams lambda bmc_prop: re.search(bmc_prop_pattern, bmc_prob), 5720f38712SPatrick Williams bmc_value, 5820f38712SPatrick Williams ] 598023a8cfSSushil Singh if None in status: 608023a8cfSSushil Singh bmc_rec_valid[bmc_prop] = None 618023a8cfSSushil Singh except Exception as exc_obj: 628023a8cfSSushil Singh return exc_obj 638023a8cfSSushil Singh finally: 648023a8cfSSushil Singh return bmc_rec_valid 658023a8cfSSushil Singh 668023a8cfSSushil Singh 678023a8cfSSushil Singhdef bmc_record_validation(bmc_rec_valid): 688023a8cfSSushil Singh r""" 698023a8cfSSushil Singh Parse the BMC records to validate the data is valid. 708023a8cfSSushil Singh 718023a8cfSSushil Singh Description of arguments: 728023a8cfSSushil Singh bmc_rec_valid Contain BMC properties record. 738023a8cfSSushil Singh """ 748023a8cfSSushil Singh 758023a8cfSSushil Singh try: 7620f38712SPatrick Williams for bmc_prop_key, bmc_pattern_val in zip( 7720f38712SPatrick Williams bmc_rec_prop, bmc_prop_pattern 7820f38712SPatrick Williams ): 798023a8cfSSushil Singh bmc_prop_value = bmc_rec_valid.get(bmc_prop_key, False) 808023a8cfSSushil Singh if bmc_rec_valid[bmc_prop_key] is not False: 8120f38712SPatrick Williams valid_status = validate_bmc_properties( 8220f38712SPatrick Williams bmc_pattern_val, 838023a8cfSSushil Singh bmc_prop_key, 848023a8cfSSushil Singh bmc_prop_value, 8520f38712SPatrick Williams bmc_rec_valid, 8620f38712SPatrick Williams ) 878023a8cfSSushil Singh if None not in bmc_rec_valid.values(): 888023a8cfSSushil Singh return bmc_rec_valid 898023a8cfSSushil Singh else: 908023a8cfSSushil Singh return None 918023a8cfSSushil Singh except Exception as exc_obj: 928023a8cfSSushil Singh return exc_obj 938023a8cfSSushil Singh 948023a8cfSSushil Singh 958023a8cfSSushil Singhdef bmc_inventory(service_type, bmc_inv_record): 968023a8cfSSushil Singh r""" 978023a8cfSSushil Singh Parse single record of BMC inventory and pack to dictionary form. 988023a8cfSSushil Singh 998023a8cfSSushil Singh Description of arguments: 1008023a8cfSSushil Singh service_type Service type (e.g. _obmc_rest._tcp, _obmc_redfish._tcp). 1018023a8cfSSushil Singh bmc_inv_record Individual BMC inventory record. 1028023a8cfSSushil Singh 1038023a8cfSSushil Singh This function will return this variable i.e. 1048023a8cfSSushil Singh bmc_inv in dictionary form as mention below. 1058023a8cfSSushil Singh 1068023a8cfSSushil Singh Below are the discovered BMC detail. 1078023a8cfSSushil Singh 1088023a8cfSSushil Singh [service]: _obmc_XXXX._tcp 1098023a8cfSSushil Singh [hostname]: System Name 1108023a8cfSSushil Singh [address]: XXX.XXX.XXX.XXX 1118023a8cfSSushil Singh [port]: XXX 1128023a8cfSSushil Singh [txt]: 1138023a8cfSSushil Singh """ 1148023a8cfSSushil Singh 1158023a8cfSSushil Singh try: 1168023a8cfSSushil Singh exc_obj = None 1178023a8cfSSushil Singh bmc_inv = OrderedDict() 1188023a8cfSSushil Singh service_count = 0 11920f38712SPatrick Williams for line in bmc_inv_record.split("\n"): 1208023a8cfSSushil Singh if line == "": 1218023a8cfSSushil Singh pass 1228023a8cfSSushil Singh elif service_type in line: 12320f38712SPatrick Williams bmc_inv["service"] = service_type 1248023a8cfSSushil Singh service_count += 1 12520f38712SPatrick Williams elif not line.startswith("=") and service_count == 1: 12620f38712SPatrick Williams bmc_inv[line.split("=")[0].strip()] = str( 12720f38712SPatrick Williams line.split("=")[-1].strip() 12820f38712SPatrick Williams )[1:-1] 1298023a8cfSSushil Singh except Exception as exc_obj: 1308023a8cfSSushil Singh return exc_obj 1318023a8cfSSushil Singh finally: 1328023a8cfSSushil Singh valid_status = bmc_record_validation(bmc_inv) 1338023a8cfSSushil Singh if valid_status is None: 1348023a8cfSSushil Singh return None, exc_obj 1358023a8cfSSushil Singh else: 1368023a8cfSSushil Singh return valid_status, exc_obj 1378023a8cfSSushil Singh 1388023a8cfSSushil Singh 1398023a8cfSSushil Singhdef get_bmc_records(service_type, bmc_records): 1408023a8cfSSushil Singh r""" 1418023a8cfSSushil Singh Parse the string to filter BMC discovery. 1428023a8cfSSushil Singh 1438023a8cfSSushil Singh Description of arguments: 1448023a8cfSSushil Singh service_type Service type (e.g. RESTService, RedfishService). 145*4ebb3281SGeorge Keishing bmc_records Contains the list of discovered BMC records. 1468023a8cfSSushil Singh 1478023a8cfSSushil Singh This function will return this variable i.e. 1488023a8cfSSushil Singh bmc_inv_list in dictionary form as mention below. 1498023a8cfSSushil Singh 1508023a8cfSSushil Singh Below are the list of discovered BMC details. 1518023a8cfSSushil Singh [1]: 1528023a8cfSSushil Singh [service]: _obmc_XXXX._tcp 1538023a8cfSSushil Singh [hostname]: System Name 1548023a8cfSSushil Singh [address]: XXX.XXX.XXX.XXX 1558023a8cfSSushil Singh [port]: XXX 1568023a8cfSSushil Singh [txt]: 1578023a8cfSSushil Singh [2]: 1588023a8cfSSushil Singh [service]: _obmc_XXXX._tcp 1598023a8cfSSushil Singh [hostname]: System Name 1608023a8cfSSushil Singh [address]: XXX.XXX.XXX.XXX 1618023a8cfSSushil Singh [port]: XXX 1628023a8cfSSushil Singh [txt]: 1638023a8cfSSushil Singh """ 1648023a8cfSSushil Singh 1658023a8cfSSushil Singh try: 1668023a8cfSSushil Singh count = 0 1678023a8cfSSushil Singh exe_obj = None 1688023a8cfSSushil Singh bmc_inv_list = OrderedDict() 16920f38712SPatrick Williams for match in re.finditer(bmc_rec_pattern, bmc_records, re.MULTILINE): 17020f38712SPatrick Williams bmc_record, exc_msg = bmc_inventory(service_type, match.group()) 1718023a8cfSSushil Singh if bmc_record is not None and exc_msg is None: 1728023a8cfSSushil Singh count += 1 1738023a8cfSSushil Singh bmc_inv_list[count] = bmc_record 1748023a8cfSSushil Singh except Exception as exe_obj: 1758023a8cfSSushil Singh return exe_obj 1768023a8cfSSushil Singh finally: 1778023a8cfSSushil Singh if len(bmc_inv_list) == 0: 17820f38712SPatrick Williams "", exe_obj 1798023a8cfSSushil Singh else: 1808023a8cfSSushil Singh return bmc_inv_list, exe_obj 181