blob: ba7811336d98a7e5300b31aef18af37164bd41a1 [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
Carson Labrado9e031402022-07-08 20:56:52 +000011from generate_schema_collections import generate_top_collections
Ed Tanous118b1c72018-09-13 13:45:51 -070012
Asmitha Karunanithi009c6452022-09-22 01:07:59 -050013VERSION = "DSP8010_2022.2"
Ed Tanouscb103132019-10-08 11:34:22 -070014
Ed Tanous27747912022-09-23 12:50:08 -070015WARNING = """/****************************************************************
Ed Tanous81d523a2022-05-25 12:00:51 -070016 * READ THIS WARNING FIRST
17 * This is an auto-generated header which contains definitions
18 * for Redfish DMTF defined schemas.
19 * DO NOT modify this registry outside of running the
20 * update_schemas.py script. The definitions contained within
21 * this file are owned by DMTF. Any modifications to these files
22 * should be first pushed to the relevant registry in the DMTF
23 * github organization.
Ed Tanous27747912022-09-23 12:50:08 -070024 ***************************************************************/"""
Ed Tanous81d523a2022-05-25 12:00:51 -070025
Gunnar Mills349a2ac2021-01-20 22:29:16 -060026# To use a new schema, add to list and rerun tool
27include_list = [
Ed Tanous27747912022-09-23 12:50:08 -070028 "AccountService",
29 "ActionInfo",
30 "Assembly",
31 "AttributeRegistry",
32 "Bios",
33 "Cable",
34 "CableCollection",
35 "Certificate",
36 "CertificateCollection",
37 "CertificateLocations",
38 "CertificateService",
39 "Chassis",
40 "ChassisCollection",
41 "ComputerSystem",
42 "ComputerSystemCollection",
43 "Drive",
44 "DriveCollection",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060045 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070046 "EthernetInterface",
47 "EthernetInterfaceCollection",
48 "Event",
49 "EventDestination",
50 "EventDestinationCollection",
51 "EventService",
George Liu1a7b3772022-09-29 09:29:18 +080052 "Fan",
53 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070054 "IPAddresses",
55 "JsonSchemaFile",
56 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
57 "LogEntry",
58 "LogEntryCollection",
59 "LogService",
60 "LogServiceCollection",
61 "Manager",
62 "ManagerAccount",
63 "ManagerAccountCollection",
64 "ManagerCollection",
65 "ManagerDiagnosticData",
66 "ManagerNetworkProtocol",
67 "Memory",
68 "MemoryCollection",
69 "Message",
70 "MessageRegistry",
71 "MessageRegistryCollection",
72 "MessageRegistryFile",
73 "MessageRegistryFileCollection",
74 "MetricDefinition",
75 "MetricDefinitionCollection",
76 "MetricReport",
77 "MetricReportCollection",
78 "MetricReportDefinition",
79 "MetricReportDefinitionCollection",
80 "OperatingConfig",
81 "OperatingConfigCollection",
82 "PCIeDevice",
83 "PCIeDeviceCollection",
84 "PCIeFunction",
85 "PCIeFunctionCollection",
86 "PhysicalContext",
87 "PCIeSlots",
88 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080089 "PowerSubsystem",
90 "PowerSupply",
91 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070092 "Privileges", # Used in Role
93 "Processor",
94 "ProcessorCollection",
95 "RedfishError",
96 "RedfishExtensions",
97 "Redundancy",
98 "Resource",
99 "Role",
100 "RoleCollection",
101 "Sensor",
102 "SensorCollection",
103 "ServiceRoot",
104 "Session",
105 "SessionCollection",
106 "SessionService",
107 "Settings",
108 "SoftwareInventory",
109 "SoftwareInventoryCollection",
110 "Storage",
111 "StorageCollection",
112 "StorageController",
113 "StorageControllerCollection",
114 "Task",
115 "TaskCollection",
116 "TaskService",
117 "TelemetryService",
118 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800119 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700120 "ThermalSubsystem",
121 "Triggers",
122 "TriggersCollection",
123 "UpdateService",
124 "VLanNetworkInterfaceCollection",
125 "VLanNetworkInterface",
126 "VirtualMedia",
127 "VirtualMediaCollection",
128 "odata",
129 "odata-v4",
130 "redfish-error",
131 "redfish-payload-annotations",
132 "redfish-schema",
133 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600134]
135
Ed Tanous683f7272018-07-26 12:47:19 -0700136SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
137
Ed Tanous27747912022-09-23 12:50:08 -0700138proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700139
Ed Tanouscb103132019-10-08 11:34:22 -0700140r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700141 "https://www.dmtf.org/sites/default/files/standards/documents/"
142 + VERSION
143 + ".zip",
144 proxies=proxies,
145)
Ed Tanous683f7272018-07-26 12:47:19 -0700146
147r.raise_for_status()
148
Ed Tanous81d523a2022-05-25 12:00:51 -0700149
Ed Tanous27747912022-09-23 12:50:08 -0700150static_path = os.path.realpath(
151 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
152)
Ed Tanous683f7272018-07-26 12:47:19 -0700153
Ed Tanous81d523a2022-05-25 12:00:51 -0700154
Ed Tanous27747912022-09-23 12:50:08 -0700155cpp_path = os.path.realpath(
156 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
157)
Ed Tanous81d523a2022-05-25 12:00:51 -0700158
159
Ed Tanous683f7272018-07-26 12:47:19 -0700160schema_path = os.path.join(static_path, "schema")
161json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700162metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700163
164zipBytesIO = BytesIO(r.content)
165zip_ref = zipfile.ZipFile(zipBytesIO)
166
Ed Tanous8b564552022-09-23 12:03:18 -0700167
Ed Tanous204c3762022-12-12 09:50:09 -0800168class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600169 """
Ed Tanous204c3762022-12-12 09:50:09 -0800170 A Python class for sorting Redfish schema versions. Allows sorting Redfish
171 versions in the way humans expect, by comparing version strings as lists
172 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
173 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600174 """
Ed Tanous8b564552022-09-23 12:03:18 -0700175
Ed Tanous204c3762022-12-12 09:50:09 -0800176 def __init__(self, key):
177 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700178
Ed Tanous204c3762022-12-12 09:50:09 -0800179 split_tup = key.split(".")
180 self.version_pieces = [split_tup[0]]
181 if len(split_tup) < 2:
182 return
183 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700184
Ed Tanous204c3762022-12-12 09:50:09 -0800185 if version.startswith("v"):
186 version = version[1:]
187 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600188 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700189
Ed Tanous204c3762022-12-12 09:50:09 -0800190 def __lt__(self, other):
191 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700192
193
Ed Tanous683f7272018-07-26 12:47:19 -0700194# Remove the old files
Ed Tanous27747912022-09-23 12:50:08 -0700195skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700196if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700197 files = [
198 os.path.join(schema_path, f)
199 for f in os.listdir(schema_path)
200 if not f.startswith(skip_prefixes)
201 ]
James Feistaee8d842018-09-10 16:07:40 -0700202 for f in files:
203 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700204if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700205 files = [
206 os.path.join(json_schema_path, f)
207 for f in os.listdir(json_schema_path)
208 if not f.startswith(skip_prefixes)
209 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700210 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700211 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700212 os.remove(f)
213 else:
214 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700215try:
216 os.remove(metadata_index_path)
217except FileNotFoundError:
218 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700219
Ed Tanous118b1c72018-09-13 13:45:51 -0700220if not os.path.exists(schema_path):
221 os.makedirs(schema_path)
222if not os.path.exists(json_schema_path):
223 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700224
Ed Tanous8b564552022-09-23 12:03:18 -0700225csdl_filenames = []
226json_schema_files = defaultdict(list)
227
Ed Tanous204c3762022-12-12 09:50:09 -0800228for zip_file in zip_ref.infolist():
229 if zip_file.is_dir():
230 continue
231 if zip_file.filename.startswith("csdl/"):
232 csdl_filenames.append(os.path.basename(zip_file.filename))
233 elif zip_file.filename.startswith("json-schema/"):
234 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700235 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)
Ed Tanous204c3762022-12-12 09:50:09 -0800240 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700241 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800242 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700243 pass
244
245# sort the json files by version
246for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800247 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700248
249# Create a dictionary ordered by schema name
250json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800251 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700252)
253
Ed Tanous204c3762022-12-12 09:50:09 -0800254csdl_filenames.sort(key=SchemaVersion)
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
Ed Tanous8b564552022-09-23 12:03:18 -0700265 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800266 content = zip_ref.read(os.path.join("csdl", filename))
267 content = content.replace(b"\r\n", b"\n")
268
269 schema_out.write(content)
270
271 filenamesplit = filename.split("_")
272 if filenamesplit[0] not in include_list:
273 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700274 metadata_index.write(
275 ' <edmx:Reference Uri="/redfish/v1/schema/'
276 + filename
277 + '">\n'
278 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700279
Ed Tanous8b564552022-09-23 12:03:18 -0700280 xml_root = ET.fromstring(content)
281 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
282 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
283 for edmx_child in xml_root:
284 if edmx_child.tag == edmx + "DataServices":
285 for data_child in edmx_child:
286 if data_child.tag == edm + "Schema":
287 namespace = data_child.attrib["Namespace"]
288 if namespace.startswith("RedfishExtensions"):
289 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600290 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700291 + namespace
292 + '" Alias="Redfish"/>\n'
293 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700294
Ed Tanous8b564552022-09-23 12:03:18 -0700295 else:
296 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600297 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700298 + namespace
299 + '"/>\n'
300 )
Ed Tanous8b564552022-09-23 12:03:18 -0700301 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()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700393
394generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000395generate_top_collections()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800396
397# Now delete the xml schema files we aren't supporting
398if os.path.exists(schema_path):
399 files = [
400 os.path.join(schema_path, f)
401 for f in os.listdir(schema_path)
402 if not f.startswith(skip_prefixes)
403 ]
404 for filename in files:
405 # filename will include the absolute path
406 filenamesplit = filename.split("/")
407 name = filenamesplit.pop()
408 namesplit = name.split("_")
409 if namesplit[0] not in include_list:
410 print("excluding schema: " + filename)
411 os.remove(filename)