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 12 13import xml.etree.ElementTree as ET 14 15VERSION = "DSP8010_2020.2" 16 17SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) 18 19proxies = { 20 'https': os.environ.get("https_proxy", None) 21} 22 23r = requests.get( 24 'https://www.dmtf.org/sites/default/files/standards/documents/' + 25 VERSION + 26 '.zip', 27 proxies=proxies) 28 29r.raise_for_status() 30 31static_path = os.path.realpath(os.path.join(SCRIPT_DIR, "..", "static", 32 "redfish", "v1")) 33 34schema_path = os.path.join(static_path, "schema") 35json_schema_path = os.path.join(static_path, "JsonSchemas") 36metadata_index_path = os.path.join(static_path, "$metadata", "index.xml") 37 38zipBytesIO = BytesIO(r.content) 39zip_ref = zipfile.ZipFile(zipBytesIO) 40 41# Remove the old files 42if os.path.exists(schema_path): 43 files = glob.glob(os.path.join(schema_path, '[!Oem]*')) 44 for f in files: 45 os.remove(f) 46if os.path.exists(json_schema_path): 47 files = glob.glob(os.path.join(json_schema_path, '[!Oem]*')) 48 for f in files: 49 if (os.path.isfile(f)): 50 os.remove(f) 51 else: 52 shutil.rmtree(f) 53os.remove(metadata_index_path) 54 55if not os.path.exists(schema_path): 56 os.makedirs(schema_path) 57if not os.path.exists(json_schema_path): 58 os.makedirs(json_schema_path) 59 60with open(metadata_index_path, 'w') as metadata_index: 61 62 metadata_index.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 63 metadata_index.write( 64 "<edmx:Edmx xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\" Version=\"4.0\">\n") 65 66 for zip_filepath in zip_ref.namelist(): 67 if zip_filepath.startswith(VERSION + 68 '/csdl/') & (zip_filepath != VERSION + 69 "/csdl/") & (zip_filepath != VERSION + 70 "/csdl/"): 71 filename = os.path.basename(zip_filepath) 72 with open(os.path.join(schema_path, filename), 'wb') as schema_file: 73 74 metadata_index.write( 75 " <edmx:Reference Uri=\"/redfish/v1/schema/" + 76 filename + 77 "\">\n") 78 79 content = zip_ref.read(zip_filepath) 80 content = content.replace(b'\r\n', b'\n') 81 xml_root = ET.fromstring(content) 82 83 for edmx_child in xml_root: 84 85 if edmx_child.tag == "{http://docs.oasis-open.org/odata/ns/edmx}DataServices": 86 for data_child in edmx_child: 87 if data_child.tag == "{http://docs.oasis-open.org/odata/ns/edm}Schema": 88 namespace = data_child.attrib["Namespace"] 89 if namespace.startswith("RedfishExtensions"): 90 metadata_index.write( 91 " <edmx:Include Namespace=\"" + namespace + "\" Alias=\"Redfish\"/>\n") 92 93 else: 94 metadata_index.write( 95 " <edmx:Include Namespace=\"" + namespace + "\"/>\n") 96 schema_file.write(content) 97 metadata_index.write(" </edmx:Reference>\n") 98 99 metadata_index.write(""" <edmx:DataServices> 100 <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service"> 101 <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/> 102 </Schema> 103 </edmx:DataServices> 104""") 105 # TODO:Issue#32 There's a bug in the script that currently deletes this 106 # schema (because it's an OEM schema). Because it's the only five, and we 107 # don't update schemas very often, we just manually fix it. Need a 108 # permanent fix to the script. 109 metadata_index.write( 110 " <edmx:Reference Uri=\"/redfish/v1/schema/OemManager_v1.xml\">\n") 111 metadata_index.write(" <edmx:Include Namespace=\"OemManager\"/>\n") 112 metadata_index.write(" </edmx:Reference>\n") 113 114 metadata_index.write( 115 " <edmx:Reference Uri=\"/redfish/v1/schema/OemCrashdump_v1.xml\">\n") 116 metadata_index.write(" <edmx:Include Namespace=\"OemCrashdump.v1_0_0\"/>\n") 117 metadata_index.write(" </edmx:Reference>\n") 118 119 metadata_index.write( 120 " <edmx:Reference Uri=\"/redfish/v1/schema/OemComputerSystem_v1.xml\">\n") 121 metadata_index.write(" <edmx:Include Namespace=\"OemComputerSystem\"/>\n") 122 metadata_index.write(" </edmx:Reference>\n") 123 124 metadata_index.write( 125 " <edmx:Reference Uri=\"/redfish/v1/schema/OemVirtualMedia_v1.xml\">\n") 126 metadata_index.write(" <edmx:Include Namespace=\"OemVirtualMedia\"/>\n") 127 metadata_index.write(" <edmx:Include Namespace=\"OemVirtualMedia.v1_0_0\"/>\n") 128 metadata_index.write(" </edmx:Reference>\n") 129 130 metadata_index.write( 131 " <edmx:Reference Uri=\"/redfish/v1/schema/OemAccountService_v1.xml\">\n") 132 metadata_index.write(" <edmx:Include Namespace=\"OemAccountService\"/>\n") 133 metadata_index.write(" <edmx:Include Namespace=\"OemAccountService.v1_0_0\"/>\n") 134 metadata_index.write(" </edmx:Reference>\n") 135 136 metadata_index.write( 137 " <edmx:Reference Uri=\"/redfish/v1/schema/OemLogService_v1.xml\">\n") 138 metadata_index.write(" <edmx:Include Namespace=\"OemLogService\"/>\n") 139 metadata_index.write(" <edmx:Include Namespace=\"OemLogService.v1_0_0\"/>\n") 140 metadata_index.write(" </edmx:Reference>\n") 141 142 metadata_index.write( 143 " <edmx:Reference Uri=\"/redfish/v1/schema/OemLogEntry_v1.xml\">\n") 144 metadata_index.write(" <edmx:Include Namespace=\"OemLogEntry\"/>\n") 145 metadata_index.write(" <edmx:Include Namespace=\"OemLogEntry.v1_0_0\"/>\n") 146 metadata_index.write(" </edmx:Reference>\n") 147 148 metadata_index.write( 149 " <edmx:Reference Uri=\"/redfish/v1/schema/OemSession_v1.xml\">\n") 150 metadata_index.write(" <edmx:Include Namespace=\"OemSession\"/>\n") 151 metadata_index.write(" <edmx:Include Namespace=\"OemSession.v1_0_0\"/>\n") 152 metadata_index.write(" </edmx:Reference>\n") 153 154 metadata_index.write("</edmx:Edmx>\n") 155 156schema_files = {} 157for zip_filepath in zip_ref.namelist(): 158 if zip_filepath.startswith(os.path.join(VERSION, 'json-schema/')): 159 filename = os.path.basename(zip_filepath) 160 filenamesplit = filename.split(".") 161 if len(filenamesplit) == 3: 162 thisSchemaVersion = schema_files.get(filenamesplit[0], None) 163 if thisSchemaVersion is None: 164 schema_files[filenamesplit[0]] = filenamesplit[1] 165 else: 166 # need to see if we're a newer version. 167 if list(map(int, filenamesplit[1][1:].split("_"))) > list(map( 168 int, thisSchemaVersion[1:].split("_"))): 169 schema_files[filenamesplit[0]] = filenamesplit[1] 170 171 172for schema, version in schema_files.items(): 173 basename = schema + "." + version + ".json" 174 zip_filepath = os.path.join(VERSION, "json-schema", basename) 175 schemadir = os.path.join(json_schema_path, schema) 176 os.makedirs(schemadir) 177 location_json = OrderedDict() 178 location_json["Language"] = "en" 179 location_json["PublicationUri"] = ( 180 "http://redfish.dmtf.org/schemas/v1/" + schema + ".json") 181 location_json["Uri"] = ( 182 "/redfish/v1/JsonSchemas/" + schema + "/" + schema + ".json") 183 184 index_json = OrderedDict() 185 index_json["@odata.context"] = "/redfish/v1/$metadata#JsonSchemaFile.JsonSchemaFile" 186 index_json["@odata.id"] = "/redfish/v1/JsonSchemas/" + schema 187 index_json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile" 188 index_json["Name"] = schema + " Schema File" 189 index_json["Schema"] = "#" + schema + "." + schema 190 index_json["Description"] = schema + " Schema File Location" 191 index_json["Id"] = schema 192 index_json["Languages"] = ["en"] 193 index_json["Languages@odata.count"] = 1 194 index_json["Location"] = [location_json] 195 index_json["Location@odata.count"] = 1 196 197 with open(os.path.join(schemadir, "index.json"), 'w') as schema_file: 198 json.dump(index_json, schema_file, indent=4) 199 with open(os.path.join(schemadir, schema + ".json"), 'wb') as schema_file: 200 schema_file.write(zip_ref.read(zip_filepath).replace(b'\r\n', b'\n')) 201 202with open(os.path.join(json_schema_path, "index.json"), 'w') as index_file: 203 members = [{"@odata.id": "/redfish/v1/JsonSchemas/" + schema} 204 for schema in schema_files] 205 206 members.sort(key=lambda x: x["@odata.id"]) 207 208 indexData = OrderedDict() 209 210 indexData["@odata.id"] = "/redfish/v1/JsonSchemas" 211 indexData["@odata.context"] = ("/redfish/v1/$metadata" 212 "#JsonSchemaFileCollection." 213 "JsonSchemaFileCollection") 214 indexData["@odata.type"] = ("#JsonSchemaFileCollection." 215 "JsonSchemaFileCollection") 216 indexData["Name"] = "JsonSchemaFile Collection" 217 indexData["Description"] = "Collection of JsonSchemaFiles" 218 indexData["Members@odata.count"] = len(schema_files) 219 indexData["Members"] = members 220 221 json.dump(indexData, index_file, indent=2) 222 223zip_ref.close() 224