xref: /openbmc/bmcweb/scripts/update_schemas.py (revision d125652e8a30dfeaad88bbfa5b1e04a80610469c)
1 #!/usr/bin/env python3
2 import os
3 import shutil
4 import zipfile
5 from collections import OrderedDict, defaultdict
6 from io import BytesIO
7 
8 import generate_schema_enums
9 import requests
10 from generate_schema_collections import generate_top_collections
11 
12 VERSION = "DSP8010_2025.1"
13 
14 SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
15 
16 proxies = {"https": os.environ.get("https_proxy", None)}
17 
18 r = requests.get(
19     "https://www.dmtf.org/sites/default/files/standards/documents/"
20     + VERSION
21     + ".zip",
22     proxies=proxies,
23 )
24 
25 r.raise_for_status()
26 
27 redfish_core_path = os.path.join(SCRIPT_DIR, "..", "redfish-core")
28 
29 cpp_path = os.path.realpath(os.path.join(redfish_core_path, "include"))
30 
31 schema_path = os.path.join(redfish_core_path, "schema", "dmtf", "csdl")
32 json_schema_path = os.path.join(
33     redfish_core_path, "schema", "dmtf", "json-schema"
34 )
35 
36 zipBytesIO = BytesIO(r.content)
37 zip_ref = zipfile.ZipFile(zipBytesIO)
38 
39 
40 class SchemaVersion:
41     """
42     A Python class for sorting Redfish schema versions.  Allows sorting Redfish
43     versions in the way humans expect, by comparing version strings as lists
44     (ie 0_2_0 comes before 0_10_0) in the way humans expect.  It does case
45     insensitive schema name comparisons
46     """
47 
48     def __init__(self, key):
49         key = str.casefold(key)
50 
51         split_tup = key.split(".")
52         self.version_pieces = [split_tup[0]]
53         if len(split_tup) < 2:
54             return
55         version = split_tup[1]
56 
57         if version.startswith("v"):
58             version = version[1:]
59         if any(char.isdigit() for char in version):
60             self.version_pieces.extend([int(x) for x in version.split("_")])
61 
62     def __lt__(self, other):
63         return self.version_pieces < other.version_pieces
64 
65 
66 shutil.rmtree(schema_path)
67 os.makedirs(schema_path)
68 
69 shutil.rmtree(json_schema_path)
70 os.makedirs(json_schema_path)
71 
72 csdl_filenames = []
73 json_schema_files = defaultdict(list)
74 
75 for zip_file in zip_ref.infolist():
76     if zip_file.is_dir():
77         continue
78     if zip_file.filename.startswith(VERSION + "/csdl/"):
79         csdl_filenames.append(os.path.basename(zip_file.filename))
80     elif zip_file.filename.startswith(VERSION + "/json-schema/"):
81         filename = os.path.basename(zip_file.filename)
82         filenamesplit = filename.split(".")
83         json_schema_files[filenamesplit[0]].append(filename)
84     elif zip_file.filename.startswith(VERSION + "/openapi/"):
85         pass
86     elif zip_file.filename.startswith(VERSION + "/dictionaries/"):
87         pass
88 
89 # sort the json files by version
90 for key, value in json_schema_files.items():
91     value.sort(key=SchemaVersion, reverse=True)
92 
93 # Create a dictionary ordered by schema name
94 json_schema_files = OrderedDict(
95     sorted(json_schema_files.items(), key=lambda x: SchemaVersion(x[0]))
96 )
97 
98 
99 for csdl_file in csdl_filenames:
100     with open(os.path.join(schema_path, csdl_file), "wb") as schema_out:
101         content = zip_ref.read(os.path.join(VERSION + "/csdl", csdl_file))
102         content = content.replace(b"\r\n", b"\n")
103         schema_out.write(content)
104 
105 for schema_filename, versions in json_schema_files.items():
106     zip_filepath = os.path.join(VERSION + "/json-schema", versions[0])
107 
108     with open(
109         os.path.join(json_schema_path, versions[0]), "wb"
110     ) as schema_file:
111         content = zip_ref.read(zip_filepath)
112         content = content.replace(b"\r\n", b"\n")
113         schema_file.write(content)
114 
115 zip_ref.close()
116 
117 generate_schema_enums.main()
118 generate_top_collections()
119