blob: cf79a19cef50a87c876122ce85fced46a61ade41 [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",
52 "IPAddresses",
53 "JsonSchemaFile",
54 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
55 "LogEntry",
56 "LogEntryCollection",
57 "LogService",
58 "LogServiceCollection",
59 "Manager",
60 "ManagerAccount",
61 "ManagerAccountCollection",
62 "ManagerCollection",
63 "ManagerDiagnosticData",
64 "ManagerNetworkProtocol",
65 "Memory",
66 "MemoryCollection",
67 "Message",
68 "MessageRegistry",
69 "MessageRegistryCollection",
70 "MessageRegistryFile",
71 "MessageRegistryFileCollection",
72 "MetricDefinition",
73 "MetricDefinitionCollection",
74 "MetricReport",
75 "MetricReportCollection",
76 "MetricReportDefinition",
77 "MetricReportDefinitionCollection",
78 "OperatingConfig",
79 "OperatingConfigCollection",
80 "PCIeDevice",
81 "PCIeDeviceCollection",
82 "PCIeFunction",
83 "PCIeFunctionCollection",
84 "PhysicalContext",
85 "PCIeSlots",
86 "Power",
87 "Privileges", # Used in Role
88 "Processor",
89 "ProcessorCollection",
90 "RedfishError",
91 "RedfishExtensions",
92 "Redundancy",
93 "Resource",
94 "Role",
95 "RoleCollection",
96 "Sensor",
97 "SensorCollection",
98 "ServiceRoot",
99 "Session",
100 "SessionCollection",
101 "SessionService",
102 "Settings",
103 "SoftwareInventory",
104 "SoftwareInventoryCollection",
105 "Storage",
106 "StorageCollection",
107 "StorageController",
108 "StorageControllerCollection",
109 "Task",
110 "TaskCollection",
111 "TaskService",
112 "TelemetryService",
113 "Thermal",
114 "ThermalSubsystem",
115 "Triggers",
116 "TriggersCollection",
117 "UpdateService",
118 "VLanNetworkInterfaceCollection",
119 "VLanNetworkInterface",
120 "VirtualMedia",
121 "VirtualMediaCollection",
122 "odata",
123 "odata-v4",
124 "redfish-error",
125 "redfish-payload-annotations",
126 "redfish-schema",
127 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600128]
129
Ed Tanous683f7272018-07-26 12:47:19 -0700130SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
131
Ed Tanous27747912022-09-23 12:50:08 -0700132proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700133
Ed Tanouscb103132019-10-08 11:34:22 -0700134r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700135 "https://www.dmtf.org/sites/default/files/standards/documents/"
136 + VERSION
137 + ".zip",
138 proxies=proxies,
139)
Ed Tanous683f7272018-07-26 12:47:19 -0700140
141r.raise_for_status()
142
Ed Tanous81d523a2022-05-25 12:00:51 -0700143
Ed Tanous27747912022-09-23 12:50:08 -0700144static_path = os.path.realpath(
145 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
146)
Ed Tanous683f7272018-07-26 12:47:19 -0700147
Ed Tanous81d523a2022-05-25 12:00:51 -0700148
Ed Tanous27747912022-09-23 12:50:08 -0700149cpp_path = os.path.realpath(
150 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
151)
Ed Tanous81d523a2022-05-25 12:00:51 -0700152
153
Ed Tanous683f7272018-07-26 12:47:19 -0700154schema_path = os.path.join(static_path, "schema")
155json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700156metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700157
158zipBytesIO = BytesIO(r.content)
159zip_ref = zipfile.ZipFile(zipBytesIO)
160
Ed Tanous8b564552022-09-23 12:03:18 -0700161
162def version_sort_key(key):
163 """
164 Method that computes a sort key that zero pads all numbers, such that
165 version sorting like
166 0_2_0
167 0_10_0
168 sorts in the way humans expect.
169 it also does case insensitive comparisons.
170 """
171 key = str.casefold(key)
172
173 # Decription of this class calls it "Version numbering for anarchists and
174 # software realists.". That seems like exactly what we need here.
175
176 if not any(char.isdigit() for char in key):
177 split_tup = os.path.splitext(key)
178 key = split_tup[0] + ".v0_0_0" + split_tup[1]
179
180 # special case some files that don't seem to follow the naming convention,
181 # and cause sort problems. These need brought up with DMTF TODO(Ed)
182 if key == "odata.4.0.0.json":
183 key = "odata.v4_0_0.json"
184 if key == "redfish-schema.1.0.0.json":
185 key = "redfish-schema.v1_0_0.json"
186
187 return parse(key)
188
189
Ed Tanous683f7272018-07-26 12:47:19 -0700190# Remove the old files
Ed Tanous8b564552022-09-23 12:03:18 -0700191
Ed Tanous27747912022-09-23 12:50:08 -0700192skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700193if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700194 files = [
195 os.path.join(schema_path, f)
196 for f in os.listdir(schema_path)
197 if not f.startswith(skip_prefixes)
198 ]
James Feistaee8d842018-09-10 16:07:40 -0700199 for f in files:
200 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700201if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700202 files = [
203 os.path.join(json_schema_path, f)
204 for f in os.listdir(json_schema_path)
205 if not f.startswith(skip_prefixes)
206 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700207 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700208 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700209 os.remove(f)
210 else:
211 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700212try:
213 os.remove(metadata_index_path)
214except FileNotFoundError:
215 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700216
Ed Tanous118b1c72018-09-13 13:45:51 -0700217if not os.path.exists(schema_path):
218 os.makedirs(schema_path)
219if not os.path.exists(json_schema_path):
220 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700221
Ed Tanous8b564552022-09-23 12:03:18 -0700222csdl_filenames = []
223json_schema_files = defaultdict(list)
224
225for zip_filepath in zip_ref.namelist():
226 if zip_filepath.startswith("csdl/") and (zip_filepath != "csdl/"):
227 csdl_filenames.append(os.path.basename(zip_filepath))
228 elif zip_filepath.startswith("json-schema/"):
229 filename = os.path.basename(zip_filepath)
230 filenamesplit = filename.split(".")
231 # exclude schemas again to save flash space
232 if filenamesplit[0] not in include_list:
233 continue
234 json_schema_files[filenamesplit[0]].append(filename)
235 elif zip_filepath.startswith("openapi/"):
236 pass
237 elif zip_filepath.startswith("dictionaries/"):
238 pass
239
240# sort the json files by version
241for key, value in json_schema_files.items():
242 value.sort(key=version_sort_key, reverse=True)
243
244# Create a dictionary ordered by schema name
245json_schema_files = OrderedDict(
246 sorted(json_schema_files.items(), key=lambda x: version_sort_key(x[0]))
247)
248
249csdl_filenames.sort(key=version_sort_key)
Ed Tanous27747912022-09-23 12:50:08 -0700250with open(metadata_index_path, "w") as metadata_index:
Ed Tanous118b1c72018-09-13 13:45:51 -0700251
Ed Tanous27747912022-09-23 12:50:08 -0700252 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700253 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700254 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700255 '"http://docs.oasis-open.org/odata/ns/edmx"'
256 ' Version="4.0">\n'
257 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700258
Ed Tanous8b564552022-09-23 12:03:18 -0700259 for filename in csdl_filenames:
260 # filename looks like Zone_v1.xml
261 filenamesplit = filename.split("_")
262 if filenamesplit[0] not in include_list:
263 print("excluding schema: " + filename)
264 continue
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600265
Ed Tanous8b564552022-09-23 12:03:18 -0700266 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600267
Ed Tanous8b564552022-09-23 12:03:18 -0700268 metadata_index.write(
269 ' <edmx:Reference Uri="/redfish/v1/schema/'
270 + filename
271 + '">\n'
272 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700273
Ed Tanous8b564552022-09-23 12:03:18 -0700274 content = zip_ref.read(os.path.join("csdl", filename))
275 content = content.replace(b"\r\n", b"\n")
276 xml_root = ET.fromstring(content)
277 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
278 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
279 for edmx_child in xml_root:
280 if edmx_child.tag == edmx + "DataServices":
281 for data_child in edmx_child:
282 if data_child.tag == edm + "Schema":
283 namespace = data_child.attrib["Namespace"]
284 if namespace.startswith("RedfishExtensions"):
285 metadata_index.write(
286 " "
287 '<edmx:Include Namespace="'
288 + namespace
289 + '" Alias="Redfish"/>\n'
290 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700291
Ed Tanous8b564552022-09-23 12:03:18 -0700292 else:
293 metadata_index.write(
294 " "
295 '<edmx:Include Namespace="'
296 + namespace
297 + '"/>\n'
298 )
299 schema_out.write(content)
300 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"
380 "\n"
381 "namespace redfish\n"
382 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700383 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700384 )
Ed Tanous8b564552022-09-23 12:03:18 -0700385 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700386 hpp_file.write(' "{}",\n'.format(schema_file))
387
388 hpp_file.write(" };\n" "}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700389
390zip_ref.close()