1#!/usr/bin/env python3
2
3r"""
4PEL functions.
5"""
6
7import json
8import os
9import sys
10
11import bmc_ssh_utils as bsu
12import func_args as fa
13import pel_variables
14from robot.libraries.BuiltIn import BuiltIn
15
16base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17sys.path.append(base_path + "/data/")
18
19
20class peltool_exception(Exception):
21    r"""
22    Base class for peltool related exceptions.
23    """
24
25    def __init__(self, message):
26        self.message = message
27        super().__init__(self.message)
28
29
30def peltool(option_string, parse_json=True, **bsu_options):
31    r"""
32    Run peltool on the BMC with the caller's option string and return the result.
33
34    Example:
35
36    ${pel_results}=  Peltool  -l
37    Rprint Vars  pel_results
38
39    pel_results:
40      [0x50000031]:
41        [CompID]:                       0x1000
42        [PLID]:                         0x50000031
43        [Subsystem]:                    BMC Firmware
44        [Message]:                      An application had an internal failure
45        [SRC]:                          BD8D1002
46        [Commit Time]:                  02/25/2020  04:51:31
47        [Sev]:                          Unrecoverable Error
48        [CreatorID]:                    BMC
49
50    Description of argument(s):
51    option_string                   A string of options which are to be processed by the peltool command.
52    parse_json                      Indicates that the raw JSON data should parsed into a list of
53                                    dictionaries.
54    bsu_options                     Options to be passed directly to bmc_execute_command. See its prolog for
55                                    details.
56    """
57
58    bsu_options = fa.args_to_objects(bsu_options)
59    out_buf, stderr, rc = bsu.bmc_execute_command(
60        "peltool " + option_string, **bsu_options
61    )
62    if parse_json:
63        try:
64            return json.loads(out_buf)
65        except ValueError:
66            return {}
67    return out_buf
68
69
70def get_pel_data_from_bmc(
71    include_hidden_pels=False, include_informational_pels=False
72):
73    r"""
74    Returns PEL data from BMC else throws exception.
75
76    Description of arguments:
77    include_hidden_pels           True/False (default: False).
78                                  Set True to get hidden PELs else False.
79    include_informational_pels    True/False (default: False).
80                                  Set True to get informational PELs else False.
81    """
82    try:
83        pel_cmd = " -l"
84        if include_hidden_pels:
85            pel_cmd = pel_cmd + " -h"
86        if include_informational_pels:
87            pel_cmd = pel_cmd + " -f"
88        pel_data = peltool(pel_cmd)
89        if not pel_data:
90            print("No PEL data present in BMC ...")
91    except Exception as e:
92        raise peltool_exception("Failed to get PEL data from BMC : " + str(e))
93    return pel_data
94
95
96def fetch_all_pel_ids_for_src(src_id, severity, include_hidden_pels=False):
97    r"""
98    Fetch all PEL IDs for the input SRC ID based on the severity type
99    in the list format.
100
101    Description of arguments:
102    src_id                SRC ID (e.g. BCXXYYYY).
103    severity              PEL severity (e.g. "Predictive Error"
104                                             "Recovered Error").
105    include_hidden_pels   True/False (default: False).
106                          Set True to get hidden PELs else False.
107    """
108
109    try:
110        src_pel_ids = []
111        pel_data = get_pel_data_from_bmc(include_hidden_pels)
112        pel_id_list = pel_data.keys()
113        for pel_id in pel_id_list:
114            # Check if required SRC ID with severity is present
115            if (pel_data[pel_id]["SRC"] == src_id) and (
116                pel_data[pel_id]["Sev"] == severity
117            ):
118                src_pel_ids.append(pel_id)
119
120        if not src_pel_ids:
121            raise peltool_exception(
122                src_id + " with severity " + severity + " not present"
123            )
124    except Exception as e:
125        raise peltool_exception(
126            "Failed to fetch PEL ID for required SRC : " + str(e)
127        )
128    return src_pel_ids
129
130
131def fetch_all_src(include_hidden_pels=False):
132    r"""
133    Fetch all SRC IDs from peltool in the list format.
134
135    include_hidden_pels       True/False (default: False).
136                              Set True to get hidden PELs else False.
137    """
138    try:
139        src_id = []
140        pel_data = get_pel_data_from_bmc(include_hidden_pels)
141        if pel_data:
142            pel_id_list = pel_data.keys()
143            for pel_id in pel_id_list:
144                src_id.append(pel_data[pel_id]["SRC"])
145        print("SRC IDs: " + str(src_id))
146    except Exception as e:
147        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
148    return src_id
149
150
151def check_for_unexpected_src(
152    unexpected_src_list=[], include_hidden_pels=False
153):
154    r"""
155    From the given unexpected SRC list, check if any unexpected SRC created
156    on the BMC. Returns 0 if no SRC found else throws exception.
157
158    Description of arguments:
159    unexpected_src_list       Give unexpected SRCs in the list format.
160                              e.g.: ["BBXXYYYY", "AAXXYYYY"].
161
162    include_hidden_pels       True/False (default: False).
163                              Set True to get hidden PELs else False.
164    """
165    try:
166        unexpected_src_count = 0
167        if not unexpected_src_list:
168            print("Unexpected SRC list is empty.")
169        src_data = fetch_all_src(include_hidden_pels)
170        for src in unexpected_src_list:
171            if src in src_data:
172                print("Found an unexpected SRC : " + src)
173                unexpected_src_count = unexpected_src_count + 1
174        if unexpected_src_count >= 1:
175            raise peltool_exception("Unexpected SRC found.")
176
177    except Exception as e:
178        raise peltool_exception(
179            "Failed to verify unexpected SRC list : " + str(e)
180        )
181    return unexpected_src_count
182
183
184def filter_unexpected_srcs(expected_srcs=None):
185    r"""
186    Return list of SRCs found in BMC after filtering expected SRCs.
187    If expected_srcs is None then all SRCs found in system are returned.
188
189    Description of arguments:
190    expected_srcs       List of expected SRCs. E.g. ["BBXXYYYY", "AAXXYYYY"].
191    """
192
193    srcs_found = fetch_all_src()
194    if not expected_srcs:
195        expected_srcs = []
196    print(expected_srcs)
197    return list(set(srcs_found) - set(expected_srcs))
198
199
200def get_bmc_event_log_id_for_pel(pel_id):
201    r"""
202    Return BMC event log ID for the given PEL ID.
203
204    Description of arguments:
205    pel_id       PEL ID. E.g. 0x50000021.
206    """
207
208    pel_data = peltool("-i " + pel_id)
209    print(pel_data)
210    bmc_id_for_pel = pel_data["Private Header"]["BMC Event Log Id"]
211    return bmc_id_for_pel
212