xref: /openbmc/openbmc-test-automation/lib/external_intf/management_console_utils.py (revision 2b798c7cc1002ce096d00df8ba959d9974d4c793)
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