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