我有一个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定义中检索该字段的定义,并将其嵌入到我的struct的定义中。
我为此结构生成了一个OpenAPI定义,该定义以Kubernetes OpenAPI模式的定义注入,其中键为io.myapp.MinimalPod
。现在我可以使用工具openapi2jsonschema
从这个生成JSONSchema。这会生成名为MinimalPod.json
的JSONSchema文件。
现在jsonschema
工具和文件MinimalPod.json
可用于验证提供给我的工具解析器的输入,以查看是否所有字段都是正确的。
这是正确的做事方法,还是有工具/库,如果我将Go结构提供给它,它会给我OpenAPI架构吗?如果它不能识别从哪里注入Kubernetes OpenAPI模式,甚至自动解析Go结构并给出OpenAPI定义,那将是很好的。
按照@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
的定义。
注意:要生成上述步骤,请git clone https://github.com/kedgeproject/kedge
中的GOPATH
。
答案 0 :(得分:2)
您可以使用kube-openapi包。我将在回购中添加一个样本,但我已经测试了这个简单的模型:
// Car is a simple car model.
// +k8s:openapi-gen=true
type Car struct {
Color string
Capacity int
// +k8s:openapi-gen=false
HiddenFeature string
}
如果您认为在
中创建了此文件go run example/openapi-gen/main.go -h example/model/header.txt -i k8s.io/kube-openapi/example/model -p k8s.io/kube-openapi/example/model
(您还需要添加header.txt文件)。您应该在example / model文件夹中看到一个名为openapi_generated.go的新文件。这是一个中间生成的文件,其中包含OpenAPI模型:
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"k8s.io/kube-openapi/example/model.Car": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Car is a simple car model.",
Properties: map[string]spec.Schema{
"Color": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"Capacity": {
SchemaProps: spec.SchemaProps{
Type: []string{"integer"},
Format: "int32",
},
},
},
Required: []string{"Color", "Capacity"},
},
},
Dependencies: []string{},
},
}
}
从那里你应该能够调用生成的方法,获取你的Type的模型并获得它的Schema。
随着一些变得神奇并稍微更改命令行,我能够为您的模型生成模型。以下是您应该在代码中更改的内容:
package model
import "k8s.io/api/core/v1"
// MinimalPod is a minimal pod.
// +k8s:openapi-gen=true
type MinimalPod struct {
Name string `json:"name"`
v1.PodSpec
}
然后稍微更改run命令以在生成中包含PodSpec:
go run example/openapi-gen/main.go -h example/model/header.txt -i k8s.io/kube-openapi/example/model,k8s.io/api/core/v1 -p k8s.io/kube-openapi/example/model
这是我得到的:https://gist.github.com/mbohlool/e399ac2458d12e48cc13081289efc55a