blob: b57d7c47fde01ee416cbf305b16a8a6a67ff99fb [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
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000042INCLUDE_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
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000046PROXIES = {"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)
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000051 dmtf = requests.get(url, proxies=PROXIES)
James Feiste51c7102020-03-17 10:38:18 -070052 dmtf.raise_for_status()
Ed Tanous42079ec2024-11-16 13:32:29 -080053 json_file = json.loads(dmtf.text, object_pairs_hook=OrderedDict)
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000054 path = os.path.join(INCLUDE_PATH, header_name)
James Feiste51c7102020-03-17 10:38:18 -070055 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",
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000070 ) as json_file_fd:
71 json_file = json.load(json_file_fd)
Ed Tanous3e5faba2023-08-16 15:11:29 -070072
Igor Kanyuka557ab0d2025-02-18 15:20:38 +000073 path = os.path.join(INCLUDE_PATH, "openbmc_message_registry.hpp")
Ed Tanous3e5faba2023-08-16 15:11:29 -070074 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
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000199def get_response_code(entry_id):
Ed Tanous7ccfe682024-11-16 14:36:16 -0800200 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
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000240 return codes.get(entry_id, "bad_request")
Ed Tanous7ccfe682024-11-16 14:36:16 -0800241
242
Ed Tanousf175c282024-12-02 15:12:50 -0800243def make_error_function(
244 entry_id, entry, is_header, registry_name, namespace_name
245):
Ed Tanous644cdcb2024-11-17 11:12:41 -0800246 arg_nonstring_types = {
247 "const boost::urls::url_view_base&": {
248 "AccessDenied": [1],
249 "CouldNotEstablishConnection": [1],
250 "GenerateSecretKeyRequired": [1],
251 "InvalidObject": [1],
252 "PasswordChangeRequired": [1],
253 "PropertyValueResourceConflict": [3],
254 "ResetRequired": [1],
255 "ResourceAtUriInUnknownFormat": [1],
256 "ResourceAtUriUnauthorized": [1],
257 "ResourceCreationConflict": [1],
258 "ResourceMissingAtURI": [1],
259 "SourceDoesNotSupportProtocol": [1],
260 },
261 "const nlohmann::json&": {
262 "ActionParameterValueError": [1],
263 "ActionParameterValueFormatError": [1],
264 "ActionParameterValueTypeError": [1],
265 "PropertyValueExternalConflict": [2],
266 "PropertyValueFormatError": [1],
267 "PropertyValueIncorrect": [2],
268 "PropertyValueModified": [2],
269 "PropertyValueNotInList": [1],
270 "PropertyValueOutOfRange": [1],
271 "PropertyValueResourceConflict": [2],
272 "PropertyValueTypeError": [1],
273 "QueryParameterValueFormatError": [1],
274 "QueryParameterValueTypeError": [1],
275 },
276 "uint64_t": {
277 "ArraySizeTooLong": [2],
278 "InvalidIndex": [1],
279 "StringValueTooLong": [2],
Ed Tanousf175c282024-12-02 15:12:50 -0800280 "TaskProgressChanged": [2],
Ed Tanous644cdcb2024-11-17 11:12:41 -0800281 },
Ed Tanous42079ec2024-11-16 13:32:29 -0800282 }
283
Ed Tanous7ccfe682024-11-16 14:36:16 -0800284 out = ""
285 args = []
286 argtypes = []
287 for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
288 arg_index += 1
Ed Tanous644cdcb2024-11-17 11:12:41 -0800289 typename = "std::string_view"
290 for typestring, entries in arg_nonstring_types.items():
291 if arg_index in entries.get(entry_id, []):
292 typename = typestring
293
Ed Tanous7ccfe682024-11-16 14:36:16 -0800294 argtypes.append(typename)
295 args.append(f"{typename} arg{arg_index}")
296 function_name = entry_id[0].lower() + entry_id[1:]
297 arg = ", ".join(args)
298 out += f"nlohmann::json {function_name}({arg})"
299
300 if is_header:
301 out += ";\n\n"
302 else:
303 out += "\n{\n"
304 to_array_type = ""
305 if argtypes:
306 outargs = []
307 for index, typename in enumerate(argtypes):
308 index += 1
309 if typename == "const nlohmann::json&":
310 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 -0800311 elif typename == "uint64_t":
Ed Tanous7ccfe682024-11-16 14:36:16 -0800312 out += f"std::string arg{index}Str = std::to_string(arg{index});\n"
313
314 for index, typename in enumerate(argtypes):
315 index += 1
316 if typename == "const boost::urls::url_view_base&":
317 outargs.append(f"arg{index}.buffer()")
318 to_array_type = "<std::string_view>"
319 elif typename == "const nlohmann::json&":
320 outargs.append(f"arg{index}Str")
321 to_array_type = "<std::string_view>"
Ed Tanous644cdcb2024-11-17 11:12:41 -0800322 elif typename == "uint64_t":
Ed Tanous7ccfe682024-11-16 14:36:16 -0800323 outargs.append(f"arg{index}Str")
324 to_array_type = "<std::string_view>"
325 else:
326 outargs.append(f"arg{index}")
327 argstring = ", ".join(outargs)
Ed Tanous7ccfe682024-11-16 14:36:16 -0800328
329 if argtypes:
330 arg_param = f"std::to_array{to_array_type}({{{argstring}}})"
331 else:
332 arg_param = "{}"
Ed Tanousf175c282024-12-02 15:12:50 -0800333 out += f" return getLog(redfish::registries::{namespace_name}::Index::{function_name}, {arg_param});"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800334 out += "\n}\n\n"
Ed Tanousf175c282024-12-02 15:12:50 -0800335 if registry_name == "Base":
336 args.insert(0, "crow::Response& res")
Ed Tanous7ccfe682024-11-16 14:36:16 -0800337 if entry_id == "InternalError":
Ed Tanousf175c282024-12-02 15:12:50 -0800338 if is_header:
339 args.append(
340 "std::source_location location = std::source_location::current()"
341 )
342 else:
343 args.append("const std::source_location location")
344 arg = ", ".join(args)
345 out += f"void {function_name}({arg})"
346 if is_header:
347 out += ";\n"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800348 else:
Ed Tanousf175c282024-12-02 15:12:50 -0800349 out += "\n{\n"
350 if entry_id == "InternalError":
351 out += """BMCWEB_LOG_CRITICAL("Internal Error {}({}:{}) `{}`: ", location.file_name(),
352 location.line(), location.column(),
353 location.function_name());\n"""
354
355 if entry_id == "ServiceTemporarilyUnavailable":
356 out += "res.addHeader(boost::beast::http::field::retry_after, arg1);"
357
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000358 res = get_response_code(entry_id)
Ed Tanousf175c282024-12-02 15:12:50 -0800359 if res:
360 out += f" res.result(boost::beast::http::status::{res});\n"
361 args_out = ", ".join([f"arg{x+1}" for x in range(len(argtypes))])
362
363 addMessageToJson = {
364 "PropertyDuplicate": 1,
365 "ResourceAlreadyExists": 2,
366 "CreateFailedMissingReqProperties": 1,
367 "PropertyValueFormatError": 2,
368 "PropertyValueNotInList": 2,
369 "PropertyValueTypeError": 2,
370 "PropertyValueError": 1,
371 "PropertyNotWritable": 1,
372 "PropertyValueModified": 1,
373 "PropertyMissing": 1,
374 }
375
376 addMessageToRoot = [
377 "SessionTerminated",
378 "SubscriptionTerminated",
379 "AccountRemoved",
380 "Created",
381 "Success",
382 "PasswordChangeRequired",
383 ]
384
385 if entry_id in addMessageToJson:
386 out += f" addMessageToJson(res.jsonValue, {function_name}({args_out}), arg{addMessageToJson[entry_id]});\n"
387 elif entry_id in addMessageToRoot:
388 out += f" addMessageToJsonRoot(res.jsonValue, {function_name}({args_out}));\n"
389 else:
390 out += f" addMessageToErrorJson(res.jsonValue, {function_name}({args_out}));\n"
391 out += "}\n"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800392 out += "\n"
393 return out
394
395
Ed Tanousf175c282024-12-02 15:12:50 -0800396def create_error_registry(
397 entry, registry_version, registry_name, namespace_name, filename
398):
Ed Tanous42079ec2024-11-16 13:32:29 -0800399 file, json_dict, namespace, url = entry
Ed Tanousf175c282024-12-02 15:12:50 -0800400 base_filename = filename + "_messages"
Ed Tanous42079ec2024-11-16 13:32:29 -0800401
Ed Tanous42079ec2024-11-16 13:32:29 -0800402 error_messages_hpp = os.path.join(
Ed Tanousf175c282024-12-02 15:12:50 -0800403 SCRIPT_DIR, "..", "redfish-core", "include", f"{base_filename}.hpp"
Ed Tanous42079ec2024-11-16 13:32:29 -0800404 )
Ed Tanousf8cca872024-11-16 22:47:34 -0800405 messages = json_dict["Messages"]
406
Ed Tanous42079ec2024-11-16 13:32:29 -0800407 with open(
408 error_messages_hpp,
409 "w",
410 ) as out:
411 out.write(PRAGMA_ONCE)
412 out.write(WARNING)
413 out.write(
414 """
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800415// These generated headers are a superset of what is needed.
416// clang sees them as an error, so ignore
417// NOLINTBEGIN(misc-include-cleaner)
Ed Tanous42079ec2024-11-16 13:32:29 -0800418#include "http_response.hpp"
419
420#include <boost/url/url_view_base.hpp>
421#include <nlohmann/json.hpp>
422
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800423#include <cstdint>
Ed Tanous42079ec2024-11-16 13:32:29 -0800424#include <source_location>
Ed Tanous42079ec2024-11-16 13:32:29 -0800425#include <string_view>
Ed Tanous4aad6ed2025-01-30 09:35:06 -0800426// NOLINTEND(misc-include-cleaner)
Ed Tanous42079ec2024-11-16 13:32:29 -0800427
428namespace redfish
429{
430
431namespace messages
432{
Ed Tanous42079ec2024-11-16 13:32:29 -0800433"""
434 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800435 for entry_id, entry in messages.items():
436 message = entry["Message"]
437 for index in range(1, 10):
438 message = message.replace(f"'%{index}'", f"<arg{index}>")
439 message = message.replace(f"%{index}", f"<arg{index}>")
440
Ed Tanousf175c282024-12-02 15:12:50 -0800441 if registry_name == "Base":
442 out.write("/**\n")
443 out.write(f"* @brief Formats {entry_id} message into JSON\n")
444 out.write(f'* Message body: "{message}"\n')
445 out.write("*\n")
446 arg_index = 0
447 for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
448 arg_index += 1
Ed Tanous42079ec2024-11-16 13:32:29 -0800449
Ed Tanousf175c282024-12-02 15:12:50 -0800450 out.write(
451 f"* @param[in] arg{arg_index} Parameter of message that will replace %{arg_index} in its body.\n"
452 )
453 out.write("*\n")
Ed Tanous42079ec2024-11-16 13:32:29 -0800454 out.write(
Ed Tanousf175c282024-12-02 15:12:50 -0800455 f"* @returns Message {entry_id} formatted to JSON */\n"
Ed Tanous42079ec2024-11-16 13:32:29 -0800456 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800457
Ed Tanousf175c282024-12-02 15:12:50 -0800458 out.write(
459 make_error_function(
460 entry_id, entry, True, registry_name, namespace_name
461 )
462 )
Ed Tanous42079ec2024-11-16 13:32:29 -0800463 out.write(" }\n")
464 out.write("}\n")
Ed Tanous7ccfe682024-11-16 14:36:16 -0800465
466 error_messages_cpp = os.path.join(
Ed Tanousf175c282024-12-02 15:12:50 -0800467 SCRIPT_DIR, "..", "redfish-core", "src", f"{base_filename}.cpp"
Ed Tanous7ccfe682024-11-16 14:36:16 -0800468 )
469 with open(
470 error_messages_cpp,
471 "w",
472 ) as out:
473 out.write(WARNING)
Ed Tanousf175c282024-12-02 15:12:50 -0800474 out.write(f'\n#include "{base_filename}.hpp"\n')
Ed Tanous847deee2024-12-02 15:28:10 -0800475 headers = []
Ed Tanous7ccfe682024-11-16 14:36:16 -0800476
Ed Tanous847deee2024-12-02 15:28:10 -0800477 headers.append('"registries.hpp"')
Ed Tanousf175c282024-12-02 15:12:50 -0800478 if registry_name == "Base":
479 reg_name_lower = "base"
Ed Tanous6c038f22025-01-14 09:46:04 -0800480 headers.append('"error_message_utils.hpp"')
Ed Tanous847deee2024-12-02 15:28:10 -0800481 headers.append('"http_response.hpp"')
482 headers.append('"logging.hpp"')
483 headers.append("<boost/beast/http/field.hpp>")
484 headers.append("<boost/beast/http/status.hpp>")
485 headers.append("<boost/url/url_view_base.hpp>")
486 headers.append("<source_location>")
Ed Tanousf175c282024-12-02 15:12:50 -0800487 else:
488 reg_name_lower = namespace_name.lower()
Ed Tanous847deee2024-12-02 15:28:10 -0800489 headers.append(f'"registries/{reg_name_lower}_message_registry.hpp"')
Ed Tanous7ccfe682024-11-16 14:36:16 -0800490
Ed Tanous847deee2024-12-02 15:28:10 -0800491 headers.append("<nlohmann/json.hpp>")
492 headers.append("<array>")
493 headers.append("<cstddef>")
494 headers.append("<span>")
495
Ed Tanousa8a5bc12024-12-02 15:43:16 -0800496 if registry_name not in ("ResourceEvent", "HeartbeatEvent"):
Ed Tanous847deee2024-12-02 15:28:10 -0800497 headers.append("<cstdint>")
498 headers.append("<string>")
499 headers.append("<string_view>")
500
501 for header in headers:
502 out.write(f"#include {header}\n")
503
Ed Tanousf175c282024-12-02 15:12:50 -0800504 out.write(
505 """
Ed Tanous7ccfe682024-11-16 14:36:16 -0800506// Clang can't seem to decide whether this header needs to be included or not,
507// and is inconsistent. Include it for now
508// NOLINTNEXTLINE(misc-include-cleaner)
509#include <utility>
510
511namespace redfish
512{
513
514namespace messages
515{
Ed Tanousf175c282024-12-02 15:12:50 -0800516"""
517 )
Ed Tanousf175c282024-12-02 15:12:50 -0800518 out.write(
519 """
520static nlohmann::json getLog(redfish::registries::{namespace_name}::Index name,
521 std::span<const std::string_view> args)
522{{
523 size_t index = static_cast<size_t>(name);
524 if (index >= redfish::registries::{namespace_name}::registry.size())
525 {{
526 return {{}};
527 }}
528 return getLogFromRegistry(redfish::registries::{namespace_name}::header,
529 redfish::registries::{namespace_name}::registry, index, args);
530}}
531
532""".format(
533 namespace_name=namespace_name
534 )
Ed Tanous7ccfe682024-11-16 14:36:16 -0800535 )
536 for entry_id, entry in messages.items():
537 out.write(
538 f"""/**
539 * @internal
540 * @brief Formats {entry_id} message into JSON
541 *
542 * See header file for more information
543 * @endinternal
544 */
545"""
546 )
547 message = entry["Message"]
Ed Tanousf175c282024-12-02 15:12:50 -0800548 out.write(
549 make_error_function(
550 entry_id, entry, False, registry_name, namespace_name
551 )
552 )
Ed Tanous7ccfe682024-11-16 14:36:16 -0800553
554 out.write(" }\n")
555 out.write("}\n")
556 os.system(f"clang-format -i {error_messages_hpp} {error_messages_cpp}")
Ed Tanous42079ec2024-11-16 13:32:29 -0800557
558
Ed Tanoused398212021-06-09 17:05:54 -0700559def make_privilege_registry():
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600560 path, json_file, type_name, url = make_getter(
Gunnar Mills5910d942024-04-16 12:07:17 -0500561 "Redfish_1.5.0_PrivilegeRegistry.json",
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600562 "privilege_registry.hpp",
563 "privilege",
564 )
565 with open(path, "w") as registry:
Nan Zhou043bec02022-09-20 18:12:13 +0000566 registry.write(PRIVILEGE_HEADER)
Ed Tanoused398212021-06-09 17:05:54 -0700567
568 privilege_dict = {}
569 for mapping in json_file["Mappings"]:
570 # first pass, identify all the unique privilege sets
571 for operation, privilege_list in mapping["OperationMap"].items():
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600572 privilege_dict[
573 get_privilege_string_from_list(privilege_list)
574 ] = (privilege_list,)
Ed Tanoused398212021-06-09 17:05:54 -0700575 for index, key in enumerate(privilege_dict):
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600576 (privilege_list,) = privilege_dict[key]
Ed Tanoused398212021-06-09 17:05:54 -0700577 name = get_variable_name_for_privilege_set(privilege_list)
Ed Tanousf395daa2021-08-02 08:56:24 -0700578 registry.write(
Ed Tanous5b9ef702022-02-17 12:19:32 -0800579 "const std::array<Privileges, {length}> "
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600580 "privilegeSet{name} = {key};\n".format(
581 length=len(privilege_list), name=name, key=key
582 )
Ed Tanous5b9ef702022-02-17 12:19:32 -0800583 )
Ed Tanoused398212021-06-09 17:05:54 -0700584 privilege_dict[key] = (privilege_list, name)
Ed Tanoused398212021-06-09 17:05:54 -0700585
586 for mapping in json_file["Mappings"]:
587 entity = mapping["Entity"]
Ed Tanous4d99bbb2022-02-17 10:02:57 -0800588 registry.write("// {}\n".format(entity))
Ed Tanoused398212021-06-09 17:05:54 -0700589 for operation, privilege_list in mapping["OperationMap"].items():
590 privilege_string = get_privilege_string_from_list(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600591 privilege_list
592 )
Ed Tanoused398212021-06-09 17:05:54 -0700593 operation = operation.lower()
594
Ed Tanousf395daa2021-08-02 08:56:24 -0700595 registry.write(
596 "const static auto& {}{} = privilegeSet{};\n".format(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600597 operation, entity, privilege_dict[privilege_string][1]
598 )
599 )
Ed Tanoused398212021-06-09 17:05:54 -0700600 registry.write("\n")
Ed Tanous5b9ef702022-02-17 12:19:32 -0800601 registry.write(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600602 "} // namespace redfish::privileges\n// clang-format on\n"
603 )
Ed Tanoused398212021-06-09 17:05:54 -0700604
605
Gunnar Mills665e7602024-04-10 13:14:41 -0500606def to_pascal_case(text):
607 s = text.replace("_", " ")
608 s = s.split()
609 if len(text) == 0:
610 return text
611 return "".join(i.capitalize() for i in s[0:])
612
613
Nan Zhou49aa131f2022-09-20 18:41:37 +0000614def main():
Ed Tanousc8895b02025-01-03 11:44:08 -0800615 dmtf_registries = OrderedDict(
616 [
617 ("base", "1.19.0"),
618 ("composition", "1.1.2"),
Igor Kanyuka0bce6a92025-02-21 12:40:12 +0000619 ("environmental", "1.1.0"),
Ed Tanousc8895b02025-01-03 11:44:08 -0800620 ("ethernet_fabric", "1.0.1"),
621 ("fabric", "1.0.2"),
622 ("heartbeat_event", "1.0.1"),
623 ("job_event", "1.0.1"),
624 ("license", "1.0.3"),
625 ("log_service", "1.0.1"),
626 ("network_device", "1.0.3"),
627 ("platform", "1.0.1"),
628 ("power", "1.0.1"),
629 ("resource_event", "1.3.0"),
630 ("sensor_event", "1.0.1"),
631 ("storage_device", "1.2.1"),
632 ("task_event", "1.0.3"),
633 ("telemetry", "1.0.0"),
634 ("update", "1.0.2"),
635 ]
636 )
Gunnar Mills665e7602024-04-10 13:14:41 -0500637
Nan Zhou49aa131f2022-09-20 18:41:37 +0000638 parser = argparse.ArgumentParser()
639 parser.add_argument(
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600640 "--registries",
641 type=str,
Gunnar Mills665e7602024-04-10 13:14:41 -0500642 default="privilege,openbmc,"
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700643 + ",".join([dmtf for dmtf in dmtf_registries]),
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600644 help="Comma delimited list of registries to update",
645 )
Nan Zhou49aa131f2022-09-20 18:41:37 +0000646
647 args = parser.parse_args()
648
649 registries = set(args.registries.split(","))
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700650 registries_map = OrderedDict()
Nan Zhou49aa131f2022-09-20 18:41:37 +0000651
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700652 for registry, version in dmtf_registries.items():
Gunnar Mills665e7602024-04-10 13:14:41 -0500653 if registry in registries:
654 registry_pascal_case = to_pascal_case(registry)
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000655 registries_map[registry] = make_getter(
656 f"{registry_pascal_case}.{version}.json",
657 f"{registry}_message_registry.hpp",
658 registry,
Patrick Williamsdfa3fdc2022-12-07 07:14:21 -0600659 )
Ed Tanous3e5faba2023-08-16 15:11:29 -0700660 if "openbmc" in registries:
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000661 registries_map["openbmc"] = openbmc_local_getter()
Nan Zhou49aa131f2022-09-20 18:41:37 +0000662
Igor Kanyuka557ab0d2025-02-18 15:20:38 +0000663 update_registries(registries_map.values())
Nan Zhou49aa131f2022-09-20 18:41:37 +0000664
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700665 if "base" in registries_map:
666 create_error_registry(
Ed Tanousc8895b02025-01-03 11:44:08 -0800667 registries_map["base"],
668 dmtf_registries["base"],
669 "Base",
670 "base",
671 "error",
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700672 )
673 if "heartbeat_event" in registries_map:
674 create_error_registry(
675 registries_map["heartbeat_event"],
676 dmtf_registries["heartbeat_event"],
677 "HeartbeatEvent",
678 "heartbeat_event",
679 "heartbeat",
680 )
681 if "resource_event" in registries_map:
682 create_error_registry(
683 registries_map["resource_event"],
684 dmtf_registries["resource_event"],
685 "ResourceEvent",
686 "resource_event",
687 "resource",
688 )
689 if "task_event" in registries_map:
690 create_error_registry(
Ed Tanousc8895b02025-01-03 11:44:08 -0800691 registries_map["task_event"],
692 dmtf_registries["task_event"],
693 "TaskEvent",
694 "task_event",
695 "task",
Tam Nguyen7e6d0322024-12-27 09:47:38 +0700696 )
697
Nan Zhou49aa131f2022-09-20 18:41:37 +0000698 if "privilege" in registries:
699 make_privilege_registry()
700
701
702if __name__ == "__main__":
703 main()