blob: 794ec0cd5792cab7afd5c724590cc6d1c70946ab [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",
Ed Tanous23203b42023-03-16 16:58:46 -070046 "ComponentIntegrity",
47 "ComponentIntegrityCollection",
Ed Tanous27747912022-09-23 12:50:08 -070048 "Drive",
49 "DriveCollection",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060050 "EnvironmentMetrics",
Ed Tanous27747912022-09-23 12:50:08 -070051 "EthernetInterface",
52 "EthernetInterfaceCollection",
53 "Event",
54 "EventDestination",
55 "EventDestinationCollection",
56 "EventService",
Lakshmi Yadlapati71abefe2023-01-10 22:22:09 -060057 "FabricAdapter",
58 "FabricAdapterCollection",
George Liu1a7b3772022-09-29 09:29:18 +080059 "Fan",
60 "FanCollection",
Ed Tanous27747912022-09-23 12:50:08 -070061 "IPAddresses",
62 "JsonSchemaFile",
63 "JsonSchemaFileCollection", # redfish/v1/JsonSchemas
64 "LogEntry",
65 "LogEntryCollection",
66 "LogService",
67 "LogServiceCollection",
68 "Manager",
69 "ManagerAccount",
70 "ManagerAccountCollection",
71 "ManagerCollection",
72 "ManagerDiagnosticData",
73 "ManagerNetworkProtocol",
74 "Memory",
75 "MemoryCollection",
76 "Message",
77 "MessageRegistry",
78 "MessageRegistryCollection",
79 "MessageRegistryFile",
80 "MessageRegistryFileCollection",
81 "MetricDefinition",
82 "MetricDefinitionCollection",
83 "MetricReport",
84 "MetricReportCollection",
85 "MetricReportDefinition",
86 "MetricReportDefinitionCollection",
87 "OperatingConfig",
88 "OperatingConfigCollection",
89 "PCIeDevice",
90 "PCIeDeviceCollection",
91 "PCIeFunction",
92 "PCIeFunctionCollection",
93 "PhysicalContext",
94 "PCIeSlots",
George Liu7da1c582023-02-21 14:38:49 +080095 "Port",
96 "PortCollection",
Ed Tanous27747912022-09-23 12:50:08 -070097 "Power",
Chicago Duanfe9bd2d2022-09-30 18:03:05 +080098 "PowerSubsystem",
99 "PowerSupply",
100 "PowerSupplyCollection",
Ed Tanous27747912022-09-23 12:50:08 -0700101 "Privileges", # Used in Role
102 "Processor",
103 "ProcessorCollection",
104 "RedfishError",
105 "RedfishExtensions",
106 "Redundancy",
107 "Resource",
108 "Role",
109 "RoleCollection",
110 "Sensor",
111 "SensorCollection",
112 "ServiceRoot",
113 "Session",
114 "SessionCollection",
115 "SessionService",
116 "Settings",
117 "SoftwareInventory",
118 "SoftwareInventoryCollection",
119 "Storage",
120 "StorageCollection",
121 "StorageController",
122 "StorageControllerCollection",
123 "Task",
124 "TaskCollection",
125 "TaskService",
126 "TelemetryService",
127 "Thermal",
George Liuf1240b42022-10-28 17:26:15 +0800128 "ThermalMetrics",
Ed Tanous27747912022-09-23 12:50:08 -0700129 "ThermalSubsystem",
130 "Triggers",
131 "TriggersCollection",
132 "UpdateService",
133 "VLanNetworkInterfaceCollection",
134 "VLanNetworkInterface",
135 "VirtualMedia",
136 "VirtualMediaCollection",
137 "odata",
138 "odata-v4",
139 "redfish-error",
140 "redfish-payload-annotations",
141 "redfish-schema",
142 "redfish-schema-v1",
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600143]
144
Ed Tanous683f7272018-07-26 12:47:19 -0700145SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
146
Ed Tanous27747912022-09-23 12:50:08 -0700147proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -0700148
Ed Tanouscb103132019-10-08 11:34:22 -0700149r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -0700150 "https://www.dmtf.org/sites/default/files/standards/documents/"
151 + VERSION
152 + ".zip",
153 proxies=proxies,
154)
Ed Tanous683f7272018-07-26 12:47:19 -0700155
156r.raise_for_status()
157
Ed Tanous81d523a2022-05-25 12:00:51 -0700158
Ed Tanous27747912022-09-23 12:50:08 -0700159static_path = os.path.realpath(
160 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
161)
Ed Tanous683f7272018-07-26 12:47:19 -0700162
Ed Tanous81d523a2022-05-25 12:00:51 -0700163
Ed Tanous27747912022-09-23 12:50:08 -0700164cpp_path = os.path.realpath(
165 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
166)
Ed Tanous81d523a2022-05-25 12:00:51 -0700167
168
Ed Tanous683f7272018-07-26 12:47:19 -0700169schema_path = os.path.join(static_path, "schema")
170json_schema_path = os.path.join(static_path, "JsonSchemas")
Ed Tanous118b1c72018-09-13 13:45:51 -0700171metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -0700172
173zipBytesIO = BytesIO(r.content)
174zip_ref = zipfile.ZipFile(zipBytesIO)
175
Ed Tanous8b564552022-09-23 12:03:18 -0700176
Ed Tanous204c3762022-12-12 09:50:09 -0800177class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -0600178 """
Ed Tanous204c3762022-12-12 09:50:09 -0800179 A Python class for sorting Redfish schema versions. Allows sorting Redfish
180 versions in the way humans expect, by comparing version strings as lists
181 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
182 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -0600183 """
Ed Tanous8b564552022-09-23 12:03:18 -0700184
Ed Tanous204c3762022-12-12 09:50:09 -0800185 def __init__(self, key):
186 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -0700187
Ed Tanous204c3762022-12-12 09:50:09 -0800188 split_tup = key.split(".")
189 self.version_pieces = [split_tup[0]]
190 if len(split_tup) < 2:
191 return
192 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -0700193
Ed Tanous204c3762022-12-12 09:50:09 -0800194 if version.startswith("v"):
195 version = version[1:]
196 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -0600197 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -0700198
Ed Tanous204c3762022-12-12 09:50:09 -0800199 def __lt__(self, other):
200 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -0700201
202
Ed Tanous683f7272018-07-26 12:47:19 -0700203# Remove the old files
Ed Tanous5b5574a2022-09-26 19:53:36 -0700204skip_prefixes = ["Oem", "OpenBMC"]
Ed Tanous683f7272018-07-26 12:47:19 -0700205if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700206 files = [
207 os.path.join(schema_path, f)
208 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700209 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700210 ]
James Feistaee8d842018-09-10 16:07:40 -0700211 for f in files:
212 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -0700213if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -0700214 files = [
215 os.path.join(json_schema_path, f)
216 for f in os.listdir(json_schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700217 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700218 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700219 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700220 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700221 os.remove(f)
222 else:
223 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700224try:
225 os.remove(metadata_index_path)
226except FileNotFoundError:
227 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700228
Ed Tanous118b1c72018-09-13 13:45:51 -0700229if not os.path.exists(schema_path):
230 os.makedirs(schema_path)
231if not os.path.exists(json_schema_path):
232 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700233
Ed Tanous8b564552022-09-23 12:03:18 -0700234csdl_filenames = []
235json_schema_files = defaultdict(list)
236
Ed Tanous204c3762022-12-12 09:50:09 -0800237for zip_file in zip_ref.infolist():
238 if zip_file.is_dir():
239 continue
240 if zip_file.filename.startswith("csdl/"):
241 csdl_filenames.append(os.path.basename(zip_file.filename))
242 elif zip_file.filename.startswith("json-schema/"):
243 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700244 filenamesplit = filename.split(".")
245 # exclude schemas again to save flash space
246 if filenamesplit[0] not in include_list:
247 continue
248 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800249 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700250 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800251 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700252 pass
253
254# sort the json files by version
255for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800256 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700257
258# Create a dictionary ordered by schema name
259json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800260 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700261)
262
Ed Tanous204c3762022-12-12 09:50:09 -0800263csdl_filenames.sort(key=SchemaVersion)
Ed Tanous27747912022-09-23 12:50:08 -0700264with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700265 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700266 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700267 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700268 '"http://docs.oasis-open.org/odata/ns/edmx"'
269 ' Version="4.0">\n'
270 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700271
Ed Tanous8b564552022-09-23 12:03:18 -0700272 for filename in csdl_filenames:
273 # filename looks like Zone_v1.xml
Ed Tanous8b564552022-09-23 12:03:18 -0700274 with open(os.path.join(schema_path, filename), "wb") as schema_out:
Ed Tanous853c0dc2022-12-21 13:21:52 -0800275 content = zip_ref.read(os.path.join("csdl", filename))
276 content = content.replace(b"\r\n", b"\n")
277
278 schema_out.write(content)
279
280 filenamesplit = filename.split("_")
281 if filenamesplit[0] not in include_list:
282 continue
Ed Tanous8b564552022-09-23 12:03:18 -0700283 metadata_index.write(
284 ' <edmx:Reference Uri="/redfish/v1/schema/'
285 + filename
286 + '">\n'
287 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700288
Ed Tanous8b564552022-09-23 12:03:18 -0700289 xml_root = ET.fromstring(content)
290 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
291 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
292 for edmx_child in xml_root:
293 if edmx_child.tag == edmx + "DataServices":
294 for data_child in edmx_child:
295 if data_child.tag == edm + "Schema":
296 namespace = data_child.attrib["Namespace"]
297 if namespace.startswith("RedfishExtensions"):
298 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600299 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700300 + namespace
301 + '" Alias="Redfish"/>\n'
302 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700303
Ed Tanous8b564552022-09-23 12:03:18 -0700304 else:
305 metadata_index.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600306 ' <edmx:Include Namespace="'
Ed Tanous8b564552022-09-23 12:03:18 -0700307 + namespace
308 + '"/>\n'
309 )
Ed Tanous8b564552022-09-23 12:03:18 -0700310 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700311
Ed Tanous27747912022-09-23 12:50:08 -0700312 metadata_index.write(
313 " <edmx:DataServices>\n"
314 " <Schema "
315 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
316 'Namespace="Service">\n'
317 ' <EntityContainer Name="Service" '
318 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
319 " </Schema>\n"
320 " </edmx:DataServices>\n"
321 )
Ed Tanouscb103132019-10-08 11:34:22 -0700322 # TODO:Issue#32 There's a bug in the script that currently deletes this
Asmitha Karunanithid337bb72020-09-21 10:34:02 -0500323 # schema (because it's an OEM schema). Because it's the only six, and we
Ed Tanouscb103132019-10-08 11:34:22 -0700324 # don't update schemas very often, we just manually fix it. Need a
325 # permanent fix to the script.
326 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700327 ' <edmx:Reference Uri="/redfish/v1/schema/OemManager_v1.xml">\n'
328 )
329 metadata_index.write(' <edmx:Include Namespace="OemManager"/>\n')
Marri Devender Raod45d2d02019-01-21 10:11:34 -0600330 metadata_index.write(" </edmx:Reference>\n")
Gunnar Mills20778992020-02-06 16:36:47 -0600331
332 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700333 ' <edmx:Reference Uri="'
334 '/redfish/v1/schema/OemComputerSystem_v1.xml">\n'
335 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700336 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700337 ' <edmx:Include Namespace="OemComputerSystem"/>\n'
338 )
Gunnar Mills20778992020-02-06 16:36:47 -0600339 metadata_index.write(" </edmx:Reference>\n")
340
341 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700342 ' <edmx:Reference Uri="'
343 '/redfish/v1/schema/OemVirtualMedia_v1.xml">\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"/>\n'
347 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700348 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700349 ' <edmx:Include Namespace="OemVirtualMedia.v1_0_0"/>\n'
350 )
Gunnar Mills20778992020-02-06 16:36:47 -0600351 metadata_index.write(" </edmx:Reference>\n")
352
353 metadata_index.write(
Ed Tanous27747912022-09-23 12:50:08 -0700354 ' <edmx:Reference Uri="'
Ed Tanous5d3a59d2023-02-13 10:24:04 -0800355 '/redfish/v1/schema/OpenBMCAccountService_v1.xml">\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"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700359 )
Ed Tanousf395daa2021-08-02 08:56:24 -0700360 metadata_index.write(
Ed Tanous5c5804d2023-02-13 13:35:04 -0800361 ' <edmx:Include Namespace="OpenBMCAccountService.v1_0_0"/>\n'
Ed Tanous27747912022-09-23 12:50:08 -0700362 )
Gunnar Mills20778992020-02-06 16:36:47 -0600363 metadata_index.write(" </edmx:Reference>\n")
364
Ed Tanous118b1c72018-09-13 13:45:51 -0700365 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700366
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600367
Ed Tanous8b564552022-09-23 12:03:18 -0700368for schema, version in json_schema_files.items():
369 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous683f7272018-07-26 12:47:19 -0700370 schemadir = os.path.join(json_schema_path, schema)
371 os.makedirs(schemadir)
Ed Tanous118b1c72018-09-13 13:45:51 -0700372
Ed Tanous27747912022-09-23 12:50:08 -0700373 with open(os.path.join(schemadir, schema + ".json"), "wb") as schema_file:
374 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700375
Ed Tanous27747912022-09-23 12:50:08 -0700376with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous81d523a2022-05-25 12:00:51 -0700377 hpp_file.write(
378 "#pragma once\n"
379 "{WARNING}\n"
380 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700381 "#include <array>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700382 "\n"
383 "namespace redfish\n"
384 "{{\n"
Ed Tanous27747912022-09-23 12:50:08 -0700385 " constexpr std::array schemas {{\n".format(WARNING=WARNING)
Ed Tanous81d523a2022-05-25 12:00:51 -0700386 )
Ed Tanous8b564552022-09-23 12:03:18 -0700387 for schema_file in json_schema_files:
Ed Tanous27747912022-09-23 12:50:08 -0700388 hpp_file.write(' "{}",\n'.format(schema_file))
389
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600390 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700391
392zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700393
394generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000395generate_top_collections()
Ed Tanous853c0dc2022-12-21 13:21:52 -0800396
397# Now delete the xml schema files we aren't supporting
398if os.path.exists(schema_path):
399 files = [
400 os.path.join(schema_path, f)
401 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700402 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous853c0dc2022-12-21 13:21:52 -0800403 ]
404 for filename in files:
405 # filename will include the absolute path
406 filenamesplit = filename.split("/")
407 name = filenamesplit.pop()
408 namesplit = name.split("_")
409 if namesplit[0] not in include_list:
410 print("excluding schema: " + filename)
411 os.remove(filename)