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