1#!/usr/bin/env python3 2 3import json 4import os 5import re 6from collections import OrderedDict 7 8bmc_rec_pattern = "^=(.*)\n(.*)\n(.*)\n(.*)\n(.*)" 9bmc_prop_pattern = [r"\w+", r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", "443"] 10bmc_rec_prop = ["hostname", "address", "port", "txt"] 11 12 13class Exception(Exception): 14 def __init__(self, exc_value): 15 self.exc_value = exc_value 16 17 def __str__(self): 18 return repr(self.exc_value) 19 20 21def Check_bmc_record_exists(bmc_records, bmc_ip): 22 r""" 23 Parse the BMC records to check for passed input. 24 25 Description of arguments: 26 bmc_records Contains the list of discovered BMC records. 27 bmc_ip BMC ip address. 28 """ 29 30 try: 31 for bmc_key, bmc_val in bmc_records.items(): 32 temp_ip = bmc_val.get("address", None) 33 if bmc_ip.strip() == temp_ip.strip(): 34 return True 35 else: 36 return False 37 except Exception as exc_obj: 38 return exc_obj 39 40 41def validate_bmc_properties( 42 bmc_prop_pattern, bmc_prop, bmc_value, bmc_rec_valid 43): 44 r""" 45 This function is to check pattern match in bmc properties. 46 47 Description of arguments: 48 bmc_prop_pattern Regex pattern. 49 bmc_prop BMC property (e.g. hostname, address, port). 50 bmc_value BMC property value. 51 bmc_rec_valid Contain BMC properties record. 52 """ 53 54 try: 55 status = [ 56 lambda bmc_prop: re.search(bmc_prop_pattern, bmc_prob), 57 bmc_value, 58 ] 59 if None in status: 60 bmc_rec_valid[bmc_prop] = None 61 except Exception as exc_obj: 62 return exc_obj 63 finally: 64 return bmc_rec_valid 65 66 67def bmc_record_validation(bmc_rec_valid): 68 r""" 69 Parse the BMC records to validate the data is valid. 70 71 Description of arguments: 72 bmc_rec_valid Contain BMC properties record. 73 """ 74 75 try: 76 for bmc_prop_key, bmc_pattern_val in zip( 77 bmc_rec_prop, bmc_prop_pattern 78 ): 79 bmc_prop_value = bmc_rec_valid.get(bmc_prop_key, False) 80 if bmc_rec_valid[bmc_prop_key] is not False: 81 valid_status = validate_bmc_properties( 82 bmc_pattern_val, 83 bmc_prop_key, 84 bmc_prop_value, 85 bmc_rec_valid, 86 ) 87 if None not in bmc_rec_valid.values(): 88 return bmc_rec_valid 89 else: 90 return None 91 except Exception as exc_obj: 92 return exc_obj 93 94 95def bmc_inventory(service_type, bmc_inv_record): 96 r""" 97 Parse single record of BMC inventory and pack to dictionary form. 98 99 Description of arguments: 100 service_type Service type (e.g. _obmc_rest._tcp, _obmc_redfish._tcp). 101 bmc_inv_record Individual BMC inventory record. 102 103 This function will return this variable i.e. 104 bmc_inv in dictionary form as mention below. 105 106 Below are the discovered BMC detail. 107 108 [service]: _obmc_XXXX._tcp 109 [hostname]: System Name 110 [address]: XXX.XXX.XXX.XXX 111 [port]: XXX 112 [txt]: 113 """ 114 115 try: 116 exc_obj = None 117 bmc_inv = OrderedDict() 118 service_count = 0 119 for line in bmc_inv_record.split("\n"): 120 if line == "": 121 pass 122 elif service_type in line: 123 bmc_inv["service"] = service_type 124 service_count += 1 125 elif not line.startswith("=") and service_count == 1: 126 bmc_inv[line.split("=")[0].strip()] = str( 127 line.split("=")[-1].strip() 128 )[1:-1] 129 except Exception as exc_obj: 130 return exc_obj 131 finally: 132 valid_status = bmc_record_validation(bmc_inv) 133 if valid_status is None: 134 return None, exc_obj 135 else: 136 return valid_status, exc_obj 137 138 139def get_bmc_records(service_type, bmc_records): 140 r""" 141 Parse the string to filter BMC discovery. 142 143 Description of arguments: 144 service_type Service type (e.g. RESTService, RedfishService). 145 bmc_records Contains the list of discovered BMC records. 146 147 This function will return this variable i.e. 148 bmc_inv_list in dictionary form as mention below. 149 150 Below are the list of discovered BMC details. 151 [1]: 152 [service]: _obmc_XXXX._tcp 153 [hostname]: System Name 154 [address]: XXX.XXX.XXX.XXX 155 [port]: XXX 156 [txt]: 157 [2]: 158 [service]: _obmc_XXXX._tcp 159 [hostname]: System Name 160 [address]: XXX.XXX.XXX.XXX 161 [port]: XXX 162 [txt]: 163 """ 164 165 try: 166 count = 0 167 exe_obj = None 168 bmc_inv_list = OrderedDict() 169 for match in re.finditer(bmc_rec_pattern, bmc_records, re.MULTILINE): 170 bmc_record, exc_msg = bmc_inventory(service_type, match.group()) 171 if bmc_record is not None and exc_msg is None: 172 count += 1 173 bmc_inv_list[count] = bmc_record 174 except Exception as exe_obj: 175 return exe_obj 176 finally: 177 if len(bmc_inv_list) == 0: 178 "", exe_obj 179 else: 180 return bmc_inv_list, exe_obj 181