blob: 9080a3e9907f5affd7c98e551d3d52524fad5515 [file] [log] [blame]
Nan Zhou313c1b72022-03-25 11:47:55 -07001#!/usr/bin/env python3
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -06002import argparse
Jason M. Bills70304cb2019-03-27 12:03:59 -07003import json
Nan Zhou6eaf0bd2022-08-07 01:18:45 +00004import os
Ed Tanous42079ec2024-11-16 13:32:29 -08005from collections import OrderedDict
Jason M. Bills70304cb2019-03-27 12:03:59 -07006
Nan Zhou6eaf0bd2022-08-07 01:18:45 +00007import requests
Jason M. Bills70304cb2019-03-27 12:03:59 -07008
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -06009PRAGMA_ONCE = """#pragma once
10"""
Nan Zhou043bec02022-09-20 18:12:13 +000011
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060012WARNING = """/****************************************************************
Ed Tanous1cf53df2022-02-17 09:09:25 -080013 * READ THIS WARNING FIRST
Jason M. Bills70304cb2019-03-27 12:03:59 -070014 * This is an auto-generated header which contains definitions
15 * for Redfish DMTF defined messages.
Ed Tanous1cf53df2022-02-17 09:09:25 -080016 * DO NOT modify this registry outside of running the
Jason M. Bills0e2d0692022-04-01 13:59:05 -070017 * parse_registries.py script. The definitions contained within
Ed Tanous1cf53df2022-02-17 09:09:25 -080018 * this file are owned by DMTF. Any modifications to these files
19 * should be first pushed to the relevant registry in the DMTF
20 * github organization.
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060021 ***************************************************************/"""
Ed Tanous1cf53df2022-02-17 09:09:25 -080022
Ed Tanous40e9b922024-09-10 13:50:16 -070023COPYRIGHT = """// SPDX-License-Identifier: Apache-2.0
24// SPDX-FileCopyrightText: Copyright OpenBMC Authors
25"""
26
27INCLUDES = """
Nan Zhou01c78a02022-09-20 18:17:20 +000028#include "registries.hpp"
29
30#include <array>
Jason M. Bills70304cb2019-03-27 12:03:59 -070031
Ed Tanous4d99bbb2022-02-17 10:02:57 -080032// clang-format off
33
Ed Tanousfffb8c12022-02-07 23:53:03 -080034namespace redfish::registries::{}
Jason M. Bills70304cb2019-03-27 12:03:59 -070035{{
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060036"""
Ed Tanous40e9b922024-09-10 13:50:16 -070037
38REGISTRY_HEADER = f"{COPYRIGHT}{PRAGMA_ONCE}{WARNING}{INCLUDES}"
Jason M. Bills70304cb2019-03-27 12:03:59 -070039
40SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
41
Jason M. Billsac706372020-02-18 11:36:47 -080042include_path = os.path.realpath(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060043 os.path.join(SCRIPT_DIR, "..", "redfish-core", "include", "registries")
44)
Jason M. Bills70304cb2019-03-27 12:03:59 -070045
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060046proxies = {"https": os.environ.get("https_proxy", None)}
Jason M. Bills70304cb2019-03-27 12:03:59 -070047
Jason M. Bills70304cb2019-03-27 12:03:59 -070048
James Feiste51c7102020-03-17 10:38:18 -070049def make_getter(dmtf_name, header_name, type_name):
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060050 url = "https://redfish.dmtf.org/registries/{}".format(dmtf_name)
James Feiste51c7102020-03-17 10:38:18 -070051 dmtf = requests.get(url, proxies=proxies)
52 dmtf.raise_for_status()
Ed Tanous42079ec2024-11-16 13:32:29 -080053 json_file = json.loads(dmtf.text, object_pairs_hook=OrderedDict)
James Feiste51c7102020-03-17 10:38:18 -070054 path = os.path.join(include_path, header_name)
55 return (path, json_file, type_name, url)
56
57
Ed Tanous3e5faba2023-08-16 15:11:29 -070058def openbmc_local_getter():
Milton D. Miller II770362f2024-12-17 05:28:27 +000059 url = "https://raw.githubusercontent.com/openbmc/bmcweb/refs/heads/master/redfish-core/include/registries/openbmc.json"
Ed Tanous3e5faba2023-08-16 15:11:29 -070060 with open(
61 os.path.join(
62 SCRIPT_DIR,
63 "..",
64 "redfish-core",
65 "include",
66 "registries",
67 "openbmc.json",
68 ),
69 "rb",
70 ) as json_file:
71 json_file = json.load(json_file)
72
73 path = os.path.join(include_path, "openbmc_message_registry.hpp")
74 return (path, json_file, "openbmc", url)
75
76
Nan Zhou49aa131f2022-09-20 18:41:37 +000077def update_registries(files):
78 # Remove the old files
79 for file, json_dict, namespace, url in files:
80 try:
81 os.remove(file)
82 except BaseException:
83 print("{} not found".format(file))
Jason M. Bills70304cb2019-03-27 12:03:59 -070084
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060085 with open(file, "w") as registry:
Ed Tanous56b81992024-12-02 10:36:37 -080086
87 version_split = json_dict["RegistryVersion"].split(".")
88
Nan Zhou49aa131f2022-09-20 18:41:37 +000089 registry.write(REGISTRY_HEADER.format(namespace))
90 # Parse the Registry header info
Ed Tanous5b9ef702022-02-17 12:19:32 -080091 registry.write(
Nan Zhou49aa131f2022-09-20 18:41:37 +000092 "const Header header = {{\n"
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060093 ' "{json_dict[@Redfish.Copyright]}",\n'
94 ' "{json_dict[@odata.type]}",\n'
Ed Tanous56b81992024-12-02 10:36:37 -080095 " {version_split[0]},\n"
96 " {version_split[1]},\n"
97 " {version_split[2]},\n"
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -060098 ' "{json_dict[Name]}",\n'
99 ' "{json_dict[Language]}",\n'
100 ' "{json_dict[Description]}",\n'
101 ' "{json_dict[RegistryPrefix]}",\n'
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600102 ' "{json_dict[OwningEntity]}",\n'
Nan Zhou49aa131f2022-09-20 18:41:37 +0000103 "}};\n"
104 "constexpr const char* url =\n"
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600105 ' "{url}";\n'
Nan Zhou49aa131f2022-09-20 18:41:37 +0000106 "\n"
107 "constexpr std::array registry =\n"
108 "{{\n".format(
109 json_dict=json_dict,
110 url=url,
Ed Tanous56b81992024-12-02 10:36:37 -0800111 version_split=version_split,
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600112 )
113 )
Ed Tanous30a3c432022-02-07 09:37:21 -0800114
Nan Zhou49aa131f2022-09-20 18:41:37 +0000115 messages_sorted = sorted(json_dict["Messages"].items())
116 for messageId, message in messages_sorted:
117 registry.write(
118 " MessageEntry{{\n"
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600119 ' "{messageId}",\n'
Nan Zhou49aa131f2022-09-20 18:41:37 +0000120 " {{\n"
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600121 ' "{message[Description]}",\n'
122 ' "{message[Message]}",\n'
123 ' "{message[MessageSeverity]}",\n'
Nan Zhou49aa131f2022-09-20 18:41:37 +0000124 " {message[NumberOfArgs]},\n"
125 " {{".format(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600126 messageId=messageId, message=message
127 )
128 )
Nan Zhou49aa131f2022-09-20 18:41:37 +0000129 paramTypes = message.get("ParamTypes")
130 if paramTypes:
131 for paramType in paramTypes:
132 registry.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600133 '\n "{}",'.format(paramType)
Nan Zhou49aa131f2022-09-20 18:41:37 +0000134 )
135 registry.write("\n },\n")
136 else:
137 registry.write("},\n")
138 registry.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600139 ' "{message[Resolution]}",\n'
140 " }}}},\n".format(message=message)
141 )
Nan Zhou49aa131f2022-09-20 18:41:37 +0000142
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600143 registry.write("\n};\n\nenum class Index\n{\n")
Nan Zhou49aa131f2022-09-20 18:41:37 +0000144 for index, (messageId, message) in enumerate(messages_sorted):
145 messageId = messageId[0].lower() + messageId[1:]
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600146 registry.write(" {} = {},\n".format(messageId, index))
Nan Zhou49aa131f2022-09-20 18:41:37 +0000147 registry.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600148 "}};\n}} // namespace redfish::registries::{}\n".format(
149 namespace
150 )
151 )
Ed Tanoused398212021-06-09 17:05:54 -0700152
153
154def get_privilege_string_from_list(privilege_list):
155 privilege_string = "{{\n"
156 for privilege_json in privilege_list:
157 privileges = privilege_json["Privilege"]
158 privilege_string += " {"
159 for privilege in privileges:
160 if privilege == "NoAuth":
161 continue
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600162 privilege_string += '"'
Ed Tanoused398212021-06-09 17:05:54 -0700163 privilege_string += privilege
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600164 privilege_string += '",\n'
Ed Tanoused398212021-06-09 17:05:54 -0700165 if privilege != "NoAuth":
166 privilege_string = privilege_string[:-2]
167 privilege_string += "}"
168 privilege_string += ",\n"
169 privilege_string = privilege_string[:-2]
170 privilege_string += "\n}}"
171 return privilege_string
172
Ed Tanousf395daa2021-08-02 08:56:24 -0700173
Ed Tanoused398212021-06-09 17:05:54 -0700174def get_variable_name_for_privilege_set(privilege_list):
175 names = []
176 for privilege_json in privilege_list:
177 privileges = privilege_json["Privilege"]
178 names.append("And".join(privileges))
179 return "Or".join(names)
180
Ed Tanousf395daa2021-08-02 08:56:24 -0700181
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600182PRIVILEGE_HEADER = (
Ed Tanous40e9b922024-09-10 13:50:16 -0700183 COPYRIGHT
184 + PRAGMA_ONCE
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600185 + WARNING
186 + """
Nan Zhou01c78a02022-09-20 18:17:20 +0000187#include "privileges.hpp"
188
189#include <array>
Nan Zhou043bec02022-09-20 18:12:13 +0000190
191// clang-format off
192
193namespace redfish::privileges
194{
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600195"""
196)
Nan Zhou043bec02022-09-20 18:12:13 +0000197
198
Ed Tanous7ccfe682024-11-16 14:36:16 -0800199def get_response_code(entry_id, entry):
200 codes = {
201 "InternalError": "internal_server_error",
202 "OperationTimeout": "internal_server_error",
203 "PropertyValueResourceConflict": "conflict",
204 "ResourceInUse": "service_unavailable",
205 "ServiceTemporarilyUnavailable": "service_unavailable",
206 "ResourceCannotBeDeleted": "method_not_allowed",
207 "PropertyValueModified": "ok",
208 "InsufficientPrivilege": "forbidden",
209 "AccountForSessionNoLongerExists": "forbidden",
210 "ServiceDisabled": "service_unavailable",
211 "ServiceInUnknownState": "service_unavailable",
212 "EventSubscriptionLimitExceeded": "service_unavailable",
213 "ResourceAtUriUnauthorized": "unauthorized",
214 "SessionTerminated": "ok",
215 "SubscriptionTerminated": "ok",
216 "PropertyNotWritable": "forbidden",
217 "MaximumErrorsExceeded": "internal_server_error",
218 "GeneralError": "internal_server_error",
219 "PreconditionFailed": "precondition_failed",
220 "OperationFailed": "bad_gateway",
221 "ServiceShuttingDown": "service_unavailable",
222 "AccountRemoved": "ok",
223 "PropertyValueExternalConflict": "conflict",
224 "InsufficientStorage": "insufficient_storage",
225 "OperationNotAllowed": "method_not_allowed",
226 "ResourceNotFound": "not_found",
227 "CouldNotEstablishConnection": "not_found",
228 "AccessDenied": "forbidden",
229 "Success": None,
230 "Created": "created",
231 "NoValidSession": "forbidden",
232 "SessionLimitExceeded": "service_unavailable",
233 "ResourceExhaustion": "service_unavailable",
234 "AccountModified": "ok",
235 "PasswordChangeRequired": None,
236 "ResourceInStandby": "service_unavailable",
237 "GenerateSecretKeyRequired": "forbidden",
238 }
239
240 code = codes.get(entry_id, "NOCODE")
241 if code != "NOCODE":
242 return code
243
244 return "bad_request"
245
246
Ed Tanousf175c282024-12-02 15:12:50 -0800247def make_error_function(
248 entry_id, entry, is_header, registry_name, namespace_name
249):
Ed Tanous644cdcb2024-11-17 11:12:41 -0800250 arg_nonstring_types = {
251 "const boost::urls::url_view_base&": {
252 "AccessDenied": [1],
253 "CouldNotEstablishConnection": [1],
254 "GenerateSecretKeyRequired": [1],
255 "InvalidObject": [1],
256 "PasswordChangeRequired": [1],
257 "PropertyValueResourceConflict": [3],
258 "ResetRequired": [1],
259 "ResourceAtUriInUnknownFormat": [1],
260 "ResourceAtUriUnauthorized": [1],
261 "ResourceCreationConflict": [1],
262 "ResourceMissingAtURI": [1],
263 "SourceDoesNotSupportProtocol": [1],
264 },
265 "const nlohmann::json&": {
266 "ActionParameterValueError": [1],
267 "ActionParameterValueFormatError": [1],
268 "ActionParameterValueTypeError": [1],
269 "PropertyValueExternalConflict": [2],
270 "PropertyValueFormatError": [1],
271 "PropertyValueIncorrect": [2],
272 "PropertyValueModified": [2],
273 "PropertyValueNotInList": [1],
274 "PropertyValueOutOfRange": [1],
275 "PropertyValueResourceConflict": [2],
276 "PropertyValueTypeError": [1],
277 "QueryParameterValueFormatError": [1],
278 "QueryParameterValueTypeError": [1],
279 },
280 "uint64_t": {
281 "ArraySizeTooLong": [2],
282 "InvalidIndex": [1],
283 "StringValueTooLong": [2],
Ed Tanousf175c282024-12-02 15:12:50 -0800284 "TaskProgressChanged": [2],
Ed Tanous644cdcb2024-11-17 11:12:41 -0800285 },
Ed Tanous42079ec2024-11-16 13:32:29 -0800286 }
287
Ed Tanous7ccfe682024-11-16 14:36:16 -0800288 out = ""
289 args = []
290 argtypes = []
291 for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
292 arg_index += 1
Ed Tanous644cdcb2024-11-17 11:12:41 -0800293 typename = "std::string_view"
294 for typestring, entries in arg_nonstring_types.items():
295 if arg_index in entries.get(entry_id, []):
296 typename = typestring
297
Ed Tanous7ccfe682024-11-16 14:36:16 -0800298 argtypes.append(typename)
299 args.append(f"{typename} arg{arg_index}")
300 function_name = entry_id[0].lower() + entry_id[1:]
301 arg = ", ".join(args)
302 out += f"nlohmann::json {function_name}({arg})"
303
304 if is_header:
305 out += ";\n\n"
306 else:
307 out += "\n{\n"
308 to_array_type = ""
309 if argtypes:
310 outargs = []
311 for index, typename in enumerate(argtypes):
312 index += 1
313 if typename == "const nlohmann::json&":
314 out += f"std::string arg{index}Str = arg{index}.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);\n"
Ed Tanous644cdcb2024-11-17 11:12:41 -0800315 elif typename == "uint64_t":
Ed Tanous7ccfe682024-11-16 14:36:16 -0800316 out += f"std::string arg{index}Str = std::to_string(arg{index});\n"
317
318 for index, typename in enumerate(argtypes):
319 index += 1
320 if typename == "const boost::urls::url_view_base&":
321 outargs.append(f"arg{index}.buffer()")
322 to_array_type = "<std::string_view>"
323 elif typename == "const nlohmann::json&":
324 outargs.append(f"arg{index}Str")
325 to_array_type = "<std::string_view>"
Ed Tanous644cdcb2024-11-17 11:12:41 -0800326 elif typename == "uint64_t":
Ed Tanous7ccfe682024-11-16 14:36:16 -0800327 outargs.append(f"arg{index}Str")
328 to_array_type = "<std::string_view>"
329 else:
330 outargs.append(f"arg{index}")
331 argstring = ", ".join(outargs)
Ed Tanous7ccfe682024-11-16 14:36:16 -0800332
333 if argtypes:
334 arg_param = f"std::to_array{to_array_type}({{{argstring}}})"
335 else:
336 arg_param = "{}"
Ed Tanousf175c282024-12-02 15:12:50 -0800337 out += f" return getLog(redfish::registries::{namespace_name}::Index::{function_name}, {arg_param});"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800338 out += "\n}\n\n"
Ed Tanousf175c282024-12-02 15:12:50 -0800339 if registry_name == "Base":
340 args.insert(0, "crow::Response& res")
Ed Tanous7ccfe682024-11-16 14:36:16 -0800341 if entry_id == "InternalError":
Ed Tanousf175c282024-12-02 15:12:50 -0800342 if is_header:
343 args.append(
344 "std::source_location location = std::source_location::current()"
345 )
346 else:
347 args.append("const std::source_location location")
348 arg = ", ".join(args)
349 out += f"void {function_name}({arg})"
350 if is_header:
351 out += ";\n"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800352 else:
Ed Tanousf175c282024-12-02 15:12:50 -0800353 out += "\n{\n"
354 if entry_id == "InternalError":
355 out += """BMCWEB_LOG_CRITICAL("Internal Error {}({}:{}) `{}`: ", location.file_name(),
356 location.line(), location.column(),
357 location.function_name());\n"""
358
359 if entry_id == "ServiceTemporarilyUnavailable":
360 out += "res.addHeader(boost::beast::http::field::retry_after, arg1);"
361
362 res = get_response_code(entry_id, entry)
363 if res:
364 out += f" res.result(boost::beast::http::status::{res});\n"
365 args_out = ", ".join([f"arg{x+1}" for x in range(len(argtypes))])
366
367 addMessageToJson = {
368 "PropertyDuplicate": 1,
369 "ResourceAlreadyExists": 2,
370 "CreateFailedMissingReqProperties": 1,
371 "PropertyValueFormatError": 2,
372 "PropertyValueNotInList": 2,
373 "PropertyValueTypeError": 2,
374 "PropertyValueError": 1,
375 "PropertyNotWritable": 1,
376 "PropertyValueModified": 1,
377 "PropertyMissing": 1,
378 }
379
380 addMessageToRoot = [
381 "SessionTerminated",
382 "SubscriptionTerminated",
383 "AccountRemoved",
384 "Created",
385 "Success",
386 "PasswordChangeRequired",
387 ]
388
389 if entry_id in addMessageToJson:
390 out += f" addMessageToJson(res.jsonValue, {function_name}({args_out}), arg{addMessageToJson[entry_id]});\n"
391 elif entry_id in addMessageToRoot:
392 out += f" addMessageToJsonRoot(res.jsonValue, {function_name}({args_out}));\n"
393 else:
394 out += f" addMessageToErrorJson(res.jsonValue, {function_name}({args_out}));\n"
395 out += "}\n"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800396 out += "\n"
397 return out
398
399
Ed Tanousf175c282024-12-02 15:12:50 -0800400def create_error_registry(
401 entry, registry_version, registry_name, namespace_name, filename
402):
Ed Tanous42079ec2024-11-16 13:32:29 -0800403 file, json_dict, namespace, url = entry
Ed Tanousf175c282024-12-02 15:12:50 -0800404 base_filename = filename + "_messages"
Ed Tanous42079ec2024-11-16 13:32:29 -0800405
Ed Tanous42079ec2024-11-16 13:32:29 -0800406 error_messages_hpp = os.path.join(
Ed Tanousf175c282024-12-02 15:12:50 -0800407 SCRIPT_DIR, "..", "redfish-core", "include", f"{base_filename}.hpp"
Ed Tanous42079ec2024-11-16 13:32:29 -0800408 )
Ed Tanousf8cca872024-11-16 22:47:34 -0800409 messages = json_dict["Messages"]
410
Ed Tanous42079ec2024-11-16 13:32:29 -0800411 with open(
412 error_messages_hpp,
413 "w",
414 ) as out:
415 out.write(PRAGMA_ONCE)
416 out.write(WARNING)
417 out.write(
418 """
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800419// These generated headers are a superset of what is needed.
420// clang sees them as an error, so ignore
421// NOLINTBEGIN(misc-include-cleaner)
Ed Tanous42079ec2024-11-16 13:32:29 -0800422#include "http_response.hpp"
423
424#include <boost/url/url_view_base.hpp>
425#include <nlohmann/json.hpp>
426
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800427#include <cstdint>
Ed Tanous42079ec2024-11-16 13:32:29 -0800428#include <source_location>
Ed Tanous42079ec2024-11-16 13:32:29 -0800429#include <string_view>
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800430// NOLINTEND(misc-include-cleaner)
Ed Tanous42079ec2024-11-16 13:32:29 -0800431
432namespace redfish
433{
434
435namespace messages
436{
Ed Tanous42079ec2024-11-16 13:32:29 -0800437"""
438 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800439 for entry_id, entry in messages.items():
440 message = entry["Message"]
441 for index in range(1, 10):
442 message = message.replace(f"'%{index}'", f"<arg{index}>")
443 message = message.replace(f"%{index}", f"<arg{index}>")
444
Ed Tanousf175c282024-12-02 15:12:50 -0800445 if registry_name == "Base":
446 out.write("/**\n")
447 out.write(f"* @brief Formats {entry_id} message into JSON\n")
448 out.write(f'* Message body: "{message}"\n')
449 out.write("*\n")
450 arg_index = 0
451 for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
452 arg_index += 1
Ed Tanous42079ec2024-11-16 13:32:29 -0800453
Ed Tanousf175c282024-12-02 15:12:50 -0800454 out.write(
455 f"* @param[in] arg{arg_index} Parameter of message that will replace %{arg_index} in its body.\n"
456 )
457 out.write("*\n")
Ed Tanous42079ec2024-11-16 13:32:29 -0800458 out.write(
Ed Tanousf175c282024-12-02 15:12:50 -0800459 f"* @returns Message {entry_id} formatted to JSON */\n"
Ed Tanous42079ec2024-11-16 13:32:29 -0800460 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800461
Ed Tanousf175c282024-12-02 15:12:50 -0800462 out.write(
463 make_error_function(
464 entry_id, entry, True, registry_name, namespace_name
465 )
466 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800467 out.write(" }\n")
468 out.write("}\n")
Ed Tanous7ccfe682024-11-16 14:36:16 -0800469
470 error_messages_cpp = os.path.join(
Ed Tanousf175c282024-12-02 15:12:50 -0800471 SCRIPT_DIR, "..", "redfish-core", "src", f"{base_filename}.cpp"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800472 )
473 with open(
474 error_messages_cpp,
475 "w",
476 ) as out:
477 out.write(WARNING)
Ed Tanousf175c282024-12-02 15:12:50 -0800478 out.write(f'\n#include "{base_filename}.hpp"\n')
Ed Tanous847deee2024-12-02 15:28:10 -0800479 headers = []
Ed Tanous7ccfe682024-11-16 14:36:16 -0800480
Ed Tanous847deee2024-12-02 15:28:10 -0800481 headers.append('"registries.hpp"')
Ed Tanousf175c282024-12-02 15:12:50 -0800482 if registry_name == "Base":
483 reg_name_lower = "base"
Ed Tanous6c038f22025-01-14 09:46:04 -0800484 headers.append('"error_message_utils.hpp"')
Ed Tanous847deee2024-12-02 15:28:10 -0800485 headers.append('"http_response.hpp"')
486 headers.append('"logging.hpp"')
487 headers.append("<boost/beast/http/field.hpp>")
488 headers.append("<boost/beast/http/status.hpp>")
489 headers.append("<boost/url/url_view_base.hpp>")
490 headers.append("<source_location>")
Ed Tanousf175c282024-12-02 15:12:50 -0800491 else:
492 reg_name_lower = namespace_name.lower()
Ed Tanous847deee2024-12-02 15:28:10 -0800493 headers.append(f'"registries/{reg_name_lower}_message_registry.hpp"')
Ed Tanous7ccfe682024-11-16 14:36:16 -0800494
Ed Tanous847deee2024-12-02 15:28:10 -0800495 headers.append("<nlohmann/json.hpp>")
496 headers.append("<array>")
497 headers.append("<cstddef>")
498 headers.append("<span>")
499
Ed Tanousa8a5bc12024-12-02 15:43:16 -0800500 if registry_name not in ("ResourceEvent", "HeartbeatEvent"):
Ed Tanous847deee2024-12-02 15:28:10 -0800501 headers.append("<cstdint>")
502 headers.append("<string>")
503 headers.append("<string_view>")
504
505 for header in headers:
506 out.write(f"#include {header}\n")
507
Ed Tanousf175c282024-12-02 15:12:50 -0800508 out.write(
509 """
Ed Tanous7ccfe682024-11-16 14:36:16 -0800510// Clang can't seem to decide whether this header needs to be included or not,
511// and is inconsistent. Include it for now
512// NOLINTNEXTLINE(misc-include-cleaner)
513#include <utility>
514
515namespace redfish
516{
517
518namespace messages
519{
Ed Tanousf175c282024-12-02 15:12:50 -0800520"""
521 )
Ed Tanousf175c282024-12-02 15:12:50 -0800522 out.write(
523 """
524static nlohmann::json getLog(redfish::registries::{namespace_name}::Index name,
525 std::span<const std::string_view> args)
526{{
527 size_t index = static_cast<size_t>(name);
528 if (index >= redfish::registries::{namespace_name}::registry.size())
529 {{
530 return {{}};
531 }}
532 return getLogFromRegistry(redfish::registries::{namespace_name}::header,
533 redfish::registries::{namespace_name}::registry, index, args);
534}}
535
536""".format(
537 namespace_name=namespace_name
538 )
Ed Tanous7ccfe682024-11-16 14:36:16 -0800539 )
540 for entry_id, entry in messages.items():
541 out.write(
542 f"""/**
543 * @internal
544 * @brief Formats {entry_id} message into JSON
545 *
546 * See header file for more information
547 * @endinternal
548 */
549"""
550 )
551 message = entry["Message"]
Ed Tanousf175c282024-12-02 15:12:50 -0800552 out.write(
553 make_error_function(
554 entry_id, entry, False, registry_name, namespace_name
555 )
556 )
Ed Tanous7ccfe682024-11-16 14:36:16 -0800557
558 out.write(" }\n")
559 out.write("}\n")
560 os.system(f"clang-format -i {error_messages_hpp} {error_messages_cpp}")
Ed Tanous42079ec2024-11-16 13:32:29 -0800561
562
Ed Tanoused398212021-06-09 17:05:54 -0700563def make_privilege_registry():
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600564 path, json_file, type_name, url = make_getter(
Gunnar Mills5910d942024-04-16 12:07:17 -0500565 "Redfish_1.5.0_PrivilegeRegistry.json",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600566 "privilege_registry.hpp",
567 "privilege",
568 )
569 with open(path, "w") as registry:
Nan Zhou043bec02022-09-20 18:12:13 +0000570 registry.write(PRIVILEGE_HEADER)
Ed Tanoused398212021-06-09 17:05:54 -0700571
572 privilege_dict = {}
573 for mapping in json_file["Mappings"]:
574 # first pass, identify all the unique privilege sets
575 for operation, privilege_list in mapping["OperationMap"].items():
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600576 privilege_dict[
577 get_privilege_string_from_list(privilege_list)
578 ] = (privilege_list,)
Ed Tanoused398212021-06-09 17:05:54 -0700579 for index, key in enumerate(privilege_dict):
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600580 (privilege_list,) = privilege_dict[key]
Ed Tanoused398212021-06-09 17:05:54 -0700581 name = get_variable_name_for_privilege_set(privilege_list)
Ed Tanousf395daa2021-08-02 08:56:24 -0700582 registry.write(
Ed Tanous5b9ef702022-02-17 12:19:32 -0800583 "const std::array<Privileges, {length}> "
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600584 "privilegeSet{name} = {key};\n".format(
585 length=len(privilege_list), name=name, key=key
586 )
Ed Tanous5b9ef702022-02-17 12:19:32 -0800587 )
Ed Tanoused398212021-06-09 17:05:54 -0700588 privilege_dict[key] = (privilege_list, name)
Ed Tanoused398212021-06-09 17:05:54 -0700589
590 for mapping in json_file["Mappings"]:
591 entity = mapping["Entity"]
Ed Tanous4d99bbb2022-02-17 10:02:57 -0800592 registry.write("// {}\n".format(entity))
Ed Tanoused398212021-06-09 17:05:54 -0700593 for operation, privilege_list in mapping["OperationMap"].items():
594 privilege_string = get_privilege_string_from_list(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600595 privilege_list
596 )
Ed Tanoused398212021-06-09 17:05:54 -0700597 operation = operation.lower()
598
Ed Tanousf395daa2021-08-02 08:56:24 -0700599 registry.write(
600 "const static auto& {}{} = privilegeSet{};\n".format(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600601 operation, entity, privilege_dict[privilege_string][1]
602 )
603 )
Ed Tanoused398212021-06-09 17:05:54 -0700604 registry.write("\n")
Ed Tanous5b9ef702022-02-17 12:19:32 -0800605 registry.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600606 "} // namespace redfish::privileges\n// clang-format on\n"
607 )
Ed Tanoused398212021-06-09 17:05:54 -0700608
609
Gunnar Mills665e7602024-04-10 13:14:41 -0500610def to_pascal_case(text):
611 s = text.replace("_", " ")
612 s = s.split()
613 if len(text) == 0:
614 return text
615 return "".join(i.capitalize() for i in s[0:])
616
617
Nan Zhou49aa131f2022-09-20 18:41:37 +0000618def main():
Ed Tanousc8895b02025-01-03 11:44:08 -0800619 dmtf_registries = OrderedDict(
620 [
621 ("base", "1.19.0"),
622 ("composition", "1.1.2"),
623 ("environmental", "1.0.1"),
624 ("ethernet_fabric", "1.0.1"),
625 ("fabric", "1.0.2"),
626 ("heartbeat_event", "1.0.1"),
627 ("job_event", "1.0.1"),
628 ("license", "1.0.3"),
629 ("log_service", "1.0.1"),
630 ("network_device", "1.0.3"),
631 ("platform", "1.0.1"),
632 ("power", "1.0.1"),
633 ("resource_event", "1.3.0"),
634 ("sensor_event", "1.0.1"),
635 ("storage_device", "1.2.1"),
636 ("task_event", "1.0.3"),
637 ("telemetry", "1.0.0"),
638 ("update", "1.0.2"),
639 ]
640 )
Gunnar Mills665e7602024-04-10 13:14:41 -0500641
Nan Zhou49aa131f2022-09-20 18:41:37 +0000642 parser = argparse.ArgumentParser()
643 parser.add_argument(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600644 "--registries",
645 type=str,
Gunnar Mills665e7602024-04-10 13:14:41 -0500646 default="privilege,openbmc,"
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700647 + ",".join([dmtf for dmtf in dmtf_registries]),
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600648 help="Comma delimited list of registries to update",
649 )
Nan Zhou49aa131f2022-09-20 18:41:37 +0000650
651 args = parser.parse_args()
652
653 registries = set(args.registries.split(","))
654 files = []
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700655 registries_map = OrderedDict()
Nan Zhou49aa131f2022-09-20 18:41:37 +0000656
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700657 for registry, version in dmtf_registries.items():
Gunnar Mills665e7602024-04-10 13:14:41 -0500658 if registry in registries:
659 registry_pascal_case = to_pascal_case(registry)
660 files.append(
661 make_getter(
662 f"{registry_pascal_case}.{version}.json",
663 f"{registry}_message_registry.hpp",
664 registry,
665 )
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600666 )
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700667 registries_map[registry] = files[-1]
Ed Tanous3e5faba2023-08-16 15:11:29 -0700668 if "openbmc" in registries:
669 files.append(openbmc_local_getter())
Nan Zhou49aa131f2022-09-20 18:41:37 +0000670
671 update_registries(files)
672
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700673 if "base" in registries_map:
674 create_error_registry(
Ed Tanousc8895b02025-01-03 11:44:08 -0800675 registries_map["base"],
676 dmtf_registries["base"],
677 "Base",
678 "base",
679 "error",
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700680 )
681 if "heartbeat_event" in registries_map:
682 create_error_registry(
683 registries_map["heartbeat_event"],
684 dmtf_registries["heartbeat_event"],
685 "HeartbeatEvent",
686 "heartbeat_event",
687 "heartbeat",
688 )
689 if "resource_event" in registries_map:
690 create_error_registry(
691 registries_map["resource_event"],
692 dmtf_registries["resource_event"],
693 "ResourceEvent",
694 "resource_event",
695 "resource",
696 )
697 if "task_event" in registries_map:
698 create_error_registry(
Ed Tanousc8895b02025-01-03 11:44:08 -0800699 registries_map["task_event"],
700 dmtf_registries["task_event"],
701 "TaskEvent",
702 "task_event",
703 "task",
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700704 )
705
Nan Zhou49aa131f2022-09-20 18:41:37 +0000706 if "privilege" in registries:
707 make_privilege_registry()
708
709
710if __name__ == "__main__":
711 main()