xref: /openbmc/telemetry/redfish-tests/redfish_requests.py (revision 2d5404f1381861f1d85ada402ab155e2bddc4abe)
1405c1e4bSWludzik, Jozefimport enum
2405c1e4bSWludzik, Jozefimport math
3405c1e4bSWludzik, Jozefimport re
4*2d5404f1SPatrick Williams
5405c1e4bSWludzik, Jozefimport requests
6405c1e4bSWludzik, Jozef
7405c1e4bSWludzik, Jozef
8405c1e4bSWludzik, Jozefclass RedfishHttpStatus(enum.IntEnum):
9405c1e4bSWludzik, Jozef    ok = 200
10405c1e4bSWludzik, Jozef    created = 201
11405c1e4bSWludzik, Jozef    no_content = 204
12405c1e4bSWludzik, Jozef    bad_request = 400
13405c1e4bSWludzik, Jozef    not_found = 404
14405c1e4bSWludzik, Jozef    internal_server_error = 500
15405c1e4bSWludzik, Jozef
16405c1e4bSWludzik, Jozef
17405c1e4bSWludzik, Jozefclass RedfishRequest:
18*2d5404f1SPatrick Williams    telemetry_service_path = "/redfish/v1/TelemetryService"
19*2d5404f1SPatrick Williams    metric_definition_path = f"{telemetry_service_path}/MetricDefinitions"
20*2d5404f1SPatrick Williams    metric_report_definition_path = (
21*2d5404f1SPatrick Williams        f"{telemetry_service_path}/MetricReportDefinitions"
22*2d5404f1SPatrick Williams    )
23*2d5404f1SPatrick Williams    metric_report_path = f"{telemetry_service_path}/MetricReports"
24405c1e4bSWludzik, Jozef
25405c1e4bSWludzik, Jozef    def __init__(self, host_addr, username, password):
26405c1e4bSWludzik, Jozef        self.host_addr = host_addr
27405c1e4bSWludzik, Jozef        self.username = username
28405c1e4bSWludzik, Jozef        self.password = password
29405c1e4bSWludzik, Jozef
30405c1e4bSWludzik, Jozef    def get(self, path, code=RedfishHttpStatus.ok):
31405c1e4bSWludzik, Jozef        u = self.host_addr + path
32405c1e4bSWludzik, Jozef        r = requests.get(u, auth=(self.username, self.password), verify=False)
33*2d5404f1SPatrick Williams        assert (
34*2d5404f1SPatrick Williams            r.status_code == code
35*2d5404f1SPatrick Williams        ), f"{r.status_code} == {code} on path {u}\n{r.text}"
36405c1e4bSWludzik, Jozef        print(r.text)
37405c1e4bSWludzik, Jozef        return r.json()
38405c1e4bSWludzik, Jozef
39405c1e4bSWludzik, Jozef    def post(self, path, body, code=RedfishHttpStatus.created):
40405c1e4bSWludzik, Jozef        u = self.host_addr + path
41*2d5404f1SPatrick Williams        r = requests.post(
42*2d5404f1SPatrick Williams            u, auth=(self.username, self.password), verify=False, json=body
43*2d5404f1SPatrick Williams        )
44*2d5404f1SPatrick Williams        assert (
45*2d5404f1SPatrick Williams            r.status_code == code
46*2d5404f1SPatrick Williams        ), f"{r.status_code} == {code} on path {u}\n{r.text}"
47405c1e4bSWludzik, Jozef        print(r.text)
48405c1e4bSWludzik, Jozef        return r.json()
49405c1e4bSWludzik, Jozef
50405c1e4bSWludzik, Jozef    def delete(self, path, code=RedfishHttpStatus.no_content):
51405c1e4bSWludzik, Jozef        u = self.host_addr + path
52*2d5404f1SPatrick Williams        r = requests.delete(
53*2d5404f1SPatrick Williams            u, auth=(self.username, self.password), verify=False
54*2d5404f1SPatrick Williams        )
55*2d5404f1SPatrick Williams        assert (
56*2d5404f1SPatrick Williams            r.status_code == code
57*2d5404f1SPatrick Williams        ), f"{r.status_code} == {code} on path {u}\n{r.text}"
58405c1e4bSWludzik, Jozef
59405c1e4bSWludzik, Jozef
60405c1e4bSWludzik, Jozefclass TelemetryService:
61405c1e4bSWludzik, Jozef    def __init__(self, redfish, metric_limit):
62405c1e4bSWludzik, Jozef        r = redfish.get(redfish.telemetry_service_path)
63*2d5404f1SPatrick Williams        self.min_interval = Duration.to_seconds(r["MinCollectionInterval"])
64*2d5404f1SPatrick Williams        self.max_reports = r["MaxReports"]
65405c1e4bSWludzik, Jozef        self.metrics = []
66405c1e4bSWludzik, Jozef        r = redfish.get(redfish.metric_definition_path)
67*2d5404f1SPatrick Williams        for m in r["Members"]:
68*2d5404f1SPatrick Williams            path = m["@odata.id"]
69405c1e4bSWludzik, Jozef            metricDef = redfish.get(path)
70*2d5404f1SPatrick Williams            self.metrics += [x for x in metricDef["MetricProperties"]]
71405c1e4bSWludzik, Jozef        self.metrics = self.metrics[:metric_limit]
72405c1e4bSWludzik, Jozef
73405c1e4bSWludzik, Jozef
74405c1e4bSWludzik, Jozefclass ReportDef:
75405c1e4bSWludzik, Jozef    def __init__(self, redfish):
76405c1e4bSWludzik, Jozef        self.redfish = redfish
77405c1e4bSWludzik, Jozef
78405c1e4bSWludzik, Jozef    def get_collection(self):
79405c1e4bSWludzik, Jozef        r = self.redfish.get(self.redfish.metric_report_definition_path)
80*2d5404f1SPatrick Williams        return [x["@odata.id"] for x in r["Members"]]
81405c1e4bSWludzik, Jozef
82*2d5404f1SPatrick Williams    def add_report(
83*2d5404f1SPatrick Williams        self,
84*2d5404f1SPatrick Williams        id,
85*2d5404f1SPatrick Williams        metrics=None,
86*2d5404f1SPatrick Williams        type="OnRequest",
87*2d5404f1SPatrick Williams        actions=None,
88*2d5404f1SPatrick Williams        interval=None,
89*2d5404f1SPatrick Williams        code=RedfishHttpStatus.created,
90*2d5404f1SPatrick Williams    ):
91405c1e4bSWludzik, Jozef        body = {
92*2d5404f1SPatrick Williams            "Id": id,
93*2d5404f1SPatrick Williams            "Metrics": [],
94*2d5404f1SPatrick Williams            "MetricReportDefinitionType": type,
95*2d5404f1SPatrick Williams            "ReportActions": ["RedfishEvent", "LogToMetricReportsCollection"],
96405c1e4bSWludzik, Jozef        }
97405c1e4bSWludzik, Jozef        if metrics is not None:
98*2d5404f1SPatrick Williams            body["Metrics"] = metrics
99405c1e4bSWludzik, Jozef        if actions is not None:
100*2d5404f1SPatrick Williams            body["ReportActions"] = actions
101405c1e4bSWludzik, Jozef        if interval is not None:
102*2d5404f1SPatrick Williams            body["Schedule"] = {"RecurrenceInterval": interval}
103*2d5404f1SPatrick Williams        return self.redfish.post(
104*2d5404f1SPatrick Williams            self.redfish.metric_report_definition_path, body, code
105*2d5404f1SPatrick Williams        )
106405c1e4bSWludzik, Jozef
107405c1e4bSWludzik, Jozef    def delete_report(self, path):
108*2d5404f1SPatrick Williams        self.redfish.delete(f"{path}")
109405c1e4bSWludzik, Jozef
110405c1e4bSWludzik, Jozef
111405c1e4bSWludzik, Jozefclass Duration:
112405c1e4bSWludzik, Jozef    def __init__(self):
113405c1e4bSWludzik, Jozef        pass
114405c1e4bSWludzik, Jozef
115405c1e4bSWludzik, Jozef    def to_iso8061(time):
116*2d5404f1SPatrick Williams        assert time >= 0, "Invalid argument, time is negative"
117405c1e4bSWludzik, Jozef        days = int(time / (24 * 60 * 60))
118405c1e4bSWludzik, Jozef        time = math.fmod(time, (24 * 60 * 60))
119405c1e4bSWludzik, Jozef        hours = int(time / (60 * 60))
120405c1e4bSWludzik, Jozef        time = math.fmod(time, (60 * 60))
121405c1e4bSWludzik, Jozef        minutes = int(time / 60)
122405c1e4bSWludzik, Jozef        time = round(math.fmod(time, 60), 3)
123*2d5404f1SPatrick Williams        return f"P{str(days)}DT{str(hours)}H{str(minutes)}M{str(time)}S"
124405c1e4bSWludzik, Jozef
125405c1e4bSWludzik, Jozef    def to_seconds(duration):
126*2d5404f1SPatrick Williams        r = re.fullmatch(
127*2d5404f1SPatrick Williams            r"-?P(\d+D)?(T(\d+H)?(\d+M)?(\d+(.\d+)?S)?)?", duration
128*2d5404f1SPatrick Williams        )
129*2d5404f1SPatrick Williams        assert r, "Invalid argument, not match with regex"
130405c1e4bSWludzik, Jozef        days = r.group(1)
131405c1e4bSWludzik, Jozef        hours = r.group(3)
132405c1e4bSWludzik, Jozef        minutes = r.group(4)
133405c1e4bSWludzik, Jozef        seconds = r.group(5)
134405c1e4bSWludzik, Jozef        result = 0
135405c1e4bSWludzik, Jozef        if days is not None:
136405c1e4bSWludzik, Jozef            result += int(days[:-1]) * 60 * 60 * 24
137405c1e4bSWludzik, Jozef        if hours is not None:
138405c1e4bSWludzik, Jozef            result += int(hours[:-1]) * 60 * 60
139405c1e4bSWludzik, Jozef        if minutes is not None:
140405c1e4bSWludzik, Jozef            result += int(minutes[:-1]) * 60
141405c1e4bSWludzik, Jozef        if seconds is not None:
142405c1e4bSWludzik, Jozef            result += float(seconds[:-1])
143405c1e4bSWludzik, Jozef        return result
144