我有一个Go结构体,想要自动生成OpenAPI模式。一旦我有了该结构体的OpenAPI定义,我想要生成其JSONSchema,以便验证输入数据并将其解析到这些结构体中。
该结构体如下所示:
// mySpec: io.myapp.MinimalPod
type MinimalPod struct {
Name string `json:"name"`
// k8s: io.k8s.kubernetes.pkg.api.v1.PodSpec
v1.PodSpec
}
上面的结构明显是 Kubernetes 中
PodSpec
的扩展。现在我所使用的方法是为我的结构体
MinimalPod
生成definition
,PodSpec
的定义将从Kubernetes的上游OpenAPI规范中获取。在上游OpenAPI规范中,PodSpec
有一个键io.k8s.kubernetes.pkg.api.v1.PodSpec
,此定义从那里注入到我的属性中。现在,在解析上述结构体的代码中,如果结构体字段是string
,我有模板来指导该怎么做。如果字段有一个注释,以
k8s: ...
开头,下一部分是Kubernetes对象的OpenAPI定义键。在我们的情况下,OpenAPI定义键是io.k8s.kubernetes.pkg.api.v1.PodSpec
。因此,我从上游OpenAPI定义中检索该字段的定义,并将其嵌入到我的结构的定义中。一旦我为此结构生成了一个OpenAPI定义,它被注入到Kubernetes OpenAPI模式的定义中,键为
io.myapp.MinimalPod
。现在,我可以使用工具openapi2jsonschema
将其生成为JSONSchema。这将生成一个名为MinimalPod.json
的JSONSchema文件。现在,
jsonschema
工具和文件MinimalPod.json
可以用于验证输入给我的解析器工具的正确性。这是正确的做法吗?还是有工具/库,如果我将Go结构提供给它,它会给我OpenAPI模式?即使自动解析Go结构并给出OpenAPI定义时无法确定在哪里注入Kubernetes OpenAPI模式,也可以使用。请注意保留HTML标签。
更新1
在遵循 @mehdy 的指示后,我尝试了以下操作:
我使用了这个导入路径 github.com/kedgeproject/kedge/vendor/k8s.io/client-go/pkg/api/v1
来导入 PodSpec
定义,而不是 k8s.io/api/core/v1
,代码如下:
package foomodel
import "github.com/kedgeproject/kedge/vendor/k8s.io/client-go/pkg/api/v1"
// MinimalPod is a minimal pod.
// +k8s:openapi-gen=true
type MinimalPod struct {
Name string `json:"name"`
v1.PodSpec
}
现在,当我使用标志
-i
生成相同的内容时,将k8s.io/api/core/v1
更改为github.com/kedgeproject/kedge/vendor/k8s.io/client-go/pkg/api/v1
。$ go run example/openapi-gen/main.go -i k8s.io/kube-openapi/example/model,github.com/kedgeproject/kedge/vendor/k8s.io/client-go/pkg/api/v1 -h example/foomodel/header.txt -p k8s.io/kube-openapi/example/foomodel
这是生成的内容:
$ cat openapi_generated.go
// +build !ignore_autogenerated
/*
======
Some random text
======
*/
// This file was autogenerated by openapi-gen. Do not edit it manually!
package foomodel
import (
spec "github.com/go-openapi/spec"
common "k8s.io/kube-openapi/pkg/common"
)
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"k8s.io/kube-openapi/example/model.Container": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Container defines a single application container that you want to run within a pod.",
Properties: map[string]spec.Schema{
"health": {
SchemaProps: spec.SchemaProps{
Description: "One common definitions for 'livenessProbe' and 'readinessProbe' this allows to have only one place to define both probes (if they are the same) Periodic probe of container liveness and readiness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
Ref: ref("k8s.io/client-go/pkg/api/v1.Probe"),
},
},
"Container": {
SchemaProps: spec.SchemaProps{
Ref: ref("k8s.io/client-go/pkg/api/v1.Container"),
},
},
},
Required: []string{"Container"},
},
},
Dependencies: []string{
"k8s.io/client-go/pkg/api/v1.Container", "k8s.io/client-go/pkg/api/v1.Probe"},
},
}
}
我只得到了这么多的配置生成。当我切换回 "k8s.io/api/core/v1"
时,我得到了自动生成的超过8k行的配置代码。我错过了什么吗?
在这里,k8s.io/client-go/pkg/api/v1.Container
和 k8s.io/client-go/pkg/api/v1.Probe
的定义缺失,而当我使用 k8s.io/api/core/v1
作为导入时,所有内容都被生成。
注意:要生成上述步骤,请在 GOPATH
中执行 git clone https://github.com/kedgeproject/kedge
。