blob: 8021cbb5d521791bd51fbfa55f554e4a6583c653 [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
Ed Tanous0ec8b832022-03-14 14:56:47 -07009import generate_schema_enums
Patrick Williamsfd06b302022-12-12 10:39:42 -060010import requests
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
Ed Tanous204c3762022-12-12 09:50:09 -0800167class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600168 """
Ed Tanous204c3762022-12-12 09:50:09 -0800169 A Python class for sorting Redfish schema versions. Allows sorting Redfish
170 versions in the way humans expect, by comparing version strings as lists
171 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
172 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600173 """
Ed Tanous8b564552022-09-23 12:03:18 -0700174
Ed Tanous204c3762022-12-12 09:50:09 -0800175 def __init__(self, key):
176 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700177
Ed Tanous204c3762022-12-12 09:50:09 -0800178 split_tup = key.split(".")
179 self.version_pieces = [split_tup[0]]
180 if len(split_tup) < 2:
181 return
182 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700183
Ed Tanous204c3762022-12-12 09:50:09 -0800184 if version.startswith("v"):
185 version = version[1:]
186 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600187 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700188
Ed Tanous204c3762022-12-12 09:50:09 -0800189 def __lt__(self, other):
190 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700191
192
Ed Tanous683f7272018-07-26 12:47:19 -0700193# Remove the old files
Ed Tanous27747912022-09-23 12:50:08 -0700194skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700195if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700196 files = [
197 os.path.join(schema_path, f)
198 for f in os.listdir(schema_path)
199 if not f.startswith(skip_prefixes)
200 ]
James Feistaee8d842018-09-10 16:07:40 -0700201 for f in files:
202 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700203if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700204 files = [
205 os.path.join(json_schema_path, f)
206 for f in os.listdir(json_schema_path)
207 if not f.startswith(skip_prefixes)
208 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700209 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700210 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700211 os.remove(f)
212 else:
213 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700214try:
215 os.remove(metadata_index_path)
216except FileNotFoundError:
217 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700218
Ed Tanous118b1c72018-09-13 13:45:51 -0700219if not os.path.exists(schema_path):
220 os.makedirs(schema_path)
221if not os.path.exists(json_schema_path):
222 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700223
Ed Tanous8b564552022-09-23 12:03:18 -0700224csdl_filenames = []
225json_schema_files = defaultdict(list)
226
Ed Tanous204c3762022-12-12 09:50:09 -0800227for zip_file in zip_ref.infolist():
228 if zip_file.is_dir():
229 continue
230 if zip_file.filename.startswith("csdl/"):
231 csdl_filenames.append(os.path.basename(zip_file.filename))
232 elif zip_file.filename.startswith("json-schema/"):
233 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700234 filenamesplit = filename.split(".")
235 # exclude schemas again to save flash space
236 if filenamesplit[0] not in include_list:
237 continue
238 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800239 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700240 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800241 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700242 pass
243
244# sort the json files by version
245for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800246 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700247
248# Create a dictionary ordered by schema name
249json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800250 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700251)
252
Ed Tanous204c3762022-12-12 09:50:09 -0800253csdl_filenames.sort(key=SchemaVersion)
Ed Tanous27747912022-09-23 12:50:08 -0700254with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700255 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700256 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700257 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700258 '"http://docs.oasis-open.org/odata/ns/edmx"'
259 ' Version="4.0">\n'
260 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700261
Ed Tanous8b564552022-09-23 12:03:18 -0700262 for filename in csdl_filenames:
263 # filename looks like Zone_v1.xml
Ed Tanous8b564552022-09-23 12:03:18 -0700264 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800265 content = zip_ref.read(os.path.join("csdl", filename))
266 content = content.replace(b"\r\n", b"\n")
267
268 schema_out.write(content)
269
270 filenamesplit = filename.split("_")
271 if filenamesplit[0] not in include_list:
272 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700273 metadata_index.write(
274 ' <edmx:Reference Uri="/redfish/v1/schema/'
275 + filename
276 + '">\n'
277 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700278
Ed Tanous8b564552022-09-23 12:03:18 -0700279 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 )
Ed Tanous8b564552022-09-23 12:03:18 -0700300 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700301
Ed Tanous27747912022-09-23 12:50:08 -0700302 metadata_index.write(
303 " <edmx:DataServices>\n"
304 " <Schema "
305 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
306 'Namespace="Service">\n'
307 ' <EntityContainer Name="Service" '
308 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
309 " </Schema>\n"
310 " </edmx:DataServices>\n"
311 )
Ed Tanouscb103132019-10-08 11:34:22 -0700312 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500313 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700314 # don't update schemas very often, we just manually fix it. Need a
315 # permanent fix to the script.
316 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700317 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
318 )
319 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600320 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600321
322 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700323 ' <edmx:Reference Uri="'
324 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
325 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700326 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700327 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
328 )
Gunnar Mills20778992020-02-06 16:36:47 -0600329 metadata_index.write(" </edmx:Reference>\n")
330
331 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700332 ' <edmx:Reference Uri="'
333 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
334 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700335 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700336 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
337 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700338 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700339 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
340 )
Gunnar Mills20778992020-02-06 16:36:47 -0600341 metadata_index.write(" </edmx:Reference>\n")
342
343 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700344 ' <edmx:Reference Uri="'
345 '/redfish/v1/schema/OemAccountService_v1.xml">\n'
346 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700347 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700348 ' <edmx:Include Namespace="OemAccountService"/>\n'
349 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700350 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700351 ' <edmx:Include Namespace="OemAccountService.v1_0_0"/>\n'
352 )
Gunnar Mills20778992020-02-06 16:36:47 -0600353 metadata_index.write(" </edmx:Reference>\n")
354
Ravi Tejae7d68c32020-03-15 13:30:41 -0500355 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700356 ' <edmx:Reference Uri="/redfish/v1/schema/OemSession_v1.xml">\n'
357 )
358 metadata_index.write(' <edmx:Include Namespace="OemSession"/>\n')
Ed Tanousf395daa2021-08-02 08:56:24 -0700359 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700360 ' <edmx:Include Namespace="OemSession.v1_0_0"/>\n'
361 )
Sunitha Harish9dc50742020-05-11 00:10:20 -0500362 metadata_index.write(" </edmx:Reference>\n")
363
Ed Tanous118b1c72018-09-13 13:45:51 -0700364 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700365
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600366
Ed Tanous8b564552022-09-23 12:03:18 -0700367for schema, version in json_schema_files.items():
368 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700369 schemadir = os.path.join(json_schema_path, schema)
370 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700371
Ed Tanous27747912022-09-23 12:50:08 -0700372 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
373 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700374
Ed Tanous27747912022-09-23 12:50:08 -0700375with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700376 hpp_file.write(
377 "#pragma once\n"
378 "{WARNING}\n"
379 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700380 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700381 "\n"
382 "namespace redfish\n"
383 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700384 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700385 )
Ed Tanous8b564552022-09-23 12:03:18 -0700386 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700387 hpp_file.write(' "{}",\n'.format(schema_file))
388
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600389 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700390
391zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700392
393generate_schema_enums.main()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800394
395# Now delete the xml schema files we aren't supporting
396if os.path.exists(schema_path):
397 files = [
398 os.path.join(schema_path, f)
399 for f in os.listdir(schema_path)
400 if not f.startswith(skip_prefixes)
401 ]
402 for filename in files:
403 # filename will include the absolute path
404 filenamesplit = filename.split("/")
405 name = filenamesplit.pop()
406 namesplit = name.split("_")
407 if namesplit[0] not in include_list:
408 print("excluding schema: " + filename)
409 os.remove(filename)