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
This commit is contained in:
q3k 2021-09-11 20:07:52 +00:00
parent 1dbefed537
commit 9cfc2a0e43

View file

@ -46,6 +46,7 @@ kube {
// Make OpenAPI v3 schema specification less painful.
OpenAPI:: {
local openapi = self,
Validation(obj):: {
openAPIV3Schema: obj.render,
},
@ -54,69 +55,85 @@ kube {
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,
},
},
}