1#!/usr/bin/env python
2
3r"""
4PLDM functions.
5"""
6
7import re
8import var_funcs as vf
9import func_args as fa
10import bmc_ssh_utils as bsu
11import json
12import random
13import string
14
15
16def pldmtool(option_string, **bsu_options):
17
18    r"""
19    Run pldmtool on the BMC with the caller's option string and return the result.
20
21    Example:
22
23    ${pldm_results}=  Pldmtool  base GetPLDMTypes
24    Rprint Vars  pldm_results
25
26    pldm_results:
27      pldmtool base GetPLDMVersion -t 0
28      {
29          "Response": "1.0.0"
30      }
31
32    Description of argument(s):
33    option_string                   A string of options which are to be processed by the pldmtool command.
34    parse_results                   Parse the pldmtool results and return a dictionary rather than the raw
35                                    pldmtool output.
36    bsu_options                     Options to be passed directly to bmc_execute_command.  See its prolog for
37                                    details.
38    """
39
40    # This allows callers to specify arguments in python style (e.g. print_out=1 vs. print_out=${1}).
41    bsu_options = fa.args_to_objects(bsu_options)
42
43    stdout, stderr, rc = bsu.bmc_execute_command('pldmtool ' + option_string, **bsu_options)
44    if stderr:
45        return stderr
46    try:
47        return json.loads(stdout)
48    except ValueError:
49        return stdout
50
51
52def GetBIOSEnumAttributeOptionalValues(attr_val_table_data):
53
54    """
55    From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
56    attribute handle and its optional values for BIOS Enumeration type.
57
58    Description of argument(s):
59    attr_val_table_data     pldmtool output from GetBIOSTable table type AttributeValueTable
60                            e.g.
61                            [{
62                                  "AttributeHandle": 20,
63                                  "AttributeNameHandle": "23(pvm-pcie-error-inject)",
64                                  "AttributeType": "BIOSEnumeration",
65                                  "NumberOfPossibleValues": 2,
66                                  "PossibleValueStringHandle[0]": "3(Disabled)",
67                                  "PossibleValueStringHandle[1]": "4(Enabled)",
68                                  "NumberOfDefaultValues": 1,
69                                  "DefaultValueStringHandleIndex[0]": 1,
70                                  "StringHandle": "4(Enabled)"
71                             }]
72    @return                  Dictionary of BIOS attribute and its value.
73                             e.g. {'pvm_pcie_error_inject': ['Disabled', 'Enabled']}
74    """
75
76    attr_val_data_dict = {}
77    for item in attr_val_table_data:
78        for attr in item:
79            if (attr == "NumberOfPossibleValues"):
80                value_list = []
81                for i in range(0, int(item[attr])):
82                    attr_values = item["PossibleValueStringHandle[" + str(i) + "]"]
83                    value = re.search(r'\((.*?)\)', attr_values).group(1)
84                    if value:
85                        # Example:
86                        # value = '"Power Off"'
87                        if ' ' in value:
88                            value = '"' + value + '"'
89                        value_list.append(value)
90                    else:
91                        value_list.append('')
92
93                attr_handle = re.findall(r'\(.*?\)', item["AttributeNameHandle"])
94                attr_val_data_dict[attr_handle[0][1:-1]] = value_list
95    return attr_val_data_dict
96
97
98def GetBIOSStrAndIntAttributeHandles(attr_type, attr_val_table_data):
99
100    """
101    From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
102    attribute handle and its values based on the attribute type.
103
104    Description of argument(s):
105    attr_type               "BIOSInteger" or "BIOSString".
106    attr_val_table_data     pldmtool output from GetBIOSTable table type AttributeValueTable.
107
108    @return                 Dict of BIOS attribute and its value based on attribute type.
109
110    """
111    attr_val_int_dict = {}
112    attr_val_str_dict = {}
113    for item in attr_val_table_data:
114        value_dict = {}
115        attr_handle = re.findall(r'\(.*?\)', item["AttributeNameHandle"])
116        # Example:
117        # {'vmi_if0_ipv4_prefix_length': {'UpperBound': 32, 'LowerBound': 0}
118        if (item["AttributeType"] == "BIOSInteger"):
119            value_dict["LowerBound"] = item["LowerBound"]
120            value_dict["UpperBound"] = item["UpperBound"]
121            attr_val_int_dict[attr_handle[0][1:-1]] = value_dict
122        # Example:
123        # {'vmi_if1_ipv4_ipaddr': {'MaximumStringLength': 15, 'MinimumStringLength': 7}}
124        elif (item["AttributeType"] == "BIOSString"):
125            value_dict["MinimumStringLength"] = item["MinimumStringLength"]
126            value_dict["MaximumStringLength"] = item["MaximumStringLength"]
127            attr_val_str_dict[attr_handle[0][1:-1]] = value_dict
128
129    if (attr_type == "BIOSInteger"):
130        return attr_val_int_dict
131    elif (attr_type == "BIOSString"):
132        return attr_val_str_dict
133
134
135def GetRandomBIOSIntAndStrValues(attr_name, count):
136
137    """
138    Get random integer or string values for BIOS attribute values based on the count.
139
140    Description of argument(s):
141    attr_name               Attribute name of BIOS attribute type Integer or string.
142    count                   Max length for BIOS attribute type Integer or string.
143
144    @return                 Random attribute value based on BIOS attribute type Integer
145                            or string.
146
147    """
148    attr_random_value = ''
149
150    # Example
151    # 12.13.14.15
152    if 'gateway' in attr_name:
153        attr_random_value = ".".join(map(str, (random.randint(0, 255) for _ in range(4))))
154    # Example
155    # 11.11.11.11
156    elif 'ipaddr' in attr_name:
157        attr_random_value = ".".join(map(str, (random.randint(0, 255) for _ in range(4))))
158    # Example
159    # E5YWEDWJJ
160    elif 'name' in attr_name:
161        data = string.ascii_uppercase + string.digits
162        attr_random_value = ''.join(random.choice(data) for _ in range(int(count)))
163
164    elif 'mfg_flags' in attr_name:
165        data = string.ascii_uppercase + string.digits
166        attr_random_value = ''.join(random.choice(data) for _ in range(int(count)))
167
168    else:
169        attr_random_value = random.randint(0, int(count))
170    return attr_random_value
171
172
173def GetBIOSAttrOriginalValues(attr_val_table_data):
174
175    """
176    From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
177    attribute handle and its values.
178
179    Description of argument(s):
180    attr_val_table_data     pldmtool output from GetBIOSTable table type AttributeValueTable.
181
182    @return                 Dict of BIOS attribute and its value.
183
184    """
185    attr_val_data_dict = {}
186    for item in attr_val_table_data:
187        attr_handle = re.findall(r'\(.*?\)', item["AttributeNameHandle"])
188        attr_name = attr_handle[0][1:-1]
189
190        command = "bios GetBIOSAttributeCurrentValueByHandle -a " + attr_name
191        value = pldmtool(command)
192        attr_val_data_dict[attr_name] = value["CurrentValue"]
193        if not value["CurrentValue"]:
194            if 'name' in attr_name:
195                attr_val_data_dict[attr_name] = '""'
196
197    return attr_val_data_dict
198
199
200def GetBIOSAttrDefaultValues(attr_val_table_data):
201
202    """
203    From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
204    attribute handle and its default attribute values.
205
206    Description of argument(s):
207    attr_val_table_data     pldmtool output from GetBIOSTable table type AttributeValueTable.
208
209    @return                 Dict of BIOS attribute and its default attribute value.
210
211    """
212    attr_val_data_dict = {}
213    for item in attr_val_table_data:
214        attr_handle = re.findall(r'\(.*?\)', item["AttributeNameHandle"])
215        attr_name = attr_handle[0][1:-1]
216
217        if "DefaultString" in item:
218            attr_val_data_dict[attr_name] = item["DefaultString"]
219            if not item["DefaultString"]:
220                if 'name' in attr_name:
221                    attr_val_data_dict[attr_name] = '""'
222        elif "DefaultValue" in item:
223            attr_val_data_dict[attr_name] = item["DefaultValue"]
224        elif "StringHandle" in item:
225            attr_default_value = re.findall(r'\(.*?\)', item["StringHandle"])
226            attr_val_data_dict[attr_name] = attr_default_value[0][1:-1]
227
228    return attr_val_data_dict
229