blob: 474c268febf2075969321d846deb83d1c049f07c [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 Labrado8b2521a2023-02-18 02:33:14 +000031 "AggregationSource",
Carson Labrado5315c1b2023-02-18 01:02:18 +000032 "AggregationSourceCollection",
Ed Tanous27747912022-09-23 12:50:08 -070033 "Assembly",
34 "AttributeRegistry",
35 "Bios",
36 "Cable",
37 "CableCollection",
38 "Certificate",
39 "CertificateCollection",
40 "CertificateLocations",
41 "CertificateService",
42 "Chassis",
43 "ChassisCollection",
44 "ComputerSystem",
45 "ComputerSystemCollection",
46 "Drive",
47 "DriveCollection",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060048 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070049 "EthernetInterface",
50 "EthernetInterfaceCollection",
51 "Event",
52 "EventDestination",
53 "EventDestinationCollection",
54 "EventService",
Lakshmi Yadlapati71abefe2023-01-10 22:22:09 -060055 "FabricAdapter",
56 "FabricAdapterCollection",
George Liu1a7b3772022-09-29 09:29:18 +080057 "Fan",
58 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070059 "IPAddresses",
60 "JsonSchemaFile",
61 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
62 "LogEntry",
63 "LogEntryCollection",
64 "LogService",
65 "LogServiceCollection",
66 "Manager",
67 "ManagerAccount",
68 "ManagerAccountCollection",
69 "ManagerCollection",
70 "ManagerDiagnosticData",
71 "ManagerNetworkProtocol",
72 "Memory",
73 "MemoryCollection",
74 "Message",
75 "MessageRegistry",
76 "MessageRegistryCollection",
77 "MessageRegistryFile",
78 "MessageRegistryFileCollection",
79 "MetricDefinition",
80 "MetricDefinitionCollection",
81 "MetricReport",
82 "MetricReportCollection",
83 "MetricReportDefinition",
84 "MetricReportDefinitionCollection",
85 "OperatingConfig",
86 "OperatingConfigCollection",
87 "PCIeDevice",
88 "PCIeDeviceCollection",
89 "PCIeFunction",
90 "PCIeFunctionCollection",
91 "PhysicalContext",
92 "PCIeSlots",
George Liu7da1c582023-02-21 14:38:49 +080093 "Port",
94 "PortCollection",
Ed Tanous27747912022-09-23 12:50:08 -070095 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080096 "PowerSubsystem",
97 "PowerSupply",
98 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -070099 "Privileges", # Used in Role
100 "Processor",
101 "ProcessorCollection",
102 "RedfishError",
103 "RedfishExtensions",
104 "Redundancy",
105 "Resource",
106 "Role",
107 "RoleCollection",
108 "Sensor",
109 "SensorCollection",
110 "ServiceRoot",
111 "Session",
112 "SessionCollection",
113 "SessionService",
114 "Settings",
115 "SoftwareInventory",
116 "SoftwareInventoryCollection",
117 "Storage",
118 "StorageCollection",
119 "StorageController",
120 "StorageControllerCollection",
121 "Task",
122 "TaskCollection",
123 "TaskService",
124 "TelemetryService",
125 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800126 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700127 "ThermalSubsystem",
128 "Triggers",
129 "TriggersCollection",
130 "UpdateService",
131 "VLanNetworkInterfaceCollection",
132 "VLanNetworkInterface",
133 "VirtualMedia",
134 "VirtualMediaCollection",
135 "odata",
136 "odata-v4",
137 "redfish-error",
138 "redfish-payload-annotations",
139 "redfish-schema",
140 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600141]
142
Ed Tanous683f7272018-07-26 12:47:19 -0700143SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
144
Ed Tanous27747912022-09-23 12:50:08 -0700145proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700146
Ed Tanouscb103132019-10-08 11:34:22 -0700147r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700148 "https://www.dmtf.org/sites/default/files/standards/documents/"
149 + VERSION
150 + ".zip",
151 proxies=proxies,
152)
Ed Tanous683f7272018-07-26 12:47:19 -0700153
154r.raise_for_status()
155
Ed Tanous81d523a2022-05-25 12:00:51 -0700156
Ed Tanous27747912022-09-23 12:50:08 -0700157static_path = os.path.realpath(
158 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
159)
Ed Tanous683f7272018-07-26 12:47:19 -0700160
Ed Tanous81d523a2022-05-25 12:00:51 -0700161
Ed Tanous27747912022-09-23 12:50:08 -0700162cpp_path = os.path.realpath(
163 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
164)
Ed Tanous81d523a2022-05-25 12:00:51 -0700165
166
Ed Tanous683f7272018-07-26 12:47:19 -0700167schema_path = os.path.join(static_path, "schema")
168json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700169metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700170
171zipBytesIO = BytesIO(r.content)
172zip_ref = zipfile.ZipFile(zipBytesIO)
173
Ed Tanous8b564552022-09-23 12:03:18 -0700174
Ed Tanous204c3762022-12-12 09:50:09 -0800175class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600176 """
Ed Tanous204c3762022-12-12 09:50:09 -0800177 A Python class for sorting Redfish schema versions. Allows sorting Redfish
178 versions in the way humans expect, by comparing version strings as lists
179 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
180 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600181 """
Ed Tanous8b564552022-09-23 12:03:18 -0700182
Ed Tanous204c3762022-12-12 09:50:09 -0800183 def __init__(self, key):
184 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700185
Ed Tanous204c3762022-12-12 09:50:09 -0800186 split_tup = key.split(".")
187 self.version_pieces = [split_tup[0]]
188 if len(split_tup) < 2:
189 return
190 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700191
Ed Tanous204c3762022-12-12 09:50:09 -0800192 if version.startswith("v"):
193 version = version[1:]
194 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600195 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700196
Ed Tanous204c3762022-12-12 09:50:09 -0800197 def __lt__(self, other):
198 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700199
200
Ed Tanous683f7272018-07-26 12:47:19 -0700201# Remove the old files
Ed Tanous5b5574a2022-09-26 19:53:36 -0700202skip_prefixes = ["Oem", "OpenBMC"]
Ed Tanous683f7272018-07-26 12:47:19 -0700203if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700204 files = [
205 os.path.join(schema_path, f)
206 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700207 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700208 ]
James Feistaee8d842018-09-10 16:07:40 -0700209 for f in files:
210 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700211if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700212 files = [
213 os.path.join(json_schema_path, f)
214 for f in os.listdir(json_schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700215 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700216 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700217 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700218 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700219 os.remove(f)
220 else:
221 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700222try:
223 os.remove(metadata_index_path)
224except FileNotFoundError:
225 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700226
Ed Tanous118b1c72018-09-13 13:45:51 -0700227if not os.path.exists(schema_path):
228 os.makedirs(schema_path)
229if not os.path.exists(json_schema_path):
230 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700231
Ed Tanous8b564552022-09-23 12:03:18 -0700232csdl_filenames = []
233json_schema_files = defaultdict(list)
234
Ed Tanous204c3762022-12-12 09:50:09 -0800235for zip_file in zip_ref.infolist():
236 if zip_file.is_dir():
237 continue
238 if zip_file.filename.startswith("csdl/"):
239 csdl_filenames.append(os.path.basename(zip_file.filename))
240 elif zip_file.filename.startswith("json-schema/"):
241 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700242 filenamesplit = filename.split(".")
243 # exclude schemas again to save flash space
244 if filenamesplit[0] not in include_list:
245 continue
246 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800247 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700248 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800249 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700250 pass
251
252# sort the json files by version
253for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800254 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700255
256# Create a dictionary ordered by schema name
257json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800258 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700259)
260
Ed Tanous204c3762022-12-12 09:50:09 -0800261csdl_filenames.sort(key=SchemaVersion)
Ed Tanous27747912022-09-23 12:50:08 -0700262with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700263 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700264 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700265 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700266 '"http://docs.oasis-open.org/odata/ns/edmx"'
267 ' Version="4.0">\n'
268 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700269
Ed Tanous8b564552022-09-23 12:03:18 -0700270 for filename in csdl_filenames:
271 # filename looks like Zone_v1.xml
Ed Tanous8b564552022-09-23 12:03:18 -0700272 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800273 content = zip_ref.read(os.path.join("csdl", filename))
274 content = content.replace(b"\r\n", b"\n")
275
276 schema_out.write(content)
277
278 filenamesplit = filename.split("_")
279 if filenamesplit[0] not in include_list:
280 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700281 metadata_index.write(
282 ' <edmx:Reference Uri="/redfish/v1/schema/'
283 + filename
284 + '">\n'
285 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700286
Ed Tanous8b564552022-09-23 12:03:18 -0700287 xml_root = ET.fromstring(content)
288 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
289 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
290 for edmx_child in xml_root:
291 if edmx_child.tag == edmx + "DataServices":
292 for data_child in edmx_child:
293 if data_child.tag == edm + "Schema":
294 namespace = data_child.attrib["Namespace"]
295 if namespace.startswith("RedfishExtensions"):
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 + '" Alias="Redfish"/>\n'
300 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700301
Ed Tanous8b564552022-09-23 12:03:18 -0700302 else:
303 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600304 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700305 + namespace
306 + '"/>\n'
307 )
Ed Tanous8b564552022-09-23 12:03:18 -0700308 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700309
Ed Tanous27747912022-09-23 12:50:08 -0700310 metadata_index.write(
311 " <edmx:DataServices>\n"
312 " <Schema "
313 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
314 'Namespace="Service">\n'
315 ' <EntityContainer Name="Service" '
316 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
317 " </Schema>\n"
318 " </edmx:DataServices>\n"
319 )
Ed Tanouscb103132019-10-08 11:34:22 -0700320 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500321 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700322 # don't update schemas very often, we just manually fix it. Need a
323 # permanent fix to the script.
324 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700325 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
326 )
327 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600328 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600329
330 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700331 ' <edmx:Reference Uri="'
332 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
333 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700334 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700335 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
336 )
Gunnar Mills20778992020-02-06 16:36:47 -0600337 metadata_index.write(" </edmx:Reference>\n")
338
339 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700340 ' <edmx:Reference Uri="'
341 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\n'
342 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700343 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700344 ' <edmx:Include Namespace="OemVirtualMedia"/>\n'
345 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700346 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700347 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
348 )
Gunnar Mills20778992020-02-06 16:36:47 -0600349 metadata_index.write(" </edmx:Reference>\n")
350
351 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700352 ' <edmx:Reference Uri="'
Ed Tanous5d3a59d2023-02-13 10:24:04 -0800353 '/redfish/v1/schema/OpenBMCAccountService_v1.xml">\n'
Ed Tanous27747912022-09-23 12:50:08 -0700354 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700355 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800356 ' <edmx:Include Namespace="OpenBMCAccountService"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700357 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700358 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800359 ' <edmx:Include Namespace="OpenBMCAccountService.v1_0_0"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700360 )
Gunnar Mills20778992020-02-06 16:36:47 -0600361 metadata_index.write(" </edmx:Reference>\n")
362
Ed Tanous118b1c72018-09-13 13:45:51 -0700363 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700364
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600365
Ed Tanous8b564552022-09-23 12:03:18 -0700366for schema, version in json_schema_files.items():
367 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700368 schemadir = os.path.join(json_schema_path, schema)
369 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700370
Ed Tanous27747912022-09-23 12:50:08 -0700371 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
372 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700373
Ed Tanous27747912022-09-23 12:50:08 -0700374with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700375 hpp_file.write(
376 "#pragma once\n"
377 "{WARNING}\n"
378 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700379 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700380 "\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
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600388 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700389
390zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700391
392generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000393generate_top_collections()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800394
395# Now delete the xml schema files we aren't supporting
396if os.path.exists(schema_path):
397 files = [
398 os.path.join(schema_path, f)
399 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700400 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous853c0dc2022-12-21 13:21:52 -0800401 ]
402 for filename in files:
403 # filename will include the absolute path
404 filenamesplit = filename.split("/")
405 name = filenamesplit.pop()
406 namesplit = name.split("_")
407 if namesplit[0] not in include_list:
408 print("excluding schema: " + filename)
409 os.remove(filename)