1#!/usr/bin/env python3
2
3r"""
4PEL functions.
5"""
6
7import func_args as fa
8import bmc_ssh_utils as bsu
9import pel_variables
10
11import json
12import os
13import sys
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('peltool ' + option_string, **bsu_options)
60    if parse_json:
61        try:
62            return json.loads(out_buf)
63        except ValueError:
64            return {}
65    return out_buf
66
67
68def get_pel_data_from_bmc(include_hidden_pels=False,
69                          include_informational_pels=False):
70    r"""
71    Returns PEL data from BMC else throws exception.
72
73    Description of arguments:
74    include_hidden_pels           True/False (default: False).
75                                  Set True to get hidden PELs else False.
76    include_informational_pels    True/False (default: False).
77                                  Set True to get informational PELs else False.
78    """
79    try:
80        pel_cmd = " -l"
81        if include_hidden_pels:
82            pel_cmd = pel_cmd + " -h"
83        if include_informational_pels:
84            pel_cmd = pel_cmd + " -f"
85        pel_data = peltool(pel_cmd)
86        if not pel_data:
87            print("No PEL data present in BMC ...")
88    except Exception as e:
89        raise peltool_exception("Failed to get PEL data from BMC : " + str(e))
90    return pel_data
91
92
93def fetch_all_pel_ids_for_src(src_id, severity, include_hidden_pels=False):
94    r"""
95    Fetch all PEL IDs for the input SRC ID based on the severity type
96    in the list format.
97
98    Description of arguments:
99    src_id                SRC ID (e.g. BCXXYYYY).
100    severity              PEL severity (e.g. "Predictive Error"
101                                             "Recovered Error").
102    include_hidden_pels   True/False (default: False).
103                          Set True to get hidden PELs else False.
104    """
105
106    try:
107        src_pel_ids = []
108        pel_data = get_pel_data_from_bmc(include_hidden_pels)
109        pel_id_list = pel_data.keys()
110        for pel_id in pel_id_list:
111            # Check if required SRC ID with severity is present
112            if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)):
113                src_pel_ids.append(pel_id)
114
115        if not src_pel_ids:
116            raise peltool_exception(src_id + " with severity " + severity + " not present")
117    except Exception as e:
118        raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e))
119    return src_pel_ids
120
121
122def fetch_all_src(include_hidden_pels=False):
123    r"""
124    Fetch all SRC IDs from peltool in the list format.
125
126    include_hidden_pels       True/False (default: False).
127                              Set True to get hidden PELs else False.
128    """
129    try:
130        src_id = []
131        pel_data = get_pel_data_from_bmc(include_hidden_pels)
132        if pel_data:
133            pel_id_list = pel_data.keys()
134            for pel_id in pel_id_list:
135                src_id.append(pel_data[pel_id]["SRC"])
136        print("SRC IDs: " + str(src_id))
137    except Exception as e:
138        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
139    return src_id
140
141
142def check_for_unexpected_src(unexpected_src_list=[], include_hidden_pels=False):
143    r"""
144    From the given unexpected SRC list, check if any unexpected SRC created
145    on the BMC. Returns 0 if no SRC found else throws exception.
146
147    Description of arguments:
148    unexpected_src_list       Give unexpected SRCs in the list format.
149                              e.g.: ["BBXXYYYY", "AAXXYYYY"].
150
151    include_hidden_pels       True/False (default: False).
152                              Set True to get hidden PELs else False.
153    """
154    try:
155        unexpected_src_count = 0
156        if not unexpected_src_list:
157            print("Unexpected SRC list is empty.")
158        src_data = fetch_all_src(include_hidden_pels)
159        for src in unexpected_src_list:
160            if src in src_data:
161                print("Found an unexpected SRC : " + src)
162                unexpected_src_count = unexpected_src_count + 1
163        if (unexpected_src_count >= 1):
164            raise peltool_exception("Unexpected SRC found.")
165
166    except Exception as e:
167        raise peltool_exception("Failed to verify unexpected SRC list : " + str(e))
168    return unexpected_src_count
169
170
171def filter_unexpected_srcs(expected_srcs=None):
172    r"""
173    Return list of SRCs found in BMC after filtering expected SRCs.
174    If expected_srcs is None then all SRCs found in system are returned.
175
176    Description of arguments:
177    expected_srcs       List of expected SRCs. E.g. ["BBXXYYYY", "AAXXYYYY"].
178    """
179
180    srcs_found = fetch_all_src()
181    if not expected_srcs:
182        expected_srcs = []
183    print(expected_srcs)
184    return list(set(srcs_found) - set(expected_srcs))
185
186
187def get_bmc_event_log_id_for_pel(pel_id):
188    r"""
189    Return BMC event log ID for the given PEL ID.
190
191    Description of arguments:
192    pel_id       PEL ID. E.g. 0x50000021.
193    """
194
195    pel_data = peltool("-i " + pel_id)
196    print(pel_data)
197    bmc_id_for_pel = pel_data["Private Header"]["BMC Event Log Id"]
198    return bmc_id_for_pel
199