blob: 626c0d10a7f76659194c68dcbeecdc7325ed7fac [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",
89 "Privileges", # Used in Role
90 "Processor",
91 "ProcessorCollection",
92 "RedfishError",
93 "RedfishExtensions",
94 "Redundancy",
95 "Resource",
96 "Role",
97 "RoleCollection",
98 "Sensor",
99 "SensorCollection",
100 "ServiceRoot",
101 "Session",
102 "SessionCollection",
103 "SessionService",
104 "Settings",
105 "SoftwareInventory",
106 "SoftwareInventoryCollection",
107 "Storage",
108 "StorageCollection",
109 "StorageController",
110 "StorageControllerCollection",
111 "Task",
112 "TaskCollection",
113 "TaskService",
114 "TelemetryService",
115 "Thermal",
116 "ThermalSubsystem",
117 "Triggers",
118 "TriggersCollection",
119 "UpdateService",
120 "VLanNetworkInterfaceCollection",
121 "VLanNetworkInterface",
122 "VirtualMedia",
123 "VirtualMediaCollection",
124 "odata",
125 "odata-v4",
126 "redfish-error",
127 "redfish-payload-annotations",
128 "redfish-schema",
129 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600130]
131
Ed Tanous683f7272018-07-26 12:47:19 -0700132SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
133
Ed Tanous27747912022-09-23 12:50:08 -0700134proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700135
Ed Tanouscb103132019-10-08 11:34:22 -0700136r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700137 "https://www.dmtf.org/sites/default/files/standards/documents/"
138 + VERSION
139 + ".zip",
140 proxies=proxies,
141)
Ed Tanous683f7272018-07-26 12:47:19 -0700142
143r.raise_for_status()
144
Ed Tanous81d523a2022-05-25 12:00:51 -0700145
Ed Tanous27747912022-09-23 12:50:08 -0700146static_path = os.path.realpath(
147 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
148)
Ed Tanous683f7272018-07-26 12:47:19 -0700149
Ed Tanous81d523a2022-05-25 12:00:51 -0700150
Ed Tanous27747912022-09-23 12:50:08 -0700151cpp_path = os.path.realpath(
152 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
153)
Ed Tanous81d523a2022-05-25 12:00:51 -0700154
155
Ed Tanous683f7272018-07-26 12:47:19 -0700156schema_path = os.path.join(static_path, "schema")
157json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700158metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700159
160zipBytesIO = BytesIO(r.content)
161zip_ref = zipfile.ZipFile(zipBytesIO)
162
Ed Tanous8b564552022-09-23 12:03:18 -0700163
164def version_sort_key(key):
165 """
166 Method that computes a sort key that zero pads all numbers, such that
167 version sorting like
168 0_2_0
169 0_10_0
170 sorts in the way humans expect.
171 it also does case insensitive comparisons.
172 """
173 key = str.casefold(key)
174
175 # Decription of this class calls it "Version numbering for anarchists and
176 # software realists.". That seems like exactly what we need here.
177
178 if not any(char.isdigit() for char in key):
179 split_tup = os.path.splitext(key)
180 key = split_tup[0] + ".v0_0_0" + split_tup[1]
181
182 # special case some files that don't seem to follow the naming convention,
183 # and cause sort problems. These need brought up with DMTF TODO(Ed)
184 if key == "odata.4.0.0.json":
185 key = "odata.v4_0_0.json"
186 if key == "redfish-schema.1.0.0.json":
187 key = "redfish-schema.v1_0_0.json"
188
189 return parse(key)
190
191
Ed Tanous683f7272018-07-26 12:47:19 -0700192# Remove the old files
Ed Tanous8b564552022-09-23 12:03:18 -0700193
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
227for zip_filepath in zip_ref.namelist():
228 if zip_filepath.startswith("csdl/") and (zip_filepath != "csdl/"):
229 csdl_filenames.append(os.path.basename(zip_filepath))
230 elif zip_filepath.startswith("json-schema/"):
231 filename = os.path.basename(zip_filepath)
232 filenamesplit = filename.split(".")
233 # exclude schemas again to save flash space
234 if filenamesplit[0] not in include_list:
235 continue
236 json_schema_files[filenamesplit[0]].append(filename)
237 elif zip_filepath.startswith("openapi/"):
238 pass
239 elif zip_filepath.startswith("dictionaries/"):
240 pass
241
242# sort the json files by version
243for key, value in json_schema_files.items():
244 value.sort(key=version_sort_key, reverse=True)
245
246# Create a dictionary ordered by schema name
247json_schema_files = OrderedDict(
248 sorted(json_schema_files.items(), key=lambda x: version_sort_key(x[0]))
249)
250
251csdl_filenames.sort(key=version_sort_key)
Ed Tanous27747912022-09-23 12:50:08 -0700252with open(metadata_index_path, "w") as metadata_index:
Ed Tanous118b1c72018-09-13 13:45:51 -0700253
Ed Tanous27747912022-09-23 12:50:08 -0700254 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700255 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700256 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700257 '"http://docs.oasis-open.org/odata/ns/edmx"'
258 ' Version="4.0">\n'
259 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700260
Ed Tanous8b564552022-09-23 12:03:18 -0700261 for filename in csdl_filenames:
262 # filename looks like Zone_v1.xml
263 filenamesplit = filename.split("_")
264 if filenamesplit[0] not in include_list:
265 print("excluding schema: " + filename)
266 continue
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600267
Ed Tanous8b564552022-09-23 12:03:18 -0700268 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600269
Ed Tanous8b564552022-09-23 12:03:18 -0700270 metadata_index.write(
271 ' <edmx:Reference Uri="/redfish/v1/schema/'
272 + filename
273 + '">\n'
274 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700275
Ed Tanous8b564552022-09-23 12:03:18 -0700276 content = zip_ref.read(os.path.join("csdl", filename))
277 content = content.replace(b"\r\n", b"\n")
278 xml_root = ET.fromstring(content)
279 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
280 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
281 for edmx_child in xml_root:
282 if edmx_child.tag == edmx + "DataServices":
283 for data_child in edmx_child:
284 if data_child.tag == edm + "Schema":
285 namespace = data_child.attrib["Namespace"]
286 if namespace.startswith("RedfishExtensions"):
287 metadata_index.write(
288 " "
289 '<edmx:Include Namespace="'
290 + 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(
296 " "
297 '<edmx:Include Namespace="'
298 + namespace
299 + '"/>\n'
300 )
301 schema_out.write(content)
302 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700303
Ed Tanous27747912022-09-23 12:50:08 -0700304 metadata_index.write(
305 " <edmx:DataServices>\n"
306 " <Schema "
307 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
308 'Namespace="Service">\n'
309 ' <EntityContainer Name="Service" '
310 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
311 " </Schema>\n"
312 " </edmx:DataServices>\n"
313 )
Ed Tanouscb103132019-10-08 11:34:22 -0700314 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500315 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700316 # don't update schemas very often, we just manually fix it. Need a
317 # permanent fix to the script.
318 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700319 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
320 )
321 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600322 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600323
324 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700325 ' <edmx:Reference Uri="'
326 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
327 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700328 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700329 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
330 )
Gunnar Mills20778992020-02-06 16:36:47 -0600331 metadata_index.write(" </edmx:Reference>\n")
332
333 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700334 ' <edmx:Reference Uri="'
335 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
336 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700337 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700338 ' <edmx:Include Namespace="OemVirtualMedia"/>\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.v1_0_0"/>\n'
342 )
Gunnar Mills20778992020-02-06 16:36:47 -0600343 metadata_index.write(" </edmx:Reference>\n")
344
345 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700346 ' <edmx:Reference Uri="'
347 '/redfish/v1/schema/OemAccountService_v1.xml">\n'
348 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700349 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700350 ' <edmx:Include Namespace="OemAccountService"/>\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.v1_0_0"/>\n'
354 )
Gunnar Mills20778992020-02-06 16:36:47 -0600355 metadata_index.write(" </edmx:Reference>\n")
356
Ravi Tejae7d68c32020-03-15 13:30:41 -0500357 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700358 ' <edmx:Reference Uri="/redfish/v1/schema/OemSession_v1.xml">\n'
359 )
360 metadata_index.write(' <edmx:Include Namespace="OemSession"/>\n')
Ed Tanousf395daa2021-08-02 08:56:24 -0700361 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700362 ' <edmx:Include Namespace="OemSession.v1_0_0"/>\n'
363 )
Sunitha Harish9dc50742020-05-11 00:10:20 -0500364 metadata_index.write(" </edmx:Reference>\n")
365
Ed Tanous118b1c72018-09-13 13:45:51 -0700366 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700367
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600368
Ed Tanous8b564552022-09-23 12:03:18 -0700369for schema, version in json_schema_files.items():
370 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700371 schemadir = os.path.join(json_schema_path, schema)
372 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700373
Ed Tanous27747912022-09-23 12:50:08 -0700374 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
375 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700376
Ed Tanous27747912022-09-23 12:50:08 -0700377with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700378 hpp_file.write(
379 "#pragma once\n"
380 "{WARNING}\n"
381 "// clang-format off\n"
382 "\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
390 hpp_file.write(" };\n" "}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700391
392zip_ref.close()