blob: a27c1562984b8ef808b1c387bc6696aa9f4e9ac7 [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",
Carson Labrado5315c1b2023-02-18 01:02:18 +000031 "AggregationSourceCollection",
Ed Tanous27747912022-09-23 12:50:08 -070032 "Assembly",
33 "AttributeRegistry",
34 "Bios",
35 "Cable",
36 "CableCollection",
37 "Certificate",
38 "CertificateCollection",
39 "CertificateLocations",
40 "CertificateService",
41 "Chassis",
42 "ChassisCollection",
43 "ComputerSystem",
44 "ComputerSystemCollection",
45 "Drive",
46 "DriveCollection",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060047 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070048 "EthernetInterface",
49 "EthernetInterfaceCollection",
50 "Event",
51 "EventDestination",
52 "EventDestinationCollection",
53 "EventService",
Lakshmi Yadlapati71abefe2023-01-10 22:22:09 -060054 "FabricAdapter",
55 "FabricAdapterCollection",
George Liu1a7b3772022-09-29 09:29:18 +080056 "Fan",
57 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070058 "IPAddresses",
59 "JsonSchemaFile",
60 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
61 "LogEntry",
62 "LogEntryCollection",
63 "LogService",
64 "LogServiceCollection",
65 "Manager",
66 "ManagerAccount",
67 "ManagerAccountCollection",
68 "ManagerCollection",
69 "ManagerDiagnosticData",
70 "ManagerNetworkProtocol",
71 "Memory",
72 "MemoryCollection",
73 "Message",
74 "MessageRegistry",
75 "MessageRegistryCollection",
76 "MessageRegistryFile",
77 "MessageRegistryFileCollection",
78 "MetricDefinition",
79 "MetricDefinitionCollection",
80 "MetricReport",
81 "MetricReportCollection",
82 "MetricReportDefinition",
83 "MetricReportDefinitionCollection",
84 "OperatingConfig",
85 "OperatingConfigCollection",
86 "PCIeDevice",
87 "PCIeDeviceCollection",
88 "PCIeFunction",
89 "PCIeFunctionCollection",
90 "PhysicalContext",
91 "PCIeSlots",
George Liu7da1c582023-02-21 14:38:49 +080092 "Port",
93 "PortCollection",
Ed Tanous27747912022-09-23 12:50:08 -070094 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080095 "PowerSubsystem",
96 "PowerSupply",
97 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070098 "Privileges", # Used in Role
99 "Processor",
100 "ProcessorCollection",
101 "RedfishError",
102 "RedfishExtensions",
103 "Redundancy",
104 "Resource",
105 "Role",
106 "RoleCollection",
107 "Sensor",
108 "SensorCollection",
109 "ServiceRoot",
110 "Session",
111 "SessionCollection",
112 "SessionService",
113 "Settings",
114 "SoftwareInventory",
115 "SoftwareInventoryCollection",
116 "Storage",
117 "StorageCollection",
118 "StorageController",
119 "StorageControllerCollection",
120 "Task",
121 "TaskCollection",
122 "TaskService",
123 "TelemetryService",
124 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800125 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700126 "ThermalSubsystem",
127 "Triggers",
128 "TriggersCollection",
129 "UpdateService",
130 "VLanNetworkInterfaceCollection",
131 "VLanNetworkInterface",
132 "VirtualMedia",
133 "VirtualMediaCollection",
134 "odata",
135 "odata-v4",
136 "redfish-error",
137 "redfish-payload-annotations",
138 "redfish-schema",
139 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600140]
141
Ed Tanous683f7272018-07-26 12:47:19 -0700142SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
143
Ed Tanous27747912022-09-23 12:50:08 -0700144proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700145
Ed Tanouscb103132019-10-08 11:34:22 -0700146r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700147 "https://www.dmtf.org/sites/default/files/standards/documents/"
148 + VERSION
149 + ".zip",
150 proxies=proxies,
151)
Ed Tanous683f7272018-07-26 12:47:19 -0700152
153r.raise_for_status()
154
Ed Tanous81d523a2022-05-25 12:00:51 -0700155
Ed Tanous27747912022-09-23 12:50:08 -0700156static_path = os.path.realpath(
157 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
158)
Ed Tanous683f7272018-07-26 12:47:19 -0700159
Ed Tanous81d523a2022-05-25 12:00:51 -0700160
Ed Tanous27747912022-09-23 12:50:08 -0700161cpp_path = os.path.realpath(
162 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
163)
Ed Tanous81d523a2022-05-25 12:00:51 -0700164
165
Ed Tanous683f7272018-07-26 12:47:19 -0700166schema_path = os.path.join(static_path, "schema")
167json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700168metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700169
170zipBytesIO = BytesIO(r.content)
171zip_ref = zipfile.ZipFile(zipBytesIO)
172
Ed Tanous8b564552022-09-23 12:03:18 -0700173
Ed Tanous204c3762022-12-12 09:50:09 -0800174class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600175 """
Ed Tanous204c3762022-12-12 09:50:09 -0800176 A Python class for sorting Redfish schema versions. Allows sorting Redfish
177 versions in the way humans expect, by comparing version strings as lists
178 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
179 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600180 """
Ed Tanous8b564552022-09-23 12:03:18 -0700181
Ed Tanous204c3762022-12-12 09:50:09 -0800182 def __init__(self, key):
183 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700184
Ed Tanous204c3762022-12-12 09:50:09 -0800185 split_tup = key.split(".")
186 self.version_pieces = [split_tup[0]]
187 if len(split_tup) < 2:
188 return
189 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700190
Ed Tanous204c3762022-12-12 09:50:09 -0800191 if version.startswith("v"):
192 version = version[1:]
193 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600194 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700195
Ed Tanous204c3762022-12-12 09:50:09 -0800196 def __lt__(self, other):
197 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700198
199
Ed Tanous683f7272018-07-26 12:47:19 -0700200# Remove the old files
Ed Tanous5b5574a2022-09-26 19:53:36 -0700201skip_prefixes = ["Oem", "OpenBMC"]
Ed Tanous683f7272018-07-26 12:47:19 -0700202if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700203 files = [
204 os.path.join(schema_path, f)
205 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700206 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700207 ]
James Feistaee8d842018-09-10 16:07:40 -0700208 for f in files:
209 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700210if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700211 files = [
212 os.path.join(json_schema_path, f)
213 for f in os.listdir(json_schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700214 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700215 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700216 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700217 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700218 os.remove(f)
219 else:
220 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700221try:
222 os.remove(metadata_index_path)
223except FileNotFoundError:
224 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700225
Ed Tanous118b1c72018-09-13 13:45:51 -0700226if not os.path.exists(schema_path):
227 os.makedirs(schema_path)
228if not os.path.exists(json_schema_path):
229 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700230
Ed Tanous8b564552022-09-23 12:03:18 -0700231csdl_filenames = []
232json_schema_files = defaultdict(list)
233
Ed Tanous204c3762022-12-12 09:50:09 -0800234for zip_file in zip_ref.infolist():
235 if zip_file.is_dir():
236 continue
237 if zip_file.filename.startswith("csdl/"):
238 csdl_filenames.append(os.path.basename(zip_file.filename))
239 elif zip_file.filename.startswith("json-schema/"):
240 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700241 filenamesplit = filename.split(".")
242 # exclude schemas again to save flash space
243 if filenamesplit[0] not in include_list:
244 continue
245 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800246 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700247 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800248 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700249 pass
250
251# sort the json files by version
252for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800253 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700254
255# Create a dictionary ordered by schema name
256json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800257 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700258)
259
Ed Tanous204c3762022-12-12 09:50:09 -0800260csdl_filenames.sort(key=SchemaVersion)
Ed Tanous27747912022-09-23 12:50:08 -0700261with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700262 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700263 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700264 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700265 '"http://docs.oasis-open.org/odata/ns/edmx"'
266 ' Version="4.0">\n'
267 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700268
Ed Tanous8b564552022-09-23 12:03:18 -0700269 for filename in csdl_filenames:
270 # filename looks like Zone_v1.xml
Ed Tanous8b564552022-09-23 12:03:18 -0700271 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800272 content = zip_ref.read(os.path.join("csdl", filename))
273 content = content.replace(b"\r\n", b"\n")
274
275 schema_out.write(content)
276
277 filenamesplit = filename.split("_")
278 if filenamesplit[0] not in include_list:
279 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700280 metadata_index.write(
281 ' <edmx:Reference Uri="/redfish/v1/schema/'
282 + filename
283 + '">\n'
284 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700285
Ed Tanous8b564552022-09-23 12:03:18 -0700286 xml_root = ET.fromstring(content)
287 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
288 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
289 for edmx_child in xml_root:
290 if edmx_child.tag == edmx + "DataServices":
291 for data_child in edmx_child:
292 if data_child.tag == edm + "Schema":
293 namespace = data_child.attrib["Namespace"]
294 if namespace.startswith("RedfishExtensions"):
295 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600296 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700297 + namespace
298 + '" Alias="Redfish"/>\n'
299 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700300
Ed Tanous8b564552022-09-23 12:03:18 -0700301 else:
302 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600303 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700304 + namespace
305 + '"/>\n'
306 )
Ed Tanous8b564552022-09-23 12:03:18 -0700307 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="'
Ed Tanous5d3a59d2023-02-13 10:24:04 -0800352 '/redfish/v1/schema/OpenBMCAccountService_v1.xml">\n'
Ed Tanous27747912022-09-23 12:50:08 -0700353 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700354 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800355 ' <edmx:Include Namespace="OpenBMCAccountService"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700356 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700357 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800358 ' <edmx:Include Namespace="OpenBMCAccountService.v1_0_0"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700359 )
Gunnar Mills20778992020-02-06 16:36:47 -0600360 metadata_index.write(" </edmx:Reference>\n")
361
Ed Tanous118b1c72018-09-13 13:45:51 -0700362 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700363
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600364
Ed Tanous8b564552022-09-23 12:03:18 -0700365for schema, version in json_schema_files.items():
366 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700367 schemadir = os.path.join(json_schema_path, schema)
368 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700369
Ed Tanous27747912022-09-23 12:50:08 -0700370 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
371 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700372
Ed Tanous27747912022-09-23 12:50:08 -0700373with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700374 hpp_file.write(
375 "#pragma once\n"
376 "{WARNING}\n"
377 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700378 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700379 "\n"
380 "namespace redfish\n"
381 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700382 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700383 )
Ed Tanous8b564552022-09-23 12:03:18 -0700384 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700385 hpp_file.write(' "{}",\n'.format(schema_file))
386
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600387 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700388
389zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700390
391generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000392generate_top_collections()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800393
394# Now delete the xml schema files we aren't supporting
395if os.path.exists(schema_path):
396 files = [
397 os.path.join(schema_path, f)
398 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700399 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous853c0dc2022-12-21 13:21:52 -0800400 ]
401 for filename in files:
402 # filename will include the absolute path
403 filenamesplit = filename.split("/")
404 name = filenamesplit.pop()
405 namesplit = name.split("_")
406 if namesplit[0] not in include_list:
407 print("excluding schema: " + filename)
408 os.remove(filename)