kube.libsonnet: refactor OpenAPI lib, support extra types
This was to be used by a Ceph CRD bump, but we ended up using upstream
yaml instead. But it's a useful change regardless.
I really should document this and write some tests.
Change-Id: I27ce94c6ebe50a4a93baa83418e8d40004755231
diff --git a/kube/kube.libsonnet b/kube/kube.libsonnet
index 8d7254a..7e69720 100644
--- a/kube/kube.libsonnet
+++ b/kube/kube.libsonnet
@@ -46,6 +46,7 @@
// Make OpenAPI v3 schema specification less painful.
OpenAPI:: {
+ local openapi = self,
Validation(obj):: {
openAPIV3Schema: obj.render,
},
@@ -54,69 +55,85 @@
required:: true,
},
- Dict:: {
- local dict = self,
+ renderable:: {
required:: false,
+ render:: {},
+ },
+ local renderable = self.renderable,
+
+ lift(f, keys):: {
+ [if f[k] != null then k]: f[k]
+ for k in keys
+ },
+ local lift = self.lift,
+
+ parametrized(type, keys=[]):: (
+ local keysp = keys + [
+ "description",
+ "nullable",
+ "x-kubernetes-preserve-unknown-fields",
+ ];
+ renderable {
+ render:: lift(self, keysp) {
+ type: type,
+ },
+ } + {
+ [k]: null
+ for k in keysp
+ }
+ ),
+ local parametrized = self.parametrized,
+
+ Any:: renderable,
+ Boolean:: parametrized("boolean"),
+ Integer:: parametrized("integer", ["minimum", "maximum", "format"]),
+ Number:: parametrized("number"),
+ String:: parametrized("string", ["pattern"]),
+
+ Dict:: renderable {
+ local d = self,
local requiredList = [
- k for k in std.filter(function(k) dict[k].required, std.objectFields(dict))
+ k for k in std.filter(function(k) d[k].required, std.objectFields(d))
],
- render:: {
+ render+: {
properties: {
- [k]: dict[k].render
- for k in std.objectFields(dict)
+ [k]: d[k].render
+ for k in std.objectFields(d)
},
- } + (if std.length(requiredList) > 0 then {
- required: requiredList,
- } else {}),
+ [if std.length(requiredList) > 0 then 'required']: requiredList,
+ },
+ },
+ Object(props={}):: parametrized("object") {
+ local requiredList = [
+ k for k in std.filter(function(k) props[k].required, std.objectFields(props))
+ ],
+
+ render+: {
+ [if std.length(std.objectFields(props)) > 0 then "properties"]: {
+ [k]: props[k].render
+ for k in std.objectFields(props)
+ },
+ [if std.length(requiredList) > 0 then 'required']: requiredList,
+ },
},
- Array(items):: {
- required:: false,
- render:: {
- type: "array",
+ Array(items):: parametrized("array") {
+ render+: {
items: items.render,
},
},
- Integer:: {
- local integer = self,
- required:: false,
- render:: {
- type: "integer",
- } + (if integer.minimum != null then {
- minimum: integer.minimum,
- } else {}) + (if integer.maximum != null then {
- maximum: integer.maximum,
- } else {}),
-
- minimum:: null,
- maximum:: null,
- },
-
- String:: {
- local string = self,
- required:: false,
- render:: {
- type: "string",
- } + (if string.pattern != null then {
- pattern: string.pattern,
- } else {}),
-
- pattern:: null,
- },
-
- Boolean:: {
- required:: false,
- render:: {
- type: "boolean",
+ Enum(items):: parametrized("string") {
+ render+: {
+ enum: items,
},
},
- Any:: {
- required:: false,
- render:: {},
+ KubeAny(nullable=false):: self.Object() {
+ [if nullable then "nullable"]: true,
+ "x-kubernetes-preserve-unknown-fields": true,
},
},
}