blob: f6eca42c787b27fc0f7df0aebc004e089e6e049b [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
9import requests
10from packaging.version import parse
Ed Tanous0ec8b832022-03-14 14:56:47 -070011import generate_schema_enums
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
168def version_sort_key(key):
169 """
170 Method that computes a sort key that zero pads all numbers, such that
171 version sorting like
172 0_2_0
173 0_10_0
174 sorts in the way humans expect.
175 it also does case insensitive comparisons.
176 """
177 key = str.casefold(key)
178
179 # Decription of this class calls it "Version numbering for anarchists and
180 # software realists.". That seems like exactly what we need here.
181
182 if not any(char.isdigit() for char in key):
183 split_tup = os.path.splitext(key)
184 key = split_tup[0] + ".v0_0_0" + split_tup[1]
185
186 # special case some files that don't seem to follow the naming convention,
187 # and cause sort problems. These need brought up with DMTF TODO(Ed)
188 if key == "odata.4.0.0.json":
189 key = "odata.v4_0_0.json"
190 if key == "redfish-schema.1.0.0.json":
191 key = "redfish-schema.v1_0_0.json"
192
193 return parse(key)
194
195
Ed Tanous683f7272018-07-26 12:47:19 -0700196# Remove the old files
Ed Tanous8b564552022-09-23 12:03:18 -0700197
Ed Tanous27747912022-09-23 12:50:08 -0700198skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700199if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700200 files = [
201 os.path.join(schema_path, f)
202 for f in os.listdir(schema_path)
203 if not f.startswith(skip_prefixes)
204 ]
James Feistaee8d842018-09-10 16:07:40 -0700205 for f in files:
206 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700207if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700208 files = [
209 os.path.join(json_schema_path, f)
210 for f in os.listdir(json_schema_path)
211 if not f.startswith(skip_prefixes)
212 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700213 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700214 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700215 os.remove(f)
216 else:
217 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700218try:
219 os.remove(metadata_index_path)
220except FileNotFoundError:
221 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700222
Ed Tanous118b1c72018-09-13 13:45:51 -0700223if not os.path.exists(schema_path):
224 os.makedirs(schema_path)
225if not os.path.exists(json_schema_path):
226 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700227
Ed Tanous8b564552022-09-23 12:03:18 -0700228csdl_filenames = []
229json_schema_files = defaultdict(list)
230
231for zip_filepath in zip_ref.namelist():
232 if zip_filepath.startswith("csdl/") and (zip_filepath != "csdl/"):
233 csdl_filenames.append(os.path.basename(zip_filepath))
234 elif zip_filepath.startswith("json-schema/"):
235 filename = os.path.basename(zip_filepath)
236 filenamesplit = filename.split(".")
237 # exclude schemas again to save flash space
238 if filenamesplit[0] not in include_list:
239 continue
240 json_schema_files[filenamesplit[0]].append(filename)
241 elif zip_filepath.startswith("openapi/"):
242 pass
243 elif zip_filepath.startswith("dictionaries/"):
244 pass
245
246# sort the json files by version
247for key, value in json_schema_files.items():
248 value.sort(key=version_sort_key, reverse=True)
249
250# Create a dictionary ordered by schema name
251json_schema_files = OrderedDict(
252 sorted(json_schema_files.items(), key=lambda x: version_sort_key(x[0]))
253)
254
255csdl_filenames.sort(key=version_sort_key)
Ed Tanous27747912022-09-23 12:50:08 -0700256with open(metadata_index_path, "w") as metadata_index:
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:
Ed Tanous8b564552022-09-23 12:03:18 -0700272 metadata_index.write(
273 ' <edmx:Reference Uri="/redfish/v1/schema/'
274 + filename
275 + '">\n'
276 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700277
Ed Tanous8b564552022-09-23 12:03:18 -0700278 content = zip_ref.read(os.path.join("csdl", filename))
279 content = content.replace(b"\r\n", b"\n")
280 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 )
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"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700382 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700383 "\n"
384 "namespace redfish\n"
385 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700386 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700387 )
Ed Tanous8b564552022-09-23 12:03:18 -0700388 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700389 hpp_file.write(' "{}",\n'.format(schema_file))
390
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600391 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700392
393zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700394
395generate_schema_enums.main()