【发布时间】:2018-03-17 10:54:01
【问题描述】:
我有一个 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 的扩充。
现在我使用的方法是将generate definition 部分用于我的结构MinimalPod,PodSpec 的定义将来自Kubernetes 的upstream OpenAPI spec。 PodSpec在upstream OpenAPI spec中有一个键io.k8s.kubernetes.pkg.api.v1.PodSpec,这个定义就是injected from there in my Properties。现在,在我的解析上述结构的代码中,我有如果struct field is string 该怎么做的模板。
如果该字段有注释 starts with 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 结构的自动解析中注入 Kubernetes OpenAPI 模式的位置并提供 OpenAPI 定义将不胜感激。
更新 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 作为导入时,所有内容都会生成。
注意:如需生成上述步骤,请在GOPATHgit clone https://github.com/kedgeproject/kedge。
【问题讨论】:
-
为结构生成 openapi 定义是很容易的部分。构建用于生成 openapi 路径的路由更具挑战性。您可以在这里查看我的类似问题:groups.google.com/forum/#!topic/kubernetes-users/_ipF9ocbIQE
标签: go kubernetes swagger jsonschema openapi