1#!/usr/bin/python3 2import requests 3import zipfile 4from io import BytesIO 5import os 6from collections import defaultdict 7from collections import OrderedDict 8from distutils.version import StrictVersion 9import shutil 10import json 11import glob 12import subprocess 13 14import xml.etree.ElementTree as ET 15 16REGISTRY_HEADER = ''' 17/**************************************************************** 18 * This is an auto-generated header which contains definitions 19 * for Redfish DMTF defined messages. 20 ***************************************************************/ 21#pragma once 22#include <registries.hpp> 23 24namespace redfish::message_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 52def clang_format(filename): 53 subprocess.check_call(["clang-format-12", "-i", filename]) 54 55 56files = [] 57files.append(make_getter('Base.1.10.0.json', 58 'base_message_registry.hpp', 59 'base')) 60files.append(make_getter('TaskEvent.1.0.3.json', 61 'task_event_message_registry.hpp', 62 'task_event')) 63files.append(make_getter('ResourceEvent.1.0.3.json', 64 'resource_event_message_registry.hpp', 65 'resource_event')) 66 67# Remove the old files 68for file, json_dict, namespace, url in files: 69 try: 70 os.remove(file) 71 except BaseException: 72 print("{} not found".format(file)) 73 74 with open(file, 'w') as registry: 75 registry.write(REGISTRY_HEADER.format(namespace)) 76 # Parse the Registry header info 77 registry.write("const Header header = {") 78 registry.write("\"{}\",".format(json_dict["@Redfish.Copyright"])) 79 registry.write("\"{}\",".format(json_dict["@odata.type"])) 80 registry.write("\"{}\",".format(json_dict["Id"])) 81 registry.write("\"{}\",".format(json_dict["Name"])) 82 registry.write("\"{}\",".format(json_dict["Language"])) 83 registry.write("\"{}\",".format(json_dict["Description"])) 84 registry.write("\"{}\",".format(json_dict["RegistryPrefix"])) 85 registry.write("\"{}\",".format(json_dict["RegistryVersion"])) 86 registry.write("\"{}\",".format(json_dict["OwningEntity"])) 87 registry.write("};") 88 89 registry.write('constexpr const char * url = "{}";\n\n'.format(url)) 90 # Parse each Message entry 91 registry.write( 92 "constexpr std::array<MessageEntry, {}> registry = {{".format( 93 len(json_dict["Messages"]))) 94 for messageId, message in sorted(json_dict["Messages"].items()): 95 registry.write("MessageEntry{") 96 registry.write("\"{}\",".format(messageId)) 97 registry.write("{") 98 registry.write("\"{}\",".format(message["Description"])) 99 registry.write("\"{}\",".format(message["Message"])) 100 registry.write("\"{}\",".format(message["Severity"])) 101 registry.write("\"{}\",".format(message["MessageSeverity"])) 102 registry.write("{},".format(message["NumberOfArgs"])) 103 registry.write("{") 104 paramTypes = message.get("ParamTypes") 105 if paramTypes: 106 for paramType in paramTypes: 107 registry.write("\"{}\",".format(paramType)) 108 registry.write("},") 109 registry.write("\"{}\",".format(message["Resolution"])) 110 registry.write("}},") 111 registry.write("};}\n") 112 clang_format(file) 113 114 115def get_privilege_string_from_list(privilege_list): 116 privilege_string = "{{\n" 117 for privilege_json in privilege_list: 118 privileges = privilege_json["Privilege"] 119 privilege_string += " {" 120 for privilege in privileges: 121 if privilege == "NoAuth": 122 continue 123 privilege_string += "\"" 124 privilege_string += privilege 125 privilege_string += "\",\n" 126 if privilege != "NoAuth": 127 privilege_string = privilege_string[:-2] 128 privilege_string += "}" 129 privilege_string += ",\n" 130 privilege_string = privilege_string[:-2] 131 privilege_string += "\n}}" 132 return privilege_string 133 134 135def get_variable_name_for_privilege_set(privilege_list): 136 names = [] 137 for privilege_json in privilege_list: 138 privileges = privilege_json["Privilege"] 139 names.append("And".join(privileges)) 140 return "Or".join(names) 141 142 143def make_privilege_registry(): 144 path, json_file, type_name, url = \ 145 make_getter('Redfish_1.1.0_PrivilegeRegistry.json', 146 'privilege_registry.hpp', 'privilege') 147 with open(path, 'w') as registry: 148 registry.write("#pragma once\n") 149 registry.write( 150 "//{} is generated. Do not edit directly\n".format( 151 os.path.basename(path))) 152 153 registry.write("#include <privileges.hpp>\n\n") 154 registry.write("namespace redfish::privileges{\n") 155 156 privilege_dict = {} 157 for mapping in json_file["Mappings"]: 158 # first pass, identify all the unique privilege sets 159 for operation, privilege_list in mapping["OperationMap"].items(): 160 privilege_dict[get_privilege_string_from_list( 161 privilege_list)] = (privilege_list, ) 162 registry.write("// clang-format off\n") 163 for index, key in enumerate(privilege_dict): 164 (privilege_list, ) = privilege_dict[key] 165 name = get_variable_name_for_privilege_set(privilege_list) 166 registry.write( 167 "const std::array<Privileges, {}> ".format( 168 len(privilege_list))) 169 registry.write( 170 "privilegeSet{} = {};\n".format(name, key)) 171 privilege_dict[key] = (privilege_list, name) 172 registry.write("// clang-format on\n\n") 173 174 for mapping in json_file["Mappings"]: 175 entity = mapping["Entity"] 176 registry.write("//{}\n".format(entity)) 177 for operation, privilege_list in mapping["OperationMap"].items(): 178 privilege_string = get_privilege_string_from_list( 179 privilege_list) 180 operation = operation.lower() 181 182 registry.write( 183 "const static auto& {}{} = privilegeSet{};\n".format( 184 operation, 185 entity, 186 privilege_dict[privilege_string][1])) 187 registry.write("\n") 188 registry.write("} // namespace redfish::privileges\n") 189 clang_format(path) 190 191 192make_privilege_registry() 193