-
Notifications
You must be signed in to change notification settings - Fork 668
Description
What would you like to be added:
Similar to the main Kubernetes project, I want an OpenAPI v2 spec in JSON that can be consumed by clients.
The Kubernetes project handles this by spinning up the API server and GETing its OpenAPI v2 spec endpoint:
https://github.com/kubernetes/kubernetes/blob/54241eea4dbdf1ac4bce83748f748a49488a70c1/hack/update-openapi-spec.sh#L115-L118
This outputs this file:
https://github.com/kubernetes/kubernetes/blob/master/api/openapi-spec/swagger.json
This project does get halfway there by generating an OpenAPI spec, but it's in a Go file, not a JSON spec:
https://github.com/kubernetes-sigs/gateway-api/blob/main/pkg/generated/openapi/zz_generated.openapi.go
As part of hack/update-clientset.sh, the zz_generated.openapi.go file should be read and a swagger.json file should be output beside it.
Why this is needed:
The pkg/generated/openapi/zz_generated.openapi.go is useful for clients written in Go, but other languages are left with no API definition. Anyone wanting to use one of the many OpenAPI library generators will need an OpenAPI spec in JSON.
Suggested solution:
I have a "working" hack that can spit out a JSON spec, but it is too hacky an incomplete for me to open a PR with it. I will add it below in case it helps with understanding this request, getting started on a solution, or for anyone in my situation who just needs a JSON spec right now.
First, write a tiny Go program to convert the Go spec to JSON:
// pkg/generated/swagger.go
package main
import (
"encoding/json"
"os"
"k8s.io/kube-openapi/pkg/validation/spec"
"sigs.k8s.io/gateway-api/pkg/generated/openapi"
)
func main() {
b, _ := json.Marshal(openapi.GetOpenAPIDefinitions(func(path string) (spec.Ref) {
return spec.MustCreateRef(path);
}));
os.Stdout.Write(b);
}This outputs the definitions part of a OpenAPI v2 spec, though it isn't exactly matching the spec (it has a Schema key under each definition that needs to be folded out).
Then, convert it to a conformant OpenAPI v2 spec file:
go run pkg/generated/swagger.go \
| jq '{"swagger":"2.0","info":{"title":"gateway-api","version":"v1.5.0-rc.1"},"paths":{},"definitions":(.|map_values(.Schema))}' \
| sed 's|k8s.io/apimachinery/pkg/apis/meta/|io.k8s.apimachinery.pkg.apis.meta.|' \
| sed 's|k8s.io/apimachinery/pkg/runtime/|io.k8s.apimachinery.pkg.runtime.|' \
| sed -E 's|sigs.k8s.io/gateway-api/apis(x)?/|io.k8s.sigs.gateway-api.apis\1.|' \
> pkg/generated/openapi/swagger.jsonThis is spec compliant, matches the definition name format of the Kubernetes spec, and worked on the generator I tried and made model objects.
Besides feeling like a huge hack, the biggest issue is the lack of paths. I do not know how to solve that, as this project doesn't have any knowledge or control over API paths AFAIK, since it uses the CRD API points in Kubernetes. However, they could and probably should be documented somehow (ex: /apis/gateway.networking.k8s.io/v1/namespaces/{namespace}/httproutes).