Переход от структур к OpenAPI к генерации JSONSchema автоматически

У меня есть структура 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.


person surajd    schedule 05.10.2017    source источник
comment
Генерация определений openapi для структур - самая простая часть. Создание маршрутов, которые используются для создания путей openapi, является более сложной задачей. Вы можете посмотреть на мой аналогичный вопрос здесь: groups.google.com / forum / #! topic / kubernetes-users / _ipF9ocbIQE   -  person MarkNS    schedule 06.10.2017


Ответы (1)


Для этого вы можете использовать пакет 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{},
        },
    }
}

Оттуда вы сможете вызвать сгенерированный метод, получить модель для своего типа и получить его схему.

Приложив некоторые усилия и немного изменив командную строку, я смог сгенерировать модель для вашей модели. Вот что вам следует изменить в своем коде:

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
}

а затем немного измените команду запуска, чтобы включить 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

person Mehdy    schedule 06.10.2017
comment
Спасибо за подробный ответ, я попробовал то, что вы предложили, и это сработало для меня, но, пожалуйста, см. Обновление № 1 в вопросе, которое не работает для другого местоположения импорта PodSpec, ваши вклады приветствуются! - person surajd; 09.10.2017