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