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_2019.4" 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 '/' + 69 VERSION + 70 '/csdl/') & (zip_filepath != VERSION + 71 "/csdl/") & (zip_filepath != VERSION + 72 '/' + 73 VERSION + 74 "/csdl/"): 75 filename = os.path.basename(zip_filepath) 76 with open(os.path.join(schema_path, filename), 'wb') as schema_file: 77 78 metadata_index.write( 79 " <edmx:Reference Uri=\"/redfish/v1/schema/" + 80 filename + 81 "\">\n") 82 83 content = zip_ref.read(zip_filepath) 84 content = content.replace(b'\r\n', b'\n') 85 xml_root = ET.fromstring(content) 86 87 for edmx_child in xml_root: 88 89 if edmx_child.tag == "{http://docs.oasis-open.org/odata/ns/edmx}DataServices": 90 for data_child in edmx_child: 91 if data_child.tag == "{http://docs.oasis-open.org/odata/ns/edm}Schema": 92 namespace = data_child.attrib["Namespace"] 93 if namespace.startswith("RedfishExtensions"): 94 metadata_index.write( 95 " <edmx:Include Namespace=\"" + namespace + "\" Alias=\"Redfish\"/>\n") 96 97 else: 98 metadata_index.write( 99 " <edmx:Include Namespace=\"" + namespace + "\"/>\n") 100 schema_file.write(content) 101 metadata_index.write(" </edmx:Reference>\n") 102 103 metadata_index.write(""" <edmx:DataServices> 104 <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service"> 105 <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/> 106 </Schema> 107 </edmx:DataServices> 108""") 109 # TODO:Issue#32 There's a bug in the script that currently deletes this 110 # schema (because it's an OEM schema). Because it's the only five, and we 111 # don't update schemas very often, we just manually fix it. Need a 112 # permanent fix to the script. 113 metadata_index.write( 114 " <edmx:Reference Uri=\"/redfish/v1/schema/OemManager_v1.xml\">\n") 115 metadata_index.write(" <edmx:Include Namespace=\"OemManager\"/>\n") 116 metadata_index.write(" </edmx:Reference>\n") 117 118 metadata_index.write( 119 " <edmx:Reference Uri=\"/redfish/v1/schema/OemCrashdump_v1.xml\">\n") 120 metadata_index.write(" <edmx:Include Namespace=\"OemCrashdump.v1_0_0\"/>\n") 121 metadata_index.write(" </edmx:Reference>\n") 122 123 metadata_index.write( 124 " <edmx:Reference Uri=\"/redfish/v1/schema/OemComputerSystem_v1.xml\">\n") 125 metadata_index.write(" <edmx:Include Namespace=\"OemComputerSystem\"/>\n") 126 metadata_index.write(" </edmx:Reference>\n") 127 128 metadata_index.write( 129 " <edmx:Reference Uri=\"/redfish/v1/schema/OemVirtualMedia_v1.xml\">\n") 130 metadata_index.write(" <edmx:Include Namespace=\"OemVirtualMedia\"/>\n") 131 metadata_index.write(" <edmx:Include Namespace=\"OemVirtualMedia.v1_0_0\"/>\n") 132 metadata_index.write(" </edmx:Reference>\n") 133 134 metadata_index.write( 135 " <edmx:Reference Uri=\"/redfish/v1/schema/OemAccountService_v1.xml\">\n") 136 metadata_index.write(" <edmx:Include Namespace=\"OemAccountService\"/>\n") 137 metadata_index.write(" <edmx:Include Namespace=\"OemAccountService.v1_0_0\"/>\n") 138 metadata_index.write(" </edmx:Reference>\n") 139 140 metadata_index.write("</edmx:Edmx>\n") 141 142schema_files = {} 143for zip_filepath in zip_ref.namelist(): 144 if zip_filepath.startswith(os.path.join(VERSION, VERSION, 'json-schema/')): 145 filename = os.path.basename(zip_filepath) 146 filenamesplit = filename.split(".") 147 if len(filenamesplit) == 3: 148 thisSchemaVersion = schema_files.get(filenamesplit[0], None) 149 if thisSchemaVersion is None: 150 schema_files[filenamesplit[0]] = filenamesplit[1] 151 else: 152 # need to see if we're a newer version. 153 if list(map(int, filenamesplit[1][1:].split("_"))) > list(map( 154 int, thisSchemaVersion[1:].split("_"))): 155 schema_files[filenamesplit[0]] = filenamesplit[1] 156 157 158for schema, version in schema_files.items(): 159 basename = schema + "." + version + ".json" 160 zip_filepath = os.path.join(VERSION, VERSION, "json-schema", basename) 161 schemadir = os.path.join(json_schema_path, schema) 162 os.makedirs(schemadir) 163 location_json = OrderedDict() 164 location_json["Language"] = "en" 165 location_json["PublicationUri"] = ( 166 "http://redfish.dmtf.org/schemas/v1/" + schema + ".json") 167 location_json["Uri"] = ( 168 "/redfish/v1/JsonSchemas/" + schema + "/" + schema + ".json") 169 170 index_json = OrderedDict() 171 index_json["@odata.context"] = "/redfish/v1/$metadata#JsonSchemaFile.JsonSchemaFile" 172 index_json["@odata.id"] = "/redfish/v1/JsonSchemas/" + schema 173 index_json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile" 174 index_json["Name"] = schema + " Schema File" 175 index_json["Schema"] = "#" + schema + "." + schema 176 index_json["Description"] = schema + " Schema File Location" 177 index_json["Id"] = schema 178 index_json["Languages"] = ["en"] 179 index_json["Languages@odata.count"] = 1 180 index_json["Location"] = [location_json] 181 index_json["Location@odata.count"] = 1 182 183 with open(os.path.join(schemadir, "index.json"), 'w') as schema_file: 184 json.dump(index_json, schema_file, indent=4) 185 with open(os.path.join(schemadir, schema + ".json"), 'wb') as schema_file: 186 schema_file.write(zip_ref.read(zip_filepath).replace(b'\r\n', b'\n')) 187 188with open(os.path.join(json_schema_path, "index.json"), 'w') as index_file: 189 members = [{"@odata.id": "/redfish/v1/JsonSchemas/" + schema} 190 for schema in schema_files] 191 192 members.sort(key=lambda x: x["@odata.id"]) 193 194 indexData = OrderedDict() 195 196 indexData["@odata.id"] = "/redfish/v1/JsonSchemas" 197 indexData["@odata.context"] = ("/redfish/v1/$metadata" 198 "#JsonSchemaFileCollection." 199 "JsonSchemaFileCollection") 200 indexData["@odata.type"] = ("#JsonSchemaFileCollection." 201 "JsonSchemaFileCollection") 202 indexData["Name"] = "JsonSchemaFile Collection" 203 indexData["Description"] = "Collection of JsonSchemaFiles" 204 indexData["Members@odata.count"] = len(schema_files) 205 indexData["Members"] = members 206 207 json.dump(indexData, index_file, indent=2) 208 209zip_ref.close() 210