1#!/usr/bin/env python3 2import json 3import os 4 5import requests 6 7WARNING = '''/**************************************************************** 8 * READ THIS WARNING FIRST 9 * This is an auto-generated header which contains definitions 10 * for Redfish DMTF defined messages. 11 * DO NOT modify this registry outside of running the 12 * parse_registries.py script. The definitions contained within 13 * this file are owned by DMTF. Any modifications to these files 14 * should be first pushed to the relevant registry in the DMTF 15 * github organization. 16 ***************************************************************/''' 17 18REGISTRY_HEADER = WARNING + ''' 19#pragma once 20#include <registries.hpp> 21 22// clang-format off 23 24namespace redfish::registries::{} 25{{ 26''' 27 28SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) 29 30include_path = os.path.realpath( 31 os.path.join( 32 SCRIPT_DIR, 33 "..", 34 "redfish-core", 35 "include", 36 "registries")) 37 38proxies = { 39 'https': os.environ.get("https_proxy", None) 40} 41 42 43def make_getter(dmtf_name, header_name, type_name): 44 url = 'https://redfish.dmtf.org/registries/{}'.format(dmtf_name) 45 dmtf = requests.get(url, proxies=proxies) 46 dmtf.raise_for_status() 47 json_file = json.loads(dmtf.text) 48 path = os.path.join(include_path, header_name) 49 return (path, json_file, type_name, url) 50 51 52files = [] 53files.append(make_getter('Base.1.13.0.json', 54 'base_message_registry.hpp', 55 'base')) 56files.append(make_getter('TaskEvent.1.0.3.json', 57 'task_event_message_registry.hpp', 58 'task_event')) 59files.append(make_getter('ResourceEvent.1.0.3.json', 60 'resource_event_message_registry.hpp', 61 'resource_event')) 62 63# Remove the old files 64for file, json_dict, namespace, url in files: 65 try: 66 os.remove(file) 67 except BaseException: 68 print("{} not found".format(file)) 69 70 with open(file, 'w') as registry: 71 registry.write(REGISTRY_HEADER.format(namespace)) 72 # Parse the Registry header info 73 registry.write( 74 "const Header header = {{\n" 75 " \"{json_dict[@Redfish.Copyright]}\",\n" 76 " \"{json_dict[@odata.type]}\",\n" 77 " \"{json_dict[Id]}\",\n" 78 " \"{json_dict[Name]}\",\n" 79 " \"{json_dict[Language]}\",\n" 80 " \"{json_dict[Description]}\",\n" 81 " \"{json_dict[RegistryPrefix]}\",\n" 82 " \"{json_dict[RegistryVersion]}\",\n" 83 " \"{json_dict[OwningEntity]}\",\n" 84 "}};\n" 85 "constexpr const char* url =\n" 86 " \"{url}\";\n" 87 "\n" 88 "constexpr std::array registry =\n" 89 "{{\n".format( 90 json_dict=json_dict, 91 url=url, 92 )) 93 94 messages_sorted = sorted(json_dict["Messages"].items()) 95 for messageId, message in messages_sorted: 96 registry.write( 97 " MessageEntry{{\n" 98 " \"{messageId}\",\n" 99 " {{\n" 100 " \"{message[Description]}\",\n" 101 " \"{message[Message]}\",\n" 102 " \"{message[MessageSeverity]}\",\n" 103 " {message[NumberOfArgs]},\n" 104 " {{".format( 105 messageId=messageId, 106 message=message 107 )) 108 paramTypes = message.get("ParamTypes") 109 if paramTypes: 110 for paramType in paramTypes: 111 registry.write( 112 "\n" 113 " \"{}\",".format(paramType) 114 ) 115 registry.write("\n },\n") 116 else: 117 registry.write("},\n") 118 registry.write( 119 " \"{message[Resolution]}\",\n" 120 " }}}},\n".format(message=message)) 121 122 registry.write( 123 "\n};\n" 124 "\n" 125 "enum class Index\n" 126 "{\n" 127 ) 128 for index, (messageId, message) in enumerate(messages_sorted): 129 messageId = messageId[0].lower() + messageId[1:] 130 registry.write( 131 " {} = {},\n".format(messageId, index)) 132 registry.write( 133 "}};\n" 134 "}} // namespace redfish::registries::{}\n" 135 .format(namespace)) 136 137 138def get_privilege_string_from_list(privilege_list): 139 privilege_string = "{{\n" 140 for privilege_json in privilege_list: 141 privileges = privilege_json["Privilege"] 142 privilege_string += " {" 143 for privilege in privileges: 144 if privilege == "NoAuth": 145 continue 146 privilege_string += "\"" 147 privilege_string += privilege 148 privilege_string += "\",\n" 149 if privilege != "NoAuth": 150 privilege_string = privilege_string[:-2] 151 privilege_string += "}" 152 privilege_string += ",\n" 153 privilege_string = privilege_string[:-2] 154 privilege_string += "\n}}" 155 return privilege_string 156 157 158def get_variable_name_for_privilege_set(privilege_list): 159 names = [] 160 for privilege_json in privilege_list: 161 privileges = privilege_json["Privilege"] 162 names.append("And".join(privileges)) 163 return "Or".join(names) 164 165 166def make_privilege_registry(): 167 path, json_file, type_name, url = \ 168 make_getter('Redfish_1.3.0_PrivilegeRegistry.json', 169 'privilege_registry.hpp', 'privilege') 170 with open(path, 'w') as registry: 171 registry.write( 172 "#pragma once\n" 173 "{WARNING}\n" 174 "// clang-format off\n" 175 "\n" 176 "#include <privileges.hpp>\n" 177 "\n" 178 "namespace redfish::privileges\n" 179 "{{\n" 180 .format( 181 WARNING=WARNING, 182 filename=os.path.basename(path))) 183 184 privilege_dict = {} 185 for mapping in json_file["Mappings"]: 186 # first pass, identify all the unique privilege sets 187 for operation, privilege_list in mapping["OperationMap"].items(): 188 privilege_dict[get_privilege_string_from_list( 189 privilege_list)] = (privilege_list, ) 190 for index, key in enumerate(privilege_dict): 191 (privilege_list, ) = privilege_dict[key] 192 name = get_variable_name_for_privilege_set(privilege_list) 193 registry.write( 194 "const std::array<Privileges, {length}> " 195 "privilegeSet{name} = {key};\n" 196 .format(length=len(privilege_list), name=name, key=key) 197 ) 198 privilege_dict[key] = (privilege_list, name) 199 200 for mapping in json_file["Mappings"]: 201 entity = mapping["Entity"] 202 registry.write("// {}\n".format(entity)) 203 for operation, privilege_list in mapping["OperationMap"].items(): 204 privilege_string = get_privilege_string_from_list( 205 privilege_list) 206 operation = operation.lower() 207 208 registry.write( 209 "const static auto& {}{} = privilegeSet{};\n".format( 210 operation, 211 entity, 212 privilege_dict[privilege_string][1])) 213 registry.write("\n") 214 registry.write( 215 "} // namespace redfish::privileges\n" 216 "// clang-format on\n") 217 218 219make_privilege_registry() 220