blob: 70d0fec20f7c6fe68dd31c24c411edc91a1b0c3f [file] [log] [blame]
#!/usr/bin/env python3
import argparse
import json
import os
import requests
PRAGMA_ONCE = """#pragma once
"""
WARNING = """/****************************************************************
* READ THIS WARNING FIRST
* This is an auto-generated header which contains definitions
* for Redfish DMTF defined messages.
* DO NOT modify this registry outside of running the
* parse_registries.py script. The definitions contained within
* this file are owned by DMTF. Any modifications to these files
* should be first pushed to the relevant registry in the DMTF
* github organization.
***************************************************************/"""
REGISTRY_HEADER = (
PRAGMA_ONCE
+ WARNING
+ """
#include "registries.hpp"
#include <array>
// clang-format off
namespace redfish::registries::{}
{{
"""
)
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
include_path = os.path.realpath(
os.path.join(SCRIPT_DIR, "..", "redfish-core", "include", "registries")
)
proxies = {"https": os.environ.get("https_proxy", None)}
def make_getter(dmtf_name, header_name, type_name):
url = "https://redfish.dmtf.org/registries/{}".format(dmtf_name)
dmtf = requests.get(url, proxies=proxies)
dmtf.raise_for_status()
json_file = json.loads(dmtf.text)
path = os.path.join(include_path, header_name)
return (path, json_file, type_name, url)
def openbmc_local_getter():
url = ""
with open(
os.path.join(
SCRIPT_DIR,
"..",
"redfish-core",
"include",
"registries",
"openbmc.json",
),
"rb",
) as json_file:
json_file = json.load(json_file)
path = os.path.join(include_path, "openbmc_message_registry.hpp")
return (path, json_file, "openbmc", url)
def update_registries(files):
# Remove the old files
for file, json_dict, namespace, url in files:
try:
os.remove(file)
except BaseException:
print("{} not found".format(file))
with open(file, "w") as registry:
registry.write(REGISTRY_HEADER.format(namespace))
# Parse the Registry header info
registry.write(
"const Header header = {{\n"
' "{json_dict[@Redfish.Copyright]}",\n'
' "{json_dict[@odata.type]}",\n'
' "{json_dict[Id]}",\n'
' "{json_dict[Name]}",\n'
' "{json_dict[Language]}",\n'
' "{json_dict[Description]}",\n'
' "{json_dict[RegistryPrefix]}",\n'
' "{json_dict[RegistryVersion]}",\n'
' "{json_dict[OwningEntity]}",\n'
"}};\n"
"constexpr const char* url =\n"
' "{url}";\n'
"\n"
"constexpr std::array registry =\n"
"{{\n".format(
json_dict=json_dict,
url=url,
)
)
messages_sorted = sorted(json_dict["Messages"].items())
for messageId, message in messages_sorted:
registry.write(
" MessageEntry{{\n"
' "{messageId}",\n'
" {{\n"
' "{message[Description]}",\n'
' "{message[Message]}",\n'
' "{message[MessageSeverity]}",\n'
" {message[NumberOfArgs]},\n"
" {{".format(
messageId=messageId, message=message
)
)
paramTypes = message.get("ParamTypes")
if paramTypes:
for paramType in paramTypes:
registry.write(
'\n "{}",'.format(paramType)
)
registry.write("\n },\n")
else:
registry.write("},\n")
registry.write(
' "{message[Resolution]}",\n'
" }}}},\n".format(message=message)
)
registry.write("\n};\n\nenum class Index\n{\n")
for index, (messageId, message) in enumerate(messages_sorted):
messageId = messageId[0].lower() + messageId[1:]
registry.write(" {} = {},\n".format(messageId, index))
registry.write(
"}};\n}} // namespace redfish::registries::{}\n".format(
namespace
)
)
def get_privilege_string_from_list(privilege_list):
privilege_string = "{{\n"
for privilege_json in privilege_list:
privileges = privilege_json["Privilege"]
privilege_string += " {"
for privilege in privileges:
if privilege == "NoAuth":
continue
privilege_string += '"'
privilege_string += privilege
privilege_string += '",\n'
if privilege != "NoAuth":
privilege_string = privilege_string[:-2]
privilege_string += "}"
privilege_string += ",\n"
privilege_string = privilege_string[:-2]
privilege_string += "\n}}"
return privilege_string
def get_variable_name_for_privilege_set(privilege_list):
names = []
for privilege_json in privilege_list:
privileges = privilege_json["Privilege"]
names.append("And".join(privileges))
return "Or".join(names)
PRIVILEGE_HEADER = (
PRAGMA_ONCE
+ WARNING
+ """
#include "privileges.hpp"
#include <array>
// clang-format off
namespace redfish::privileges
{
"""
)
def make_privilege_registry():
path, json_file, type_name, url = make_getter(
"Redfish_1.5.0_PrivilegeRegistry.json",
"privilege_registry.hpp",
"privilege",
)
with open(path, "w") as registry:
registry.write(PRIVILEGE_HEADER)
privilege_dict = {}
for mapping in json_file["Mappings"]:
# first pass, identify all the unique privilege sets
for operation, privilege_list in mapping["OperationMap"].items():
privilege_dict[
get_privilege_string_from_list(privilege_list)
] = (privilege_list,)
for index, key in enumerate(privilege_dict):
(privilege_list,) = privilege_dict[key]
name = get_variable_name_for_privilege_set(privilege_list)
registry.write(
"const std::array<Privileges, {length}> "
"privilegeSet{name} = {key};\n".format(
length=len(privilege_list), name=name, key=key
)
)
privilege_dict[key] = (privilege_list, name)
for mapping in json_file["Mappings"]:
entity = mapping["Entity"]
registry.write("// {}\n".format(entity))
for operation, privilege_list in mapping["OperationMap"].items():
privilege_string = get_privilege_string_from_list(
privilege_list
)
operation = operation.lower()
registry.write(
"const static auto& {}{} = privilegeSet{};\n".format(
operation, entity, privilege_dict[privilege_string][1]
)
)
registry.write("\n")
registry.write(
"} // namespace redfish::privileges\n// clang-format on\n"
)
def to_pascal_case(text):
s = text.replace("_", " ")
s = s.split()
if len(text) == 0:
return text
return "".join(i.capitalize() for i in s[0:])
def main():
dmtf_registries = (
("base", "1.18.1"),
("composition", "1.1.2"),
("environmental", "1.0.1"),
("ethernet_fabric", "1.0.1"),
("fabric", "1.0.2"),
("heartbeat_event", "1.0.1"),
("job_event", "1.0.1"),
("license", "1.0.3"),
("log_service", "1.0.1"),
("network_device", "1.0.3"),
("platform", "1.0.1"),
("power", "1.0.1"),
("resource_event", "1.3.0"),
("sensor_event", "1.0.1"),
("storage_device", "1.2.1"),
("task_event", "1.0.3"),
("telemetry", "1.0.0"),
("update", "1.0.2"),
)
parser = argparse.ArgumentParser()
parser.add_argument(
"--registries",
type=str,
default="privilege,openbmc,"
+ ",".join([dmtf[0] for dmtf in dmtf_registries]),
help="Comma delimited list of registries to update",
)
args = parser.parse_args()
registries = set(args.registries.split(","))
files = []
for registry, version in dmtf_registries:
if registry in registries:
registry_pascal_case = to_pascal_case(registry)
files.append(
make_getter(
f"{registry_pascal_case}.{version}.json",
f"{registry}_message_registry.hpp",
registry,
)
)
if "openbmc" in registries:
files.append(openbmc_local_getter())
update_registries(files)
if "privilege" in registries:
make_privilege_registry()
if __name__ == "__main__":
main()