У меня есть структура 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
.
Теперь подход, который я использовал, заключается в том, чтобы сгенерировать definition
< / a> для моей структуры MinimalPod
, определение для PodSpec
будет происходить из спецификация OpenAPI Kubernetes. PodSpec
имеет ключ io.k8s.kubernetes.pkg.api.v1.PodSpec
в восходящей спецификации OpenAPI, это определение введено оттуда в мои свойства. Теперь в моем коде, который анализирует структуру выше, есть шаблоны того, что делать, если поле структуры string
.
Если в поле есть комментарий, который начинается с _9 _9 _9 _9 _ a> следующая часть - это ключ определения OpenAPI объекта Kubernetes. В нашем случае ключ определения OpenAPI - io.k8s.kubernetes.pkg.api.v1.PodSpec
. Поэтому я извлекаю определение этого поля из вышестоящего определения OpenAPI и встраиваю его в определение моей структуры.
Как только я сгенерировал определение OpenAPI для этой структуры, которое вводится в определение схемы Kubernetes OpenAPI с ключом io.myapp.MinimalPod
. Теперь я могу использовать инструмент openapi2jsonschema
для создания схемы JSONSchema из этого. При этом создается файл JSONSchema с именем MinimalPod.json
.
Теперь инструмент jsonschema
и файл MinimalPod.json
можно использовать для проверки ввода, переданного парсеру моего инструмента, чтобы убедиться, что все поля заданы правильно.
Это правильный подход к работе или есть инструмент / библиотека, и если я скармливаю ему структуры Go, он дает мне схему OpenAPI? Было бы хорошо, если бы он не определял, куда внедрять схему Kubernetes OpenAPI даже из автоматического анализа структур Go, и предоставление определения 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
в качестве импорта, все создается.
Примечание. Чтобы создать вышеуказанные шаги, git clone https://github.com/kedgeproject/kedge
в GOPATH
.