| import enum |
| import math |
| import re |
| |
| import requests |
| |
| |
| class RedfishHttpStatus(enum.IntEnum): |
| ok = 200 |
| created = 201 |
| no_content = 204 |
| bad_request = 400 |
| not_found = 404 |
| internal_server_error = 500 |
| |
| |
| class RedfishRequest: |
| telemetry_service_path = "/redfish/v1/TelemetryService" |
| metric_definition_path = f"{telemetry_service_path}/MetricDefinitions" |
| metric_report_definition_path = ( |
| f"{telemetry_service_path}/MetricReportDefinitions" |
| ) |
| metric_report_path = f"{telemetry_service_path}/MetricReports" |
| |
| def __init__(self, host_addr, username, password): |
| self.host_addr = host_addr |
| self.username = username |
| self.password = password |
| |
| def get(self, path, code=RedfishHttpStatus.ok): |
| u = self.host_addr + path |
| r = requests.get(u, auth=(self.username, self.password), verify=False) |
| assert ( |
| r.status_code == code |
| ), f"{r.status_code} == {code} on path {u}\n{r.text}" |
| print(r.text) |
| return r.json() |
| |
| def post(self, path, body, code=RedfishHttpStatus.created): |
| u = self.host_addr + path |
| r = requests.post( |
| u, auth=(self.username, self.password), verify=False, json=body |
| ) |
| assert ( |
| r.status_code == code |
| ), f"{r.status_code} == {code} on path {u}\n{r.text}" |
| print(r.text) |
| return r.json() |
| |
| def delete(self, path, code=RedfishHttpStatus.no_content): |
| u = self.host_addr + path |
| r = requests.delete( |
| u, auth=(self.username, self.password), verify=False |
| ) |
| assert ( |
| r.status_code == code |
| ), f"{r.status_code} == {code} on path {u}\n{r.text}" |
| |
| |
| class TelemetryService: |
| def __init__(self, redfish, metric_limit): |
| r = redfish.get(redfish.telemetry_service_path) |
| self.min_interval = Duration.to_seconds(r["MinCollectionInterval"]) |
| self.max_reports = r["MaxReports"] |
| self.metrics = [] |
| r = redfish.get(redfish.metric_definition_path) |
| for m in r["Members"]: |
| path = m["@odata.id"] |
| metricDef = redfish.get(path) |
| self.metrics += [x for x in metricDef["MetricProperties"]] |
| self.metrics = self.metrics[:metric_limit] |
| |
| |
| class ReportDef: |
| def __init__(self, redfish): |
| self.redfish = redfish |
| |
| def get_collection(self): |
| r = self.redfish.get(self.redfish.metric_report_definition_path) |
| return [x["@odata.id"] for x in r["Members"]] |
| |
| def add_report( |
| self, |
| id, |
| metrics=None, |
| type="OnRequest", |
| actions=None, |
| interval=None, |
| code=RedfishHttpStatus.created, |
| ): |
| body = { |
| "Id": id, |
| "Metrics": [], |
| "MetricReportDefinitionType": type, |
| "ReportActions": ["RedfishEvent", "LogToMetricReportsCollection"], |
| } |
| if metrics is not None: |
| body["Metrics"] = metrics |
| if actions is not None: |
| body["ReportActions"] = actions |
| if interval is not None: |
| body["Schedule"] = {"RecurrenceInterval": interval} |
| return self.redfish.post( |
| self.redfish.metric_report_definition_path, body, code |
| ) |
| |
| def delete_report(self, path): |
| self.redfish.delete(f"{path}") |
| |
| |
| class Duration: |
| def __init__(self): |
| pass |
| |
| def to_iso8061(time): |
| assert time >= 0, "Invalid argument, time is negative" |
| days = int(time / (24 * 60 * 60)) |
| time = math.fmod(time, (24 * 60 * 60)) |
| hours = int(time / (60 * 60)) |
| time = math.fmod(time, (60 * 60)) |
| minutes = int(time / 60) |
| time = round(math.fmod(time, 60), 3) |
| return f"P{str(days)}DT{str(hours)}H{str(minutes)}M{str(time)}S" |
| |
| def to_seconds(duration): |
| r = re.fullmatch( |
| r"-?P(\d+D)?(T(\d+H)?(\d+M)?(\d+(.\d+)?S)?)?", duration |
| ) |
| assert r, "Invalid argument, not match with regex" |
| days = r.group(1) |
| hours = r.group(3) |
| minutes = r.group(4) |
| seconds = r.group(5) |
| result = 0 |
| if days is not None: |
| result += int(days[:-1]) * 60 * 60 * 24 |
| if hours is not None: |
| result += int(hours[:-1]) * 60 * 60 |
| if minutes is not None: |
| result += int(minutes[:-1]) * 60 |
| if seconds is not None: |
| result += float(seconds[:-1]) |
| return result |