blob: 459d0457bd1591d0937b087f38ab312d9dd5ad36 [file] [log] [blame]
Nan Zhou313c1b72022-03-25 11:47:55 -07001#!/usr/bin/env python3
Ed Tanous683f7272018-07-26 12:47:19 -07002import os
Ed Tanous683f7272018-07-26 12:47:19 -07003import shutil
Ed Tanous118b1c72018-09-13 13:45:51 -07004import xml.etree.ElementTree as ET
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -06005import zipfile
6from collections import OrderedDict, defaultdict
7from io import BytesIO
8
9import requests
10from packaging.version import parse
Ed Tanous118b1c72018-09-13 13:45:51 -070011
Asmitha Karunanithi009c6452022-09-22 01:07:59 -050012VERSION = "DSP8010_2022.2"
Ed Tanouscb103132019-10-08 11:34:22 -070013
Ed Tanous27747912022-09-23 12:50:08 -070014WARNING = """/****************************************************************
Ed Tanous81d523a2022-05-25 12:00:51 -070015 * READ THIS WARNING FIRST
16 * This is an auto-generated header which contains definitions
17 * for Redfish DMTF defined schemas.
18 * DO NOT modify this registry outside of running the
19 * update_schemas.py script. The definitions contained within
20 * this file are owned by DMTF. Any modifications to these files
21 * should be first pushed to the relevant registry in the DMTF
22 * github organization.
Ed Tanous27747912022-09-23 12:50:08 -070023 ***************************************************************/"""
Ed Tanous81d523a2022-05-25 12:00:51 -070024
Gunnar Mills349a2ac2021-01-20 22:29:16 -060025# To use a new schema, add to list and rerun tool
26include_list = [
Ed Tanous27747912022-09-23 12:50:08 -070027 "AccountService",
28 "ActionInfo",
29 "Assembly",
30 "AttributeRegistry",
31 "Bios",
32 "Cable",
33 "CableCollection",
34 "Certificate",
35 "CertificateCollection",
36 "CertificateLocations",
37 "CertificateService",
38 "Chassis",
39 "ChassisCollection",
40 "ComputerSystem",
41 "ComputerSystemCollection",
42 "Drive",
43 "DriveCollection",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060044 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070045 "EthernetInterface",
46 "EthernetInterfaceCollection",
47 "Event",
48 "EventDestination",
49 "EventDestinationCollection",
50 "EventService",
George Liu1a7b3772022-09-29 09:29:18 +080051 "Fan",
52 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070053 "IPAddresses",
54 "JsonSchemaFile",
55 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
56 "LogEntry",
57 "LogEntryCollection",
58 "LogService",
59 "LogServiceCollection",
60 "Manager",
61 "ManagerAccount",
62 "ManagerAccountCollection",
63 "ManagerCollection",
64 "ManagerDiagnosticData",
65 "ManagerNetworkProtocol",
66 "Memory",
67 "MemoryCollection",
68 "Message",
69 "MessageRegistry",
70 "MessageRegistryCollection",
71 "MessageRegistryFile",
72 "MessageRegistryFileCollection",
73 "MetricDefinition",
74 "MetricDefinitionCollection",
75 "MetricReport",
76 "MetricReportCollection",
77 "MetricReportDefinition",
78 "MetricReportDefinitionCollection",
79 "OperatingConfig",
80 "OperatingConfigCollection",
81 "PCIeDevice",
82 "PCIeDeviceCollection",
83 "PCIeFunction",
84 "PCIeFunctionCollection",
85 "PhysicalContext",
86 "PCIeSlots",
87 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080088 "PowerSubsystem",
89 "PowerSupply",
90 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070091 "Privileges", # Used in Role
92 "Processor",
93 "ProcessorCollection",
94 "RedfishError",
95 "RedfishExtensions",
96 "Redundancy",
97 "Resource",
98 "Role",
99 "RoleCollection",
100 "Sensor",
101 "SensorCollection",
102 "ServiceRoot",
103 "Session",
104 "SessionCollection",
105 "SessionService",
106 "Settings",
107 "SoftwareInventory",
108 "SoftwareInventoryCollection",
109 "Storage",
110 "StorageCollection",
111 "StorageController",
112 "StorageControllerCollection",
113 "Task",
114 "TaskCollection",
115 "TaskService",
116 "TelemetryService",
117 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800118 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700119 "ThermalSubsystem",
120 "Triggers",
121 "TriggersCollection",
122 "UpdateService",
123 "VLanNetworkInterfaceCollection",
124 "VLanNetworkInterface",
125 "VirtualMedia",
126 "VirtualMediaCollection",
127 "odata",
128 "odata-v4",
129 "redfish-error",
130 "redfish-payload-annotations",
131 "redfish-schema",
132 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600133]
134
Ed Tanous683f7272018-07-26 12:47:19 -0700135SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
136
Ed Tanous27747912022-09-23 12:50:08 -0700137proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700138
Ed Tanouscb103132019-10-08 11:34:22 -0700139r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700140 "https://www.dmtf.org/sites/default/files/standards/documents/"
141 + VERSION
142 + ".zip",
143 proxies=proxies,
144)
Ed Tanous683f7272018-07-26 12:47:19 -0700145
146r.raise_for_status()
147
Ed Tanous81d523a2022-05-25 12:00:51 -0700148
Ed Tanous27747912022-09-23 12:50:08 -0700149static_path = os.path.realpath(
150 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
151)
Ed Tanous683f7272018-07-26 12:47:19 -0700152
Ed Tanous81d523a2022-05-25 12:00:51 -0700153
Ed Tanous27747912022-09-23 12:50:08 -0700154cpp_path = os.path.realpath(
155 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
156)
Ed Tanous81d523a2022-05-25 12:00:51 -0700157
158
Ed Tanous683f7272018-07-26 12:47:19 -0700159schema_path = os.path.join(static_path, "schema")
160json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700161metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700162
163zipBytesIO = BytesIO(r.content)
164zip_ref = zipfile.ZipFile(zipBytesIO)
165
Ed Tanous8b564552022-09-23 12:03:18 -0700166
167def version_sort_key(key):
168 """
169 Method that computes a sort key that zero pads all numbers, such that
170 version sorting like
171 0_2_0
172 0_10_0
173 sorts in the way humans expect.
174 it also does case insensitive comparisons.
175 """
176 key = str.casefold(key)
177
178 # Decription of this class calls it "Version numbering for anarchists and
179 # software realists.". That seems like exactly what we need here.
180
181 if not any(char.isdigit() for char in key):
182 split_tup = os.path.splitext(key)
183 key = split_tup[0] + ".v0_0_0" + split_tup[1]
184
185 # special case some files that don't seem to follow the naming convention,
186 # and cause sort problems. These need brought up with DMTF TODO(Ed)
187 if key == "odata.4.0.0.json":
188 key = "odata.v4_0_0.json"
189 if key == "redfish-schema.1.0.0.json":
190 key = "redfish-schema.v1_0_0.json"
191
192 return parse(key)
193
194
Ed Tanous683f7272018-07-26 12:47:19 -0700195# Remove the old files
Ed Tanous8b564552022-09-23 12:03:18 -0700196
Ed Tanous27747912022-09-23 12:50:08 -0700197skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700198if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700199 files = [
200 os.path.join(schema_path, f)
201 for f in os.listdir(schema_path)
202 if not f.startswith(skip_prefixes)
203 ]
James Feistaee8d842018-09-10 16:07:40 -0700204 for f in files:
205 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700206if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700207 files = [
208 os.path.join(json_schema_path, f)
209 for f in os.listdir(json_schema_path)
210 if not f.startswith(skip_prefixes)
211 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700212 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700213 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700214 os.remove(f)
215 else:
216 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700217try:
218 os.remove(metadata_index_path)
219except FileNotFoundError:
220 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700221
Ed Tanous118b1c72018-09-13 13:45:51 -0700222if not os.path.exists(schema_path):
223 os.makedirs(schema_path)
224if not os.path.exists(json_schema_path):
225 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700226
Ed Tanous8b564552022-09-23 12:03:18 -0700227csdl_filenames = []
228json_schema_files = defaultdict(list)
229
230for zip_filepath in zip_ref.namelist():
231 if zip_filepath.startswith("csdl/") and (zip_filepath != "csdl/"):
232 csdl_filenames.append(os.path.basename(zip_filepath))
233 elif zip_filepath.startswith("json-schema/"):
234 filename = os.path.basename(zip_filepath)
235 filenamesplit = filename.split(".")
236 # exclude schemas again to save flash space
237 if filenamesplit[0] not in include_list:
238 continue
239 json_schema_files[filenamesplit[0]].append(filename)
240 elif zip_filepath.startswith("openapi/"):
241 pass
242 elif zip_filepath.startswith("dictionaries/"):
243 pass
244
245# sort the json files by version
246for key, value in json_schema_files.items():
247 value.sort(key=version_sort_key, reverse=True)
248
249# Create a dictionary ordered by schema name
250json_schema_files = OrderedDict(
251 sorted(json_schema_files.items(), key=lambda x: version_sort_key(x[0]))
252)
253
254csdl_filenames.sort(key=version_sort_key)
Ed Tanous27747912022-09-23 12:50:08 -0700255with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700256 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700257 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700258 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700259 '"http://docs.oasis-open.org/odata/ns/edmx"'
260 ' Version="4.0">\n'
261 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700262
Ed Tanous8b564552022-09-23 12:03:18 -0700263 for filename in csdl_filenames:
264 # filename looks like Zone_v1.xml
265 filenamesplit = filename.split("_")
266 if filenamesplit[0] not in include_list:
267 print("excluding schema: " + filename)
268 continue
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600269
Ed Tanous8b564552022-09-23 12:03:18 -0700270 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous8b564552022-09-23 12:03:18 -0700271 metadata_index.write(
272 ' <edmx:Reference Uri="/redfish/v1/schema/'
273 + filename
274 + '">\n'
275 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700276
Ed Tanous8b564552022-09-23 12:03:18 -0700277 content = zip_ref.read(os.path.join("csdl", filename))
278 content = content.replace(b"\r\n", b"\n")
279 xml_root = ET.fromstring(content)
280 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
281 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
282 for edmx_child in xml_root:
283 if edmx_child.tag == edmx + "DataServices":
284 for data_child in edmx_child:
285 if data_child.tag == edm + "Schema":
286 namespace = data_child.attrib["Namespace"]
287 if namespace.startswith("RedfishExtensions"):
288 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600289 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700290 + namespace
291 + '" Alias="Redfish"/>\n'
292 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700293
Ed Tanous8b564552022-09-23 12:03:18 -0700294 else:
295 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600296 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700297 + namespace
298 + '"/>\n'
299 )
300 schema_out.write(content)
301 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700302
Ed Tanous27747912022-09-23 12:50:08 -0700303 metadata_index.write(
304 " <edmx:DataServices>\n"
305 " <Schema "
306 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
307 'Namespace="Service">\n'
308 ' <EntityContainer Name="Service" '
309 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
310 " </Schema>\n"
311 " </edmx:DataServices>\n"
312 )
Ed Tanouscb103132019-10-08 11:34:22 -0700313 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500314 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700315 # don't update schemas very often, we just manually fix it. Need a
316 # permanent fix to the script.
317 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700318 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
319 )
320 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600321 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600322
323 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700324 ' <edmx:Reference Uri="'
325 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
326 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700327 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700328 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
329 )
Gunnar Mills20778992020-02-06 16:36:47 -0600330 metadata_index.write(" </edmx:Reference>\n")
331
332 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700333 ' <edmx:Reference Uri="'
334 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
335 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700336 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700337 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
338 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700339 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700340 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
341 )
Gunnar Mills20778992020-02-06 16:36:47 -0600342 metadata_index.write(" </edmx:Reference>\n")
343
344 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700345 ' <edmx:Reference Uri="'
346 '/redfish/v1/schema/OemAccountService_v1.xml">\n'
347 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700348 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700349 ' <edmx:Include Namespace="OemAccountService"/>\n'
350 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700351 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700352 ' <edmx:Include Namespace="OemAccountService.v1_0_0"/>\n'
353 )
Gunnar Mills20778992020-02-06 16:36:47 -0600354 metadata_index.write(" </edmx:Reference>\n")
355
Ravi Tejae7d68c32020-03-15 13:30:41 -0500356 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700357 ' <edmx:Reference Uri="/redfish/v1/schema/OemSession_v1.xml">\n'
358 )
359 metadata_index.write(' <edmx:Include Namespace="OemSession"/>\n')
Ed Tanousf395daa2021-08-02 08:56:24 -0700360 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700361 ' <edmx:Include Namespace="OemSession.v1_0_0"/>\n'
362 )
Sunitha Harish9dc50742020-05-11 00:10:20 -0500363 metadata_index.write(" </edmx:Reference>\n")
364
Ed Tanous118b1c72018-09-13 13:45:51 -0700365 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700366
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600367
Ed Tanous8b564552022-09-23 12:03:18 -0700368for schema, version in json_schema_files.items():
369 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700370 schemadir = os.path.join(json_schema_path, schema)
371 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700372
Ed Tanous27747912022-09-23 12:50:08 -0700373 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
374 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700375
Ed Tanous27747912022-09-23 12:50:08 -0700376with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700377 hpp_file.write(
378 "#pragma once\n"
379 "{WARNING}\n"
380 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700381 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700382 "\n"
383 "namespace redfish\n"
384 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700385 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700386 )
Ed Tanous8b564552022-09-23 12:03:18 -0700387 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700388 hpp_file.write(' "{}",\n'.format(schema_file))
389
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600390 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700391
392zip_ref.close()