encoding/openapi: add support for openapi extension attributes in builder#3797
encoding/openapi: add support for openapi extension attributes in builder#3797nkvoll wants to merge 2 commits intocue-lang:masterfrom
Conversation
…lder Signed-off-by: Njal Karevoll <njal@karevoll.no>
d657071 to
82a7575
Compare
|
@nkvoll Thanks very much for the PR! We definitely want to support aspects of OpenAPI like this, although the right approach isn't entirely clear currently. For now, we are super busy in the run up to Kubecon. We will get back to you with feedback on this after that :) |
Signed-off-by: Njal Karevoll <njal@karevoll.no>
|
Hi @rogpeppe, just checking in if you have had some time to take a look. I just pushed a change that moves the extension definition from being json to being in cue (not 100% sure on the implementation, whether there is a better / more canonical approach available -- happy to learn). Example usage right now (pluralized extensions since multiple extensions can be defined here -- though there are currently no explicit guardrails for not colliding with the built-in attributes): package example
#SomeResource: {
spec: {
parameters: {
minReplicas: int
maxReplicas: int
replicas: int
} @openapi(extensions={
"x-kubernetes-validations": [
{
rule: "self.minReplicas <= self.replicas && self.replicas <= self.maxReplicas",
message: "replicas should be in the range minReplicas..maxReplicas",
}
]
})
}
} |
|
I like the generality of this approach, but if the main objective is support for validation expressions, we should probably see whether it might be possible to express those in CUE directly rather than in an auxilliary non-CUE syntax in attributes. To take the example from the validation rules page, ISTM it would be much nicer if it was possible to specify it as: rather than using the Kubernetes extension syntax directly. I've created #4048 to track that possibility. Given that this particular PR implements general support for OpenAPI "extensions", it would be nice to know what other kinds of extension are also good use cases. |
|
I don't know of any general overview, but https://swagger.io/docs/specification/v3_0/openapi-extensions/ has an example that uses a lambda authorizer: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-authorizer.html Google has a bunch of theirs listed here: https://cloud.google.com/endpoints/docs/openapi/openapi-extensions Redocly has a number of extensions as well https://redocly.com/docs-legacy/api-reference-docs/spec-extensions Most generically, https://openapispec.com/docs/what/what-are-openapi-extensions/ describes some /possibilities/ |
This is just taking a quick stab at something for #2638, just to see what it would take to fix. I'm not experienced with nor do I fully understand the ast or if what I'm doing is very uncanonical (just learning cue and first time potential contributor), so please bear with me as I'm looking for some feedback on whether some direction like this makes sense or if I'm looking in the wrong directions.
What I wanted to add support for is extending the openapi schema to support extensions like CEL (see https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules). This requires a little more than adding string string:string key:value pairs, so I opted for using JSON inside the cue attribute.
Having the attribute be
@openapi(extension:keyName:json-value)meant a little more parsing than something like@openapiExtension(keyName:json-value)(or similar).Example
Example resource (
example.cue):Generate:
go run ./cmd/cue def example.cue -o example.openapi.yaml --out openapi+yamlOutput