blob: 7f91496035fcd3ff92ed03ca09963b77a3bbe818 [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",
George Liubf7e67e2022-10-06 09:19:46 +080046 'EnvironmentMetrics',
Ed Tanous27747912022-09-23 12:50:08 -070047 "EthernetInterface",
48 "EthernetInterfaceCollection",
49 "Event",
50 "EventDestination",
51 "EventDestinationCollection",
52 "EventService",
George Liu1a7b3772022-09-29 09:29:18 +080053 "Fan",
54 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070055 "IPAddresses",
56 "JsonSchemaFile",
57 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
58 "LogEntry",
59 "LogEntryCollection",
60 "LogService",
61 "LogServiceCollection",
62 "Manager",
63 "ManagerAccount",
64 "ManagerAccountCollection",
65 "ManagerCollection",
66 "ManagerDiagnosticData",
67 "ManagerNetworkProtocol",
68 "Memory",
69 "MemoryCollection",
70 "Message",
71 "MessageRegistry",
72 "MessageRegistryCollection",
73 "MessageRegistryFile",
74 "MessageRegistryFileCollection",
75 "MetricDefinition",
76 "MetricDefinitionCollection",
77 "MetricReport",
78 "MetricReportCollection",
79 "MetricReportDefinition",
80 "MetricReportDefinitionCollection",
81 "OperatingConfig",
82 "OperatingConfigCollection",
83 "PCIeDevice",
84 "PCIeDeviceCollection",
85 "PCIeFunction",
86 "PCIeFunctionCollection",
87 "PhysicalContext",
88 "PCIeSlots",
89 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080090 "PowerSubsystem",
91 "PowerSupply",
92 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070093 "Privileges", # Used in Role
94 "Processor",
95 "ProcessorCollection",
96 "RedfishError",
97 "RedfishExtensions",
98 "Redundancy",
99 "Resource",
100 "Role",
101 "RoleCollection",
102 "Sensor",
103 "SensorCollection",
104 "ServiceRoot",
105 "Session",
106 "SessionCollection",
107 "SessionService",
108 "Settings",
109 "SoftwareInventory",
110 "SoftwareInventoryCollection",
111 "Storage",
112 "StorageCollection",
113 "StorageController",
114 "StorageControllerCollection",
115 "Task",
116 "TaskCollection",
117 "TaskService",
118 "TelemetryService",
119 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800120 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700121 "ThermalSubsystem",
122 "Triggers",
123 "TriggersCollection",
124 "UpdateService",
125 "VLanNetworkInterfaceCollection",
126 "VLanNetworkInterface",
127 "VirtualMedia",
128 "VirtualMediaCollection",
129 "odata",
130 "odata-v4",
131 "redfish-error",
132 "redfish-payload-annotations",
133 "redfish-schema",
134 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600135]
136
Ed Tanous683f7272018-07-26 12:47:19 -0700137SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
138
Ed Tanous27747912022-09-23 12:50:08 -0700139proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700140
Ed Tanouscb103132019-10-08 11:34:22 -0700141r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700142 "https://www.dmtf.org/sites/default/files/standards/documents/"
143 + VERSION
144 + ".zip",
145 proxies=proxies,
146)
Ed Tanous683f7272018-07-26 12:47:19 -0700147
148r.raise_for_status()
149
Ed Tanous81d523a2022-05-25 12:00:51 -0700150
Ed Tanous27747912022-09-23 12:50:08 -0700151static_path = os.path.realpath(
152 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
153)
Ed Tanous683f7272018-07-26 12:47:19 -0700154
Ed Tanous81d523a2022-05-25 12:00:51 -0700155
Ed Tanous27747912022-09-23 12:50:08 -0700156cpp_path = os.path.realpath(
157 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
158)
Ed Tanous81d523a2022-05-25 12:00:51 -0700159
160
Ed Tanous683f7272018-07-26 12:47:19 -0700161schema_path = os.path.join(static_path, "schema")
162json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700163metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700164
165zipBytesIO = BytesIO(r.content)
166zip_ref = zipfile.ZipFile(zipBytesIO)
167
Ed Tanous8b564552022-09-23 12:03:18 -0700168
169def version_sort_key(key):
170 """
171 Method that computes a sort key that zero pads all numbers, such that
172 version sorting like
173 0_2_0
174 0_10_0
175 sorts in the way humans expect.
176 it also does case insensitive comparisons.
177 """
178 key = str.casefold(key)
179
180 # Decription of this class calls it "Version numbering for anarchists and
181 # software realists.". That seems like exactly what we need here.
182
183 if not any(char.isdigit() for char in key):
184 split_tup = os.path.splitext(key)
185 key = split_tup[0] + ".v0_0_0" + split_tup[1]
186
187 # special case some files that don't seem to follow the naming convention,
188 # and cause sort problems. These need brought up with DMTF TODO(Ed)
189 if key == "odata.4.0.0.json":
190 key = "odata.v4_0_0.json"
191 if key == "redfish-schema.1.0.0.json":
192 key = "redfish-schema.v1_0_0.json"
193
194 return parse(key)
195
196
Ed Tanous683f7272018-07-26 12:47:19 -0700197# Remove the old files
Ed Tanous8b564552022-09-23 12:03:18 -0700198
Ed Tanous27747912022-09-23 12:50:08 -0700199skip_prefixes = "Oem"
Ed Tanous683f7272018-07-26 12:47:19 -0700200if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700201 files = [
202 os.path.join(schema_path, f)
203 for f in os.listdir(schema_path)
204 if not f.startswith(skip_prefixes)
205 ]
James Feistaee8d842018-09-10 16:07:40 -0700206 for f in files:
207 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700208if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700209 files = [
210 os.path.join(json_schema_path, f)
211 for f in os.listdir(json_schema_path)
212 if not f.startswith(skip_prefixes)
213 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700214 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700215 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700216 os.remove(f)
217 else:
218 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700219try:
220 os.remove(metadata_index_path)
221except FileNotFoundError:
222 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700223
Ed Tanous118b1c72018-09-13 13:45:51 -0700224if not os.path.exists(schema_path):
225 os.makedirs(schema_path)
226if not os.path.exists(json_schema_path):
227 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700228
Ed Tanous8b564552022-09-23 12:03:18 -0700229csdl_filenames = []
230json_schema_files = defaultdict(list)
231
232for zip_filepath in zip_ref.namelist():
233 if zip_filepath.startswith("csdl/") and (zip_filepath != "csdl/"):
234 csdl_filenames.append(os.path.basename(zip_filepath))
235 elif zip_filepath.startswith("json-schema/"):
236 filename = os.path.basename(zip_filepath)
237 filenamesplit = filename.split(".")
238 # exclude schemas again to save flash space
239 if filenamesplit[0] not in include_list:
240 continue
241 json_schema_files[filenamesplit[0]].append(filename)
242 elif zip_filepath.startswith("openapi/"):
243 pass
244 elif zip_filepath.startswith("dictionaries/"):
245 pass
246
247# sort the json files by version
248for key, value in json_schema_files.items():
249 value.sort(key=version_sort_key, reverse=True)
250
251# Create a dictionary ordered by schema name
252json_schema_files = OrderedDict(
253 sorted(json_schema_files.items(), key=lambda x: version_sort_key(x[0]))
254)
255
256csdl_filenames.sort(key=version_sort_key)
Ed Tanous27747912022-09-23 12:50:08 -0700257with open(metadata_index_path, "w") as metadata_index:
Ed Tanous118b1c72018-09-13 13:45:51 -0700258
Ed Tanous27747912022-09-23 12:50:08 -0700259 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700260 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700261 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700262 '"http://docs.oasis-open.org/odata/ns/edmx"'
263 ' Version="4.0">\n'
264 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700265
Ed Tanous8b564552022-09-23 12:03:18 -0700266 for filename in csdl_filenames:
267 # filename looks like Zone_v1.xml
268 filenamesplit = filename.split("_")
269 if filenamesplit[0] not in include_list:
270 print("excluding schema: " + filename)
271 continue
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600272
Ed Tanous8b564552022-09-23 12:03:18 -0700273 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600274
Ed Tanous8b564552022-09-23 12:03:18 -0700275 metadata_index.write(
276 ' <edmx:Reference Uri="/redfish/v1/schema/'
277 + filename
278 + '">\n'
279 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700280
Ed Tanous8b564552022-09-23 12:03:18 -0700281 content = zip_ref.read(os.path.join("csdl", filename))
282 content = content.replace(b"\r\n", b"\n")
283 xml_root = ET.fromstring(content)
284 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
285 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
286 for edmx_child in xml_root:
287 if edmx_child.tag == edmx + "DataServices":
288 for data_child in edmx_child:
289 if data_child.tag == edm + "Schema":
290 namespace = data_child.attrib["Namespace"]
291 if namespace.startswith("RedfishExtensions"):
292 metadata_index.write(
293 " "
294 '<edmx:Include Namespace="'
295 + namespace
296 + '" Alias="Redfish"/>\n'
297 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700298
Ed Tanous8b564552022-09-23 12:03:18 -0700299 else:
300 metadata_index.write(
301 " "
302 '<edmx:Include Namespace="'
303 + namespace
304 + '"/>\n'
305 )
306 schema_out.write(content)
307 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700308
Ed Tanous27747912022-09-23 12:50:08 -0700309 metadata_index.write(
310 " <edmx:DataServices>\n"
311 " <Schema "
312 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
313 'Namespace="Service">\n'
314 ' <EntityContainer Name="Service" '
315 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
316 " </Schema>\n"
317 " </edmx:DataServices>\n"
318 )
Ed Tanouscb103132019-10-08 11:34:22 -0700319 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500320 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700321 # don't update schemas very often, we just manually fix it. Need a
322 # permanent fix to the script.
323 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700324 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
325 )
326 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600327 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600328
329 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700330 ' <edmx:Reference Uri="'
331 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
332 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700333 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700334 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
335 )
Gunnar Mills20778992020-02-06 16:36:47 -0600336 metadata_index.write(" </edmx:Reference>\n")
337
338 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700339 ' <edmx:Reference Uri="'
340 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
341 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700342 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700343 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
344 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700345 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700346 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
347 )
Gunnar Mills20778992020-02-06 16:36:47 -0600348 metadata_index.write(" </edmx:Reference>\n")
349
350 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700351 ' <edmx:Reference Uri="'
352 '/redfish/v1/schema/OemAccountService_v1.xml">\n'
353 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700354 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700355 ' <edmx:Include Namespace="OemAccountService"/>\n'
356 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700357 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700358 ' <edmx:Include Namespace="OemAccountService.v1_0_0"/>\n'
359 )
Gunnar Mills20778992020-02-06 16:36:47 -0600360 metadata_index.write(" </edmx:Reference>\n")
361
Ravi Tejae7d68c32020-03-15 13:30:41 -0500362 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700363 ' <edmx:Reference Uri="/redfish/v1/schema/OemSession_v1.xml">\n'
364 )
365 metadata_index.write(' <edmx:Include Namespace="OemSession"/>\n')
Ed Tanousf395daa2021-08-02 08:56:24 -0700366 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700367 ' <edmx:Include Namespace="OemSession.v1_0_0"/>\n'
368 )
Sunitha Harish9dc50742020-05-11 00:10:20 -0500369 metadata_index.write(" </edmx:Reference>\n")
370
Ed Tanous118b1c72018-09-13 13:45:51 -0700371 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700372
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600373
Ed Tanous8b564552022-09-23 12:03:18 -0700374for schema, version in json_schema_files.items():
375 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700376 schemadir = os.path.join(json_schema_path, schema)
377 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700378
Ed Tanous27747912022-09-23 12:50:08 -0700379 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
380 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700381
Ed Tanous27747912022-09-23 12:50:08 -0700382with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700383 hpp_file.write(
384 "#pragma once\n"
385 "{WARNING}\n"
386 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700387 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700388 "\n"
389 "namespace redfish\n"
390 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700391 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700392 )
Ed Tanous8b564552022-09-23 12:03:18 -0700393 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700394 hpp_file.write(' "{}",\n'.format(schema_file))
395
396 hpp_file.write(" };\n" "}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700397
398zip_ref.close()