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.2.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('csdl/') & (zip_filepath != "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 metadata_index.write("</edmx:Edmx>\n") 95 96schema_files = {} 97for zip_filepath in zip_ref.namelist(): 98 if zip_filepath.startswith('json-schema/'): 99 filename = os.path.basename(zip_filepath) 100 filenamesplit = filename.split(".") 101 if len(filenamesplit) == 3: 102 thisSchemaVersion = schema_files.get(filenamesplit[0], None) 103 if thisSchemaVersion == None: 104 schema_files[filenamesplit[0]] = filenamesplit[1] 105 else: 106 # need to see if we're a newer version. 107 if list(map(int, filenamesplit[1][1:].split("_"))) > list(map( 108 int, thisSchemaVersion[1:].split("_"))): 109 schema_files[filenamesplit[0]] = filenamesplit[1] 110 111 112for schema, version in schema_files.items(): 113 basename = schema + "." + version + ".json" 114 zip_filepath = os.path.join("json-schema", basename) 115 schemadir = os.path.join(json_schema_path, schema) 116 os.makedirs(schemadir) 117 118 index_json = { 119 "@odata.context": "/redfish/v1/$metadata#JsonSchemaFile.JsonSchemaFile", 120 "@odata.id": "/redfish/v1/JSONSchemas/" + schema, 121 "@odata.type": "#JsonSchemaFile.v1_0_2.JsonSchemaFile", 122 "Name": schema + " Schema File", 123 "Schema": "#" + schema + "." + schema, 124 "Description": schema + " Schema File Location", 125 "Id": schema, 126 "Languages": [ 127 "en" 128 ], 129 "Languages@odata.count": 1, 130 "Location": [ 131 { 132 "Language": "en", 133 "PublicationUri": "http://redfish.dmtf.org/schemas/v1/" + schema + ".json", 134 "Uri": "/redfish/v1/JSONSchemas/" + schema + "/" + schema + ".json" 135 } 136 ], 137 "Location@odata.count": 1, 138 } 139 140 with open(os.path.join(schemadir, "index.json"), 'w') as schema_file: 141 json.dump(index_json, schema_file, indent=4) 142 with open(os.path.join(schemadir, schema + ".json"), 'wb') as schema_file: 143 schema_file.write(zip_ref.read(zip_filepath)) 144 145with open(os.path.join(json_schema_path, "index.json"), 'w') as index_file: 146 members = [{"@odata.id": "/redfish/v1/JsonSchemas/" + schema + "/"} 147 for schema in schema_files] 148 149 members.sort(key=lambda x: x["@odata.id"]) 150 151 indexData = OrderedDict() 152 153 indexData["@odata.id"] = "/redfish/v1/JsonSchemas" 154 indexData["@odata.context"] = ("/redfish/v1/$metadata" 155 "#JsonSchemaFileCollection." 156 "JsonSchemaFileCollection") 157 indexData["@odata.type"] = ("#JsonSchemaFileCollection." 158 "JsonSchemaFileCollection") 159 indexData["Name"] = "JsonSchemaFile Collection" 160 indexData["Description"] = "Collection of JsonSchemaFiles" 161 indexData["Members@odata.count"] = len(schema_files) 162 indexData["Members"] = members 163 164 json.dump(indexData, index_file, indent=2) 165 166zip_ref.close() 167