| #!/usr/bin/env python3 |
| import requests |
| import zipfile |
| from io import BytesIO |
| import os |
| from collections import defaultdict |
| from collections import OrderedDict |
| from distutils.version import StrictVersion |
| import shutil |
| import json |
| import glob |
| import subprocess |
| |
| import xml.etree.ElementTree as ET |
| |
| 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 = WARNING + ''' |
| #pragma once |
| #include <registries.hpp> |
| |
| // 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) |
| |
| |
| files = [] |
| files.append(make_getter('Base.1.13.0.json', |
| 'base_message_registry.hpp', |
| 'base')) |
| files.append(make_getter('TaskEvent.1.0.3.json', |
| 'task_event_message_registry.hpp', |
| 'task_event')) |
| files.append(make_getter('ResourceEvent.1.0.3.json', |
| 'resource_event_message_registry.hpp', |
| 'resource_event')) |
| |
| # 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" |
| "\n" |
| "enum 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) |
| |
| |
| def make_privilege_registry(): |
| path, json_file, type_name, url = \ |
| make_getter('Redfish_1.3.0_PrivilegeRegistry.json', |
| 'privilege_registry.hpp', 'privilege') |
| with open(path, 'w') as registry: |
| registry.write( |
| "#pragma once\n" |
| "{WARNING}\n" |
| "// clang-format off\n" |
| "\n" |
| "#include <privileges.hpp>\n" |
| "\n" |
| "namespace redfish::privileges\n" |
| "{{\n" |
| .format( |
| WARNING=WARNING, |
| filename=os.path.basename(path))) |
| |
| 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") |
| |
| |
| make_privilege_registry() |