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