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