1#!/usr/bin/env python3
2
3r"""
4PEL functions.
5"""
6
7import func_args as fa
8import bmc_ssh_utils as bsu
9import json
10import pel_variables
11
12
13class peltool_exception(Exception):
14    r"""
15    Base class for peltool related exceptions.
16    """
17    def __init__(self, message):
18        self.message = message
19        super().__init__(self.message)
20
21
22def peltool(option_string, parse_json=True, **bsu_options):
23    r"""
24    Run peltool on the BMC with the caller's option string and return the result.
25
26    Example:
27
28    ${pel_results}=  Peltool  -l
29    Rprint Vars  pel_results
30
31    pel_results:
32      [0x50000031]:
33        [CompID]:                       0x1000
34        [PLID]:                         0x50000031
35        [Subsystem]:                    BMC Firmware
36        [Message]:                      An application had an internal failure
37        [SRC]:                          BD8D1002
38        [Commit Time]:                  02/25/2020  04:51:31
39        [Sev]:                          Unrecoverable Error
40        [CreatorID]:                    BMC
41
42    Description of argument(s):
43    option_string                   A string of options which are to be processed by the peltool command.
44    parse_json                      Indicates that the raw JSON data should parsed into a list of
45                                    dictionaries.
46    bsu_options                     Options to be passed directly to bmc_execute_command. See its prolog for
47                                    details.
48    """
49
50    bsu_options = fa.args_to_objects(bsu_options)
51    out_buf, stderr, rc = bsu.bmc_execute_command('peltool ' + option_string, **bsu_options)
52    if parse_json:
53        try:
54            return json.loads(out_buf)
55        except ValueError:
56            return {}
57    return out_buf
58
59
60def fetch_all_pel_ids_for_src(src_id, severity):
61    r"""
62    Fetch all PEL IDs for the input SRC ID based on the severity type
63    in the list format.
64
65    Description of arguments:
66    src_id      SRC ID (e.g. BC20E504).
67    severity    PEL severity (e.g. "Predictive Error"
68                                   "Recovered Error").
69    """
70
71    try:
72        src_pel_ids = []
73        pel_data = peltool(" -l")
74        pel_id_list = pel_data.keys()
75        for pel_id in pel_id_list:
76            # Check if required SRC ID with severity is present
77            if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)):
78                src_pel_ids.append(pel_id)
79
80        if not src_pel_ids:
81            raise peltool_exception(src_id + " with severity " + severity + " not present")
82    except Exception as e:
83        raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e))
84    return src_pel_ids
85
86
87def verify_src_signature_and_threshold(pel_id, attn_type, signature_desc, th_limit):
88    r"""
89    Verifies SRC details for the given PEL ID based on the required
90    attention type, signature description, threshold limits.
91
92    Description of arguments:
93    pel_id          PEL ID for the required SRC details to verify.
94    attn_type       Attention type (e.g. RE, CS, UNIT_CS).
95    signature_desc  Signature description of the error inject.
96    th_limit        Threshold limit (e.g. 1, 5, 32).
97    """
98
99    try:
100        pel_cmd = " -i " + pel_id
101        src_data = peltool(pel_cmd)
102        src_dict = src_data["Primary SRC"]["SRC Details"]
103        usr_data = src_data["User Data 1"]
104
105        # Example for signature in recoverable error
106        #
107        # "SRC Details": {
108        # "Attention Type": "RECOVERABLE",
109        # "Node": 0,
110        # "Target Type": "TYPE_OMIC",
111        # "Target Instance": 0,
112        # "Signature": "MC_OMI_DL_FIR[1]: OMI-DL0 UE on data flit"
113        # }
114        if (attn_type == "RE"):
115            if (src_dict["Attention Type"] != "RECOVERABLE"):
116                raise peltool_exception("Required Attention type " + attn_type + " not found")
117
118        # Example for signature in system checkstop error
119        #
120        # "SRC Details": {
121        # "Primary Attention": "system checkstop",
122        # "Signature Description": {
123        #    "Chip Desc": "node 0 proc 0 (P10 2.0)",
124        #    "Signature": "EQ_L2_FIR(0)[7] L2 directory read UE",
125        #    "Attn Type": "checkstop"
126        # }
127
128        elif (attn_type == "CS"):
129            if (src_dict["Primary Attention"] != "system checkstop"):
130                raise peltool_exception("Required Attention type " + attn_type + " not found")
131
132        elif (attn_type == "UNIT_CS"):
133            if (src_dict["Attention Type"] != "UNIT_CS"):
134                raise peltool_exception("Required Attention type " + attn_type + " not found")
135        else:
136            raise peltool_exception("Required Attention type " + attn_type + " not found")
137
138        if signature_desc not in src_dict["Signature"]:
139            raise peltool_exception("Required Signature " + signature_desc + " not found")
140
141        if (int(th_limit) != usr_data["Error Count"]):
142            raise peltool_exception("Required Threshold limit " + th_limit + " not found")
143
144    except Exception as e:
145        raise peltool_exception("Failed to verify SRC details : " + str(e))
146    return True
147
148
149def fetch_all_src():
150    r"""
151    Fetch all SRC IDs from peltool in the list format.
152    """
153    try:
154        src_id = []
155        pel_data = peltool(" -l")
156        if pel_data:
157            pel_id_list = pel_data.keys()
158            for pel_id in pel_id_list:
159                src_id.append(pel_data[pel_id]["SRC"])
160        else:
161            raise peltool_exception("No PEL entry found ..")
162    except Exception as e:
163        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
164    return src_id
165