blob: 7fea60be7ed9ca978df8df61c1759b2a7bac9c93 [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
Ed Tanous0ec8b832022-03-14 14:56:47 -07009import generate_schema_enums
Patrick Williamsfd06b302022-12-12 10:39:42 -060010import requests
Carson Labrado9e031402022-07-08 20:56:52 +000011from generate_schema_collections import generate_top_collections
Ed Tanous118b1c72018-09-13 13:45:51 -070012
Ed Tanousa8d8f9d2023-01-26 13:57:00 -080013VERSION = "DSP8010_2022.3"
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",
Ed Tanous6c068982023-02-07 15:44:38 -080030 "AggregationService",
Ed Tanous27747912022-09-23 12:50:08 -070031 "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",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060046 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070047 "EthernetInterface",
48 "EthernetInterfaceCollection",
49 "Event",
50 "EventDestination",
51 "EventDestinationCollection",
52 "EventService",
Lakshmi Yadlapati71abefe2023-01-10 22:22:09 -060053 "FabricAdapter",
54 "FabricAdapterCollection",
George Liu1a7b3772022-09-29 09:29:18 +080055 "Fan",
56 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070057 "IPAddresses",
58 "JsonSchemaFile",
59 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
60 "LogEntry",
61 "LogEntryCollection",
62 "LogService",
63 "LogServiceCollection",
64 "Manager",
65 "ManagerAccount",
66 "ManagerAccountCollection",
67 "ManagerCollection",
68 "ManagerDiagnosticData",
69 "ManagerNetworkProtocol",
70 "Memory",
71 "MemoryCollection",
72 "Message",
73 "MessageRegistry",
74 "MessageRegistryCollection",
75 "MessageRegistryFile",
76 "MessageRegistryFileCollection",
77 "MetricDefinition",
78 "MetricDefinitionCollection",
79 "MetricReport",
80 "MetricReportCollection",
81 "MetricReportDefinition",
82 "MetricReportDefinitionCollection",
83 "OperatingConfig",
84 "OperatingConfigCollection",
85 "PCIeDevice",
86 "PCIeDeviceCollection",
87 "PCIeFunction",
88 "PCIeFunctionCollection",
89 "PhysicalContext",
90 "PCIeSlots",
George Liu7da1c582023-02-21 14:38:49 +080091 "Port",
92 "PortCollection",
Ed Tanous27747912022-09-23 12:50:08 -070093 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080094 "PowerSubsystem",
95 "PowerSupply",
96 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070097 "Privileges", # Used in Role
98 "Processor",
99 "ProcessorCollection",
100 "RedfishError",
101 "RedfishExtensions",
102 "Redundancy",
103 "Resource",
104 "Role",
105 "RoleCollection",
106 "Sensor",
107 "SensorCollection",
108 "ServiceRoot",
109 "Session",
110 "SessionCollection",
111 "SessionService",
112 "Settings",
113 "SoftwareInventory",
114 "SoftwareInventoryCollection",
115 "Storage",
116 "StorageCollection",
117 "StorageController",
118 "StorageControllerCollection",
119 "Task",
120 "TaskCollection",
121 "TaskService",
122 "TelemetryService",
123 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800124 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700125 "ThermalSubsystem",
126 "Triggers",
127 "TriggersCollection",
128 "UpdateService",
129 "VLanNetworkInterfaceCollection",
130 "VLanNetworkInterface",
131 "VirtualMedia",
132 "VirtualMediaCollection",
133 "odata",
134 "odata-v4",
135 "redfish-error",
136 "redfish-payload-annotations",
137 "redfish-schema",
138 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600139]
140
Ed Tanous683f7272018-07-26 12:47:19 -0700141SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
142
Ed Tanous27747912022-09-23 12:50:08 -0700143proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700144
Ed Tanouscb103132019-10-08 11:34:22 -0700145r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700146 "https://www.dmtf.org/sites/default/files/standards/documents/"
147 + VERSION
148 + ".zip",
149 proxies=proxies,
150)
Ed Tanous683f7272018-07-26 12:47:19 -0700151
152r.raise_for_status()
153
Ed Tanous81d523a2022-05-25 12:00:51 -0700154
Ed Tanous27747912022-09-23 12:50:08 -0700155static_path = os.path.realpath(
156 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
157)
Ed Tanous683f7272018-07-26 12:47:19 -0700158
Ed Tanous81d523a2022-05-25 12:00:51 -0700159
Ed Tanous27747912022-09-23 12:50:08 -0700160cpp_path = os.path.realpath(
161 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
162)
Ed Tanous81d523a2022-05-25 12:00:51 -0700163
164
Ed Tanous683f7272018-07-26 12:47:19 -0700165schema_path = os.path.join(static_path, "schema")
166json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700167metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700168
169zipBytesIO = BytesIO(r.content)
170zip_ref = zipfile.ZipFile(zipBytesIO)
171
Ed Tanous8b564552022-09-23 12:03:18 -0700172
Ed Tanous204c3762022-12-12 09:50:09 -0800173class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600174 """
Ed Tanous204c3762022-12-12 09:50:09 -0800175 A Python class for sorting Redfish schema versions. Allows sorting Redfish
176 versions in the way humans expect, by comparing version strings as lists
177 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
178 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600179 """
Ed Tanous8b564552022-09-23 12:03:18 -0700180
Ed Tanous204c3762022-12-12 09:50:09 -0800181 def __init__(self, key):
182 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700183
Ed Tanous204c3762022-12-12 09:50:09 -0800184 split_tup = key.split(".")
185 self.version_pieces = [split_tup[0]]
186 if len(split_tup) < 2:
187 return
188 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700189
Ed Tanous204c3762022-12-12 09:50:09 -0800190 if version.startswith("v"):
191 version = version[1:]
192 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600193 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700194
Ed Tanous204c3762022-12-12 09:50:09 -0800195 def __lt__(self, other):
196 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700197
198
Ed Tanous683f7272018-07-26 12:47:19 -0700199# Remove the old files
Ed Tanous5b5574a2022-09-26 19:53:36 -0700200skip_prefixes = ["Oem", "OpenBMC"]
Ed Tanous683f7272018-07-26 12:47:19 -0700201if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700202 files = [
203 os.path.join(schema_path, f)
204 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700205 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700206 ]
James Feistaee8d842018-09-10 16:07:40 -0700207 for f in files:
208 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700209if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700210 files = [
211 os.path.join(json_schema_path, f)
212 for f in os.listdir(json_schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700213 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700214 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700215 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700216 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700217 os.remove(f)
218 else:
219 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700220try:
221 os.remove(metadata_index_path)
222except FileNotFoundError:
223 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700224
Ed Tanous118b1c72018-09-13 13:45:51 -0700225if not os.path.exists(schema_path):
226 os.makedirs(schema_path)
227if not os.path.exists(json_schema_path):
228 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700229
Ed Tanous8b564552022-09-23 12:03:18 -0700230csdl_filenames = []
231json_schema_files = defaultdict(list)
232
Ed Tanous204c3762022-12-12 09:50:09 -0800233for zip_file in zip_ref.infolist():
234 if zip_file.is_dir():
235 continue
236 if zip_file.filename.startswith("csdl/"):
237 csdl_filenames.append(os.path.basename(zip_file.filename))
238 elif zip_file.filename.startswith("json-schema/"):
239 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700240 filenamesplit = filename.split(".")
241 # exclude schemas again to save flash space
242 if filenamesplit[0] not in include_list:
243 continue
244 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800245 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700246 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800247 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700248 pass
249
250# sort the json files by version
251for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800252 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700253
254# Create a dictionary ordered by schema name
255json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800256 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700257)
258
Ed Tanous204c3762022-12-12 09:50:09 -0800259csdl_filenames.sort(key=SchemaVersion)
Ed Tanous27747912022-09-23 12:50:08 -0700260with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700261 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700262 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700263 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700264 '"http://docs.oasis-open.org/odata/ns/edmx"'
265 ' Version="4.0">\n'
266 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700267
Ed Tanous8b564552022-09-23 12:03:18 -0700268 for filename in csdl_filenames:
269 # filename looks like Zone_v1.xml
Ed Tanous8b564552022-09-23 12:03:18 -0700270 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800271 content = zip_ref.read(os.path.join("csdl", filename))
272 content = content.replace(b"\r\n", b"\n")
273
274 schema_out.write(content)
275
276 filenamesplit = filename.split("_")
277 if filenamesplit[0] not in include_list:
278 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700279 metadata_index.write(
280 ' <edmx:Reference Uri="/redfish/v1/schema/'
281 + filename
282 + '">\n'
283 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700284
Ed Tanous8b564552022-09-23 12:03:18 -0700285 xml_root = ET.fromstring(content)
286 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
287 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
288 for edmx_child in xml_root:
289 if edmx_child.tag == edmx + "DataServices":
290 for data_child in edmx_child:
291 if data_child.tag == edm + "Schema":
292 namespace = data_child.attrib["Namespace"]
293 if namespace.startswith("RedfishExtensions"):
294 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600295 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700296 + namespace
297 + '" Alias="Redfish"/>\n'
298 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700299
Ed Tanous8b564552022-09-23 12:03:18 -0700300 else:
301 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600302 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700303 + namespace
304 + '"/>\n'
305 )
Ed Tanous8b564552022-09-23 12:03:18 -0700306 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700307
Ed Tanous27747912022-09-23 12:50:08 -0700308 metadata_index.write(
309 " <edmx:DataServices>\n"
310 " <Schema "
311 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
312 'Namespace="Service">\n'
313 ' <EntityContainer Name="Service" '
314 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
315 " </Schema>\n"
316 " </edmx:DataServices>\n"
317 )
Ed Tanouscb103132019-10-08 11:34:22 -0700318 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500319 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700320 # don't update schemas very often, we just manually fix it. Need a
321 # permanent fix to the script.
322 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700323 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
324 )
325 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600326 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600327
328 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700329 ' <edmx:Reference Uri="'
330 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
331 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700332 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700333 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
334 )
Gunnar Mills20778992020-02-06 16:36:47 -0600335 metadata_index.write(" </edmx:Reference>\n")
336
337 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700338 ' <edmx:Reference Uri="'
339 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
340 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700341 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700342 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
343 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700344 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700345 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
346 )
Gunnar Mills20778992020-02-06 16:36:47 -0600347 metadata_index.write(" </edmx:Reference>\n")
348
349 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700350 ' <edmx:Reference Uri="'
Ed Tanous5d3a59d2023-02-13 10:24:04 -0800351 '/redfish/v1/schema/OpenBMCAccountService_v1.xml">\n'
Ed Tanous27747912022-09-23 12:50:08 -0700352 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700353 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800354 ' <edmx:Include Namespace="OpenBMCAccountService"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700355 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700356 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800357 ' <edmx:Include Namespace="OpenBMCAccountService.v1_0_0"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700358 )
Gunnar Mills20778992020-02-06 16:36:47 -0600359 metadata_index.write(" </edmx:Reference>\n")
360
Ed Tanous118b1c72018-09-13 13:45:51 -0700361 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700362
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600363
Ed Tanous8b564552022-09-23 12:03:18 -0700364for schema, version in json_schema_files.items():
365 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700366 schemadir = os.path.join(json_schema_path, schema)
367 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700368
Ed Tanous27747912022-09-23 12:50:08 -0700369 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
370 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700371
Ed Tanous27747912022-09-23 12:50:08 -0700372with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700373 hpp_file.write(
374 "#pragma once\n"
375 "{WARNING}\n"
376 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700377 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700378 "\n"
379 "namespace redfish\n"
380 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700381 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700382 )
Ed Tanous8b564552022-09-23 12:03:18 -0700383 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700384 hpp_file.write(' "{}",\n'.format(schema_file))
385
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600386 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700387
388zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700389
390generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000391generate_top_collections()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800392
393# Now delete the xml schema files we aren't supporting
394if os.path.exists(schema_path):
395 files = [
396 os.path.join(schema_path, f)
397 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700398 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous853c0dc2022-12-21 13:21:52 -0800399 ]
400 for filename in files:
401 # filename will include the absolute path
402 filenamesplit = filename.split("/")
403 name = filenamesplit.pop()
404 namesplit = name.split("_")
405 if namesplit[0] not in include_list:
406 print("excluding schema: " + filename)
407 os.remove(filename)