blob: 18c99b78ea29e86481803065ff37a26bfb0428ad [file] [log] [blame]
Nan Zhou313c1b72022-03-25 11:47:55 -07001#!/usr/bin/env python3
Ed Tanous683f7272018-07-26 12:47:19 -07002import requests
3import zipfile
4from io import BytesIO
Ed Tanous8b564552022-09-23 12:03:18 -07005from packaging.version import Version, parse
6
Ed Tanous683f7272018-07-26 12:47:19 -07007import os
Ed Tanous8b564552022-09-23 12:03:18 -07008from collections import OrderedDict, defaultdict
Ed Tanous683f7272018-07-26 12:47:19 -07009import shutil
10import json
11
Ed Tanous118b1c72018-09-13 13:45:51 -070012import xml.etree.ElementTree as ET
13
Asmitha Karunanithi009c6452022-09-22 01:07:59 -050014VERSION = "DSP8010_2022.2"
Ed Tanouscb103132019-10-08 11:34:22 -070015
Ed Tanous27747912022-09-23 12:50:08 -070016WARNING = """/****************************************************************
Ed Tanous81d523a2022-05-25 12:00:51 -070017 * READ THIS WARNING FIRST
18 * This is an auto-generated header which contains definitions
19 * for Redfish DMTF defined schemas.
20 * DO NOT modify this registry outside of running the
21 * update_schemas.py script. The definitions contained within
22 * this file are owned by DMTF. Any modifications to these files
23 * should be first pushed to the relevant registry in the DMTF
24 * github organization.
Ed Tanous27747912022-09-23 12:50:08 -070025 ***************************************************************/"""
Ed Tanous81d523a2022-05-25 12:00:51 -070026
Gunnar Mills349a2ac2021-01-20 22:29:16 -060027# To use a new schema, add to list and rerun tool
28include_list = [
Ed Tanous27747912022-09-23 12:50:08 -070029 "AccountService",
30 "ActionInfo",
31 "Assembly",
32 "AttributeRegistry",
33 "Bios",
34 "Cable",
35 "CableCollection",
36 "Certificate",
37 "CertificateCollection",
38 "CertificateLocations",
39 "CertificateService",
40 "Chassis",
41 "ChassisCollection",
42 "ComputerSystem",
43 "ComputerSystemCollection",
44 "Drive",
45 "DriveCollection",
46 "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",
119 "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 Tanous118b1c72018-09-13 13:45:51 -0700256
Ed Tanous27747912022-09-23 12:50:08 -0700257 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700258 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700259 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700260 '"http://docs.oasis-open.org/odata/ns/edmx"'
261 ' Version="4.0">\n'
262 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700263
Ed Tanous8b564552022-09-23 12:03:18 -0700264 for filename in csdl_filenames:
265 # filename looks like Zone_v1.xml
266 filenamesplit = filename.split("_")
267 if filenamesplit[0] not in include_list:
268 print("excluding schema: " + filename)
269 continue
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600270
Ed Tanous8b564552022-09-23 12:03:18 -0700271 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600272
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 content = zip_ref.read(os.path.join("csdl", filename))
280 content = content.replace(b"\r\n", b"\n")
281 xml_root = ET.fromstring(content)
282 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
283 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
284 for edmx_child in xml_root:
285 if edmx_child.tag == edmx + "DataServices":
286 for data_child in edmx_child:
287 if data_child.tag == edm + "Schema":
288 namespace = data_child.attrib["Namespace"]
289 if namespace.startswith("RedfishExtensions"):
290 metadata_index.write(
291 " "
292 '<edmx:Include Namespace="'
293 + namespace
294 + '" Alias="Redfish"/>\n'
295 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700296
Ed Tanous8b564552022-09-23 12:03:18 -0700297 else:
298 metadata_index.write(
299 " "
300 '<edmx:Include Namespace="'
301 + namespace
302 + '"/>\n'
303 )
304 schema_out.write(content)
305 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700306
Ed Tanous27747912022-09-23 12:50:08 -0700307 metadata_index.write(
308 " <edmx:DataServices>\n"
309 " <Schema "
310 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
311 'Namespace="Service">\n'
312 ' <EntityContainer Name="Service" '
313 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
314 " </Schema>\n"
315 " </edmx:DataServices>\n"
316 )
Ed Tanouscb103132019-10-08 11:34:22 -0700317 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500318 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700319 # don't update schemas very often, we just manually fix it. Need a
320 # permanent fix to the script.
321 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700322 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
323 )
324 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600325 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600326
327 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700328 ' <edmx:Reference Uri="'
329 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
330 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700331 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700332 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
333 )
Gunnar Mills20778992020-02-06 16:36:47 -0600334 metadata_index.write(" </edmx:Reference>\n")
335
336 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700337 ' <edmx:Reference Uri="'
338 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
339 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700340 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700341 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
342 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700343 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700344 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
345 )
Gunnar Mills20778992020-02-06 16:36:47 -0600346 metadata_index.write(" </edmx:Reference>\n")
347
348 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700349 ' <edmx:Reference Uri="'
350 '/redfish/v1/schema/OemAccountService_v1.xml">\n'
351 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700352 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700353 ' <edmx:Include Namespace="OemAccountService"/>\n'
354 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700355 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700356 ' <edmx:Include Namespace="OemAccountService.v1_0_0"/>\n'
357 )
Gunnar Mills20778992020-02-06 16:36:47 -0600358 metadata_index.write(" </edmx:Reference>\n")
359
Ravi Tejae7d68c32020-03-15 13:30:41 -0500360 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700361 ' <edmx:Reference Uri="/redfish/v1/schema/OemSession_v1.xml">\n'
362 )
363 metadata_index.write(' <edmx:Include Namespace="OemSession"/>\n')
Ed Tanousf395daa2021-08-02 08:56:24 -0700364 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700365 ' <edmx:Include Namespace="OemSession.v1_0_0"/>\n'
366 )
Sunitha Harish9dc50742020-05-11 00:10:20 -0500367 metadata_index.write(" </edmx:Reference>\n")
368
Ed Tanous118b1c72018-09-13 13:45:51 -0700369 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700370
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600371
Ed Tanous8b564552022-09-23 12:03:18 -0700372for schema, version in json_schema_files.items():
373 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700374 schemadir = os.path.join(json_schema_path, schema)
375 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700376
Ed Tanous27747912022-09-23 12:50:08 -0700377 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
378 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700379
Ed Tanous27747912022-09-23 12:50:08 -0700380with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700381 hpp_file.write(
382 "#pragma once\n"
383 "{WARNING}\n"
384 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700385 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700386 "\n"
387 "namespace redfish\n"
388 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700389 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700390 )
Ed Tanous8b564552022-09-23 12:03:18 -0700391 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700392 hpp_file.write(' "{}",\n'.format(schema_file))
393
394 hpp_file.write(" };\n" "}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700395
396zip_ref.close()