blob: ea17d0427c8b0a0259b6780bb80248470a0ce2a8 [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
Gunnar Mills2ae81db2024-01-31 14:25:11 -060013VERSION = "DSP8010_2023.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
Ed Tanous683f7272018-07-26 12:47:19 -070026SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
27
Ed Tanous27747912022-09-23 12:50:08 -070028proxies = {"https": os.environ.get("https_proxy", None)}
Ed Tanous683f7272018-07-26 12:47:19 -070029
Ed Tanouscb103132019-10-08 11:34:22 -070030r = requests.get(
Ed Tanous27747912022-09-23 12:50:08 -070031 "https://www.dmtf.org/sites/default/files/standards/documents/"
32 + VERSION
33 + ".zip",
34 proxies=proxies,
35)
Ed Tanous683f7272018-07-26 12:47:19 -070036
37r.raise_for_status()
38
Ed Tanous81d523a2022-05-25 12:00:51 -070039
Ed Tanous27747912022-09-23 12:50:08 -070040static_path = os.path.realpath(
41 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1")
42)
Ed Tanous683f7272018-07-26 12:47:19 -070043
Ed Tanous81d523a2022-05-25 12:00:51 -070044
Ed Tanous27747912022-09-23 12:50:08 -070045cpp_path = os.path.realpath(
46 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include")
47)
Ed Tanous81d523a2022-05-25 12:00:51 -070048
49
Ed Tanous720c9892024-05-11 07:28:09 -070050schema_path = os.path.join(
51 SCRIPT_DIR, "..", "redfish-core", "schema", "dmtf", "csdl"
52)
53json_schema_path = os.path.join(
54 SCRIPT_DIR, "..", "redfish-core", "schema", "dmtf", "json-schema"
55)
Ed Tanous118b1c72018-09-13 13:45:51 -070056metadata_index_path = os.path.join(static_path, "$metadata", "index.xml")
Ed Tanous683f7272018-07-26 12:47:19 -070057
58zipBytesIO = BytesIO(r.content)
59zip_ref = zipfile.ZipFile(zipBytesIO)
60
Ed Tanous8b564552022-09-23 12:03:18 -070061
Ed Tanous204c3762022-12-12 09:50:09 -080062class SchemaVersion:
Patrick Williamsfd06b302022-12-12 10:39:42 -060063 """
Ed Tanous204c3762022-12-12 09:50:09 -080064 A Python class for sorting Redfish schema versions. Allows sorting Redfish
65 versions in the way humans expect, by comparing version strings as lists
66 (ie 0_2_0 comes before 0_10_0) in the way humans expect. It does case
67 insensitive schema name comparisons
Patrick Williamsfd06b302022-12-12 10:39:42 -060068 """
Ed Tanous8b564552022-09-23 12:03:18 -070069
Ed Tanous204c3762022-12-12 09:50:09 -080070 def __init__(self, key):
71 key = str.casefold(key)
Ed Tanous8b564552022-09-23 12:03:18 -070072
Ed Tanous204c3762022-12-12 09:50:09 -080073 split_tup = key.split(".")
74 self.version_pieces = [split_tup[0]]
75 if len(split_tup) < 2:
76 return
77 version = split_tup[1]
Ed Tanous8b564552022-09-23 12:03:18 -070078
Ed Tanous204c3762022-12-12 09:50:09 -080079 if version.startswith("v"):
80 version = version[1:]
81 if any(char.isdigit() for char in version):
Patrick Williamsfd06b302022-12-12 10:39:42 -060082 self.version_pieces.extend([int(x) for x in version.split("_")])
Ed Tanous8b564552022-09-23 12:03:18 -070083
Ed Tanous204c3762022-12-12 09:50:09 -080084 def __lt__(self, other):
85 return self.version_pieces < other.version_pieces
Ed Tanous8b564552022-09-23 12:03:18 -070086
87
Ed Tanous683f7272018-07-26 12:47:19 -070088# Remove the old files
Ed Tanous5b5574a2022-09-26 19:53:36 -070089skip_prefixes = ["Oem", "OpenBMC"]
Ed Tanous683f7272018-07-26 12:47:19 -070090if os.path.exists(schema_path):
Ed Tanous27747912022-09-23 12:50:08 -070091 files = [
92 os.path.join(schema_path, f)
93 for f in os.listdir(schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -070094 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -070095 ]
James Feistaee8d842018-09-10 16:07:40 -070096 for f in files:
97 os.remove(f)
Ed Tanous683f7272018-07-26 12:47:19 -070098if os.path.exists(json_schema_path):
Ed Tanous27747912022-09-23 12:50:08 -070099 files = [
100 os.path.join(json_schema_path, f)
101 for f in os.listdir(json_schema_path)
Ed Tanous5b5574a2022-09-26 19:53:36 -0700102 if not any([f.startswith(prefix) for prefix in skip_prefixes])
Ed Tanous27747912022-09-23 12:50:08 -0700103 ]
Ed Tanous118b1c72018-09-13 13:45:51 -0700104 for f in files:
Ed Tanous27747912022-09-23 12:50:08 -0700105 if os.path.isfile(f):
Ed Tanous118b1c72018-09-13 13:45:51 -0700106 os.remove(f)
107 else:
108 shutil.rmtree(f)
Ed Tanous8b564552022-09-23 12:03:18 -0700109try:
110 os.remove(metadata_index_path)
111except FileNotFoundError:
112 pass
Ed Tanous683f7272018-07-26 12:47:19 -0700113
Ed Tanous118b1c72018-09-13 13:45:51 -0700114if not os.path.exists(schema_path):
115 os.makedirs(schema_path)
116if not os.path.exists(json_schema_path):
117 os.makedirs(json_schema_path)
Ed Tanous683f7272018-07-26 12:47:19 -0700118
Ed Tanous8b564552022-09-23 12:03:18 -0700119csdl_filenames = []
120json_schema_files = defaultdict(list)
121
Ed Tanous204c3762022-12-12 09:50:09 -0800122for zip_file in zip_ref.infolist():
123 if zip_file.is_dir():
124 continue
125 if zip_file.filename.startswith("csdl/"):
126 csdl_filenames.append(os.path.basename(zip_file.filename))
127 elif zip_file.filename.startswith("json-schema/"):
128 filename = os.path.basename(zip_file.filename)
Ed Tanous8b564552022-09-23 12:03:18 -0700129 filenamesplit = filename.split(".")
Ed Tanous8b564552022-09-23 12:03:18 -0700130 json_schema_files[filenamesplit[0]].append(filename)
Ed Tanous204c3762022-12-12 09:50:09 -0800131 elif zip_file.filename.startswith("openapi/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700132 pass
Ed Tanous204c3762022-12-12 09:50:09 -0800133 elif zip_file.filename.startswith("dictionaries/"):
Ed Tanous8b564552022-09-23 12:03:18 -0700134 pass
135
136# sort the json files by version
137for key, value in json_schema_files.items():
Ed Tanous204c3762022-12-12 09:50:09 -0800138 value.sort(key=SchemaVersion, reverse=True)
Ed Tanous8b564552022-09-23 12:03:18 -0700139
140# Create a dictionary ordered by schema name
141json_schema_files = OrderedDict(
Ed Tanous204c3762022-12-12 09:50:09 -0800142 sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
Ed Tanous8b564552022-09-23 12:03:18 -0700143)
Ed Tanous720c9892024-05-11 07:28:09 -0700144for csdl_file in csdl_filenames:
145 with open(os.path.join(schema_path, csdl_file), "wb") as schema_out:
146 content = zip_ref.read(os.path.join("csdl", csdl_file))
147 content = content.replace(b"\r\n", b"\n")
148 schema_out.write(content)
Myung Bae480662d2023-10-04 07:19:38 -0700149
Ed Tanous27747912022-09-23 12:50:08 -0700150with open(metadata_index_path, "w") as metadata_index:
Ed Tanous27747912022-09-23 12:50:08 -0700151 metadata_index.write('<?xml version="1.0" encoding="UTF-8"?>\n')
Ed Tanous118b1c72018-09-13 13:45:51 -0700152 metadata_index.write(
Ed Tanousf395daa2021-08-02 08:56:24 -0700153 "<edmx:Edmx xmlns:edmx="
Ed Tanous27747912022-09-23 12:50:08 -0700154 '"http://docs.oasis-open.org/odata/ns/edmx"'
155 ' Version="4.0">\n'
156 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700157
Ed Tanous720c9892024-05-11 07:28:09 -0700158 schema_static_dir = os.path.join(
159 SCRIPT_DIR, "..", "static", "redfish", "v1", "schema"
160 )
161 for filename in sorted(os.listdir(schema_static_dir), key=SchemaVersion):
162 if not filename.endswith(".xml"):
163 continue
Ed Tanous853c0dc2022-12-21 13:21:52 -0800164
Myung Bae480662d2023-10-04 07:19:38 -0700165 metadata_index.write(
166 ' <edmx:Reference Uri="/redfish/v1/schema/' + filename + '">\n'
167 )
Ed Tanous853c0dc2022-12-21 13:21:52 -0800168
Ed Tanous720c9892024-05-11 07:28:09 -0700169 xml_root = ET.parse(
170 os.path.join(schema_static_dir, filename)
171 ).getroot()
Myung Bae480662d2023-10-04 07:19:38 -0700172 edmx = "{http://docs.oasis-open.org/odata/ns/edmx}"
173 edm = "{http://docs.oasis-open.org/odata/ns/edm}"
174 for edmx_child in xml_root:
175 if edmx_child.tag == edmx + "DataServices":
176 for data_child in edmx_child:
177 if data_child.tag == edm + "Schema":
178 namespace = data_child.attrib["Namespace"]
179 if namespace.startswith("RedfishExtensions"):
180 metadata_index.write(
181 ' <edmx:Include Namespace="'
182 + namespace
183 + '" Alias="Redfish"/>\n'
184 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700185
Myung Bae480662d2023-10-04 07:19:38 -0700186 else:
187 metadata_index.write(
188 ' <edmx:Include Namespace="'
189 + namespace
190 + '"/>\n'
191 )
192 metadata_index.write(" </edmx:Reference>\n")
Ed Tanous118b1c72018-09-13 13:45:51 -0700193
Ed Tanous27747912022-09-23 12:50:08 -0700194 metadata_index.write(
195 " <edmx:DataServices>\n"
196 " <Schema "
197 'xmlns="http://docs.oasis-open.org/odata/ns/edm" '
198 'Namespace="Service">\n'
199 ' <EntityContainer Name="Service" '
200 'Extends="ServiceRoot.v1_0_0.ServiceContainer"/>\n'
201 " </Schema>\n"
202 " </edmx:DataServices>\n"
203 )
Ed Tanous118b1c72018-09-13 13:45:51 -0700204 metadata_index.write("</edmx:Edmx>\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700205
Gunnar Mills349a2ac2021-01-20 22:29:16 -0600206
Ed Tanous8b564552022-09-23 12:03:18 -0700207for schema, version in json_schema_files.items():
208 zip_filepath = os.path.join("json-schema", version[0])
Ed Tanous118b1c72018-09-13 13:45:51 -0700209
Ed Tanous720c9892024-05-11 07:28:09 -0700210 with open(os.path.join(json_schema_path, version[0]), "wb") as schema_file:
Ed Tanous27747912022-09-23 12:50:08 -0700211 schema_file.write(zip_ref.read(zip_filepath).replace(b"\r\n", b"\n"))
Ed Tanous683f7272018-07-26 12:47:19 -0700212
Ed Tanous27747912022-09-23 12:50:08 -0700213with open(os.path.join(cpp_path, "schemas.hpp"), "w") as hpp_file:
Ed Tanous720c9892024-05-11 07:28:09 -0700214 schemas = []
215 for root, dirs, files in os.walk(
216 os.path.join(SCRIPT_DIR, "..", "static", "redfish", "v1", "schema")
217 ):
218 for csdl_file in sorted(files, key=SchemaVersion):
219 if csdl_file.endswith(".xml"):
220 schemas.append(csdl_file.replace("_v1.xml", ""))
Ed Tanous81d523a2022-05-25 12:00:51 -0700221 hpp_file.write(
222 "#pragma once\n"
223 "{WARNING}\n"
224 "// clang-format off\n"
Ed Tanous3d69fed2022-09-26 20:10:42 -0700225 "#include <array>\n"
Myung Bae3e737422024-04-17 14:33:03 -0500226 "#include <string_view>\n"
Ed Tanous81d523a2022-05-25 12:00:51 -0700227 "\n"
228 "namespace redfish\n"
229 "{{\n"
Myung Bae3e737422024-04-17 14:33:03 -0500230 " constexpr std::array<std::string_view,{SIZE}> schemas {{\n".format(
231 WARNING=WARNING,
Ed Tanous720c9892024-05-11 07:28:09 -0700232 SIZE=len(schemas),
Myung Bae3e737422024-04-17 14:33:03 -0500233 )
Ed Tanous81d523a2022-05-25 12:00:51 -0700234 )
Ed Tanous720c9892024-05-11 07:28:09 -0700235 for schema in schemas:
236 hpp_file.write(' "{}",\n'.format(schema))
Myung Bae480662d2023-10-04 07:19:38 -0700237
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600238 hpp_file.write(" };\n}\n")
Ed Tanous683f7272018-07-26 12:47:19 -0700239
240zip_ref.close()
Ed Tanous0ec8b832022-03-14 14:56:47 -0700241
242generate_schema_enums.main()
Carson Labrado9e031402022-07-08 20:56:52 +0000243generate_top_collections()