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.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 '/' + 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 one, 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 metadata_index.write("</edmx:Edmx>\n") 118 119schema_files = {} 120for zip_filepath in zip_ref.namelist(): 121 if zip_filepath.startswith(os.path.join(VERSION, VERSION, 'json-schema/')): 122 filename = os.path.basename(zip_filepath) 123 filenamesplit = filename.split(".") 124 if len(filenamesplit) == 3: 125 thisSchemaVersion = schema_files.get(filenamesplit[0], None) 126 if thisSchemaVersion is None: 127 schema_files[filenamesplit[0]] = filenamesplit[1] 128 else: 129 # need to see if we're a newer version. 130 if list(map(int, filenamesplit[1][1:].split("_"))) > list(map( 131 int, thisSchemaVersion[1:].split("_"))): 132 schema_files[filenamesplit[0]] = filenamesplit[1] 133 134 135for schema, version in schema_files.items(): 136 basename = schema + "." + version + ".json" 137 zip_filepath = os.path.join(VERSION, VERSION, "json-schema", basename) 138 schemadir = os.path.join(json_schema_path, schema) 139 os.makedirs(schemadir) 140 location_json = OrderedDict() 141 location_json["Language"] = "en" 142 location_json["PublicationUri"] = ( 143 "http://redfish.dmtf.org/schemas/v1/" + schema + ".json") 144 location_json["Uri"] = ( 145 "/redfish/v1/JsonSchemas/" + schema + "/" + schema + ".json") 146 147 index_json = OrderedDict() 148 index_json["@odata.context"] = "/redfish/v1/$metadata#JsonSchemaFile.JsonSchemaFile" 149 index_json["@odata.id"] = "/redfish/v1/JsonSchemas/" + schema 150 index_json["@odata.type"] = "#JsonSchemaFile.v1_0_2.JsonSchemaFile" 151 index_json["Name"] = schema + " Schema File" 152 index_json["Schema"] = "#" + schema + "." + schema 153 index_json["Description"] = schema + " Schema File Location" 154 index_json["Id"] = schema 155 index_json["Languages"] = ["en"] 156 index_json["Languages@odata.count"] = 1 157 index_json["Location"] = [location_json] 158 index_json["Location@odata.count"] = 1 159 160 with open(os.path.join(schemadir, "index.json"), 'w') as schema_file: 161 json.dump(index_json, schema_file, indent=4) 162 with open(os.path.join(schemadir, schema + ".json"), 'wb') as schema_file: 163 schema_file.write(zip_ref.read(zip_filepath).replace(b'\r\n', b'\n')) 164 165with open(os.path.join(json_schema_path, "index.json"), 'w') as index_file: 166 members = [{"@odata.id": "/redfish/v1/JsonSchemas/" + schema} 167 for schema in schema_files] 168 169 members.sort(key=lambda x: x["@odata.id"]) 170 171 indexData = OrderedDict() 172 173 indexData["@odata.id"] = "/redfish/v1/JsonSchemas" 174 indexData["@odata.context"] = ("/redfish/v1/$metadata" 175 "#JsonSchemaFileCollection." 176 "JsonSchemaFileCollection") 177 indexData["@odata.type"] = ("#JsonSchemaFileCollection." 178 "JsonSchemaFileCollection") 179 indexData["Name"] = "JsonSchemaFile Collection" 180 indexData["Description"] = "Collection of JsonSchemaFiles" 181 indexData["Members@odata.count"] = len(schema_files) 182 indexData["Members"] = members 183 184 json.dump(indexData, index_file, indent=2) 185 186zip_ref.close() 187