preprocessing script to shorten model names as much as possible
@@ -115,6 +115,8 @@ def process_swagger(spec):
except PreprocessingException as e:
print(e.message)
+ remove_model_prefixes(spec)
+
# TODO: Kubernetes does not set a version for OpenAPI spec yet,
# remove this when that is fixed.
spec['info']['version'] = SPEC_VERSION
@@ -122,6 +124,73 @@ def process_swagger(spec):
return spec
+def rename_model(spec, old_name, new_name):
+ if new_name in spec['definitions']:
+ raise PreprocessingException(
+ "Cannot rename model %s. new name %s exists." %
+ (old_name, new_name))
+ find_rename_ref_recursive(spec,
+ "#/definitions/" + old_name,
+ "#/definitions/" + new_name)
+ spec['definitions'][new_name] = spec['definitions'][old_name]
+ del spec['definitions'][old_name]
+
+
+def find_rename_ref_recursive(root, old, new):
+ if isinstance(root, list):
+ for r in root:
+ find_rename_ref_recursive(r, old, new)
+ if isinstance(root, dict):
+ if "$ref" in root:
+ if root["$ref"] == old:
+ root["$ref"] = new
+ for k, v in root.iteritems():
+ find_rename_ref_recursive(v, old, new)
+
+
+def remove_model_prefixes(spec):
+ """Remove full package name from OpenAPI model names.
+
+ Starting kubernetes 1.6, all models has full package name. This is
+ verbose and inconvenient in python client. This function tries to remove
+ parts of the package name but will make sure there is no conflicting model
+ names. This will keep most of the model names generated by previous client
+ but will change some of them.
+ """
+ models = {}
+ for k, v in spec['definitions'].iteritems():
+ if k.startswith("io.k8s"):
+ models[k] = {"split_n": 2}
+
+ conflict = True
+ while conflict:
+ for k, v in models.iteritems():
+ splits = k.rsplit(".", v["split_n"])
+ v["removed_prefix"] = splits.pop(0)
+ v["new_name"] = ".".join(splits)
+
+ conflict = False
+ for k, v in models.iteritems():
+ for k2, v2 in models.iteritems():
+ if k != k2 and v["new_name"] == v2["new_name"]:
+ v["conflict"] = True
+ v2["conflict"] = True
+ conflict = True
+
+ if conflict:
+ for k, v in models.iteritems():
+ if "conflict" in v:
+ print("Resolving conflict for %s" % k)
+ v["split_n"] += 1
+ del v["conflict"]
+
+ for k, v in models.iteritems():
+ if "new_name" not in v:
+ raise PreprocessingException("Cannot rename model %s" % k)
+ print("Removing prefix %s from %s...\n" % (v["removed_prefix"], k))
+ rename_model(spec, k, v["new_name"])
+
+
def main():
pool = urllib3.PoolManager()
with pool.request('GET', SPEC_URL, preload_content=False) as response:
