Commit 3ed58475 authored by Antoine Pelisse's avatar Antoine Pelisse

Update openapi to use kube-openapi code

parent 875a72fe
......@@ -19,6 +19,7 @@ go_library(
"//pkg/kubectl/apply:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -20,6 +20,7 @@ import (
"fmt"
"reflect"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
......@@ -60,7 +61,7 @@ func (b *Factory) CreateElement(recorded, local, remote map[string]interface{})
}
// getItem returns the appropriate Item based on the underlying type of the arguments
func (v *ElementBuildingVisitor) getItem(s openapi.Schema, name string, data apply.RawElementData) (Item, error) {
func (v *ElementBuildingVisitor) getItem(s proto.Schema, name string, data apply.RawElementData) (Item, error) {
kind, err := getType(data.GetRecorded(), data.GetLocal(), data.GetRemote())
if err != nil {
return nil, err
......
......@@ -17,8 +17,8 @@ limitations under the License.
package parse
import (
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
// Item wraps values from 3 sources (recorded, local, remote).
......@@ -31,7 +31,7 @@ type Item interface {
// primitiveItem contains a recorded, local, and remote value
type primitiveItem struct {
Name string
Primitive *openapi.Primitive
Primitive *proto.Primitive
apply.RawElementData
}
......@@ -40,7 +40,7 @@ func (i *primitiveItem) CreateElement(v ItemVisitor) (apply.Element, error) {
return v.CreatePrimitiveElement(i)
}
func (i *primitiveItem) GetMeta() openapi.Schema {
func (i *primitiveItem) GetMeta() proto.Schema {
// https://golang.org/doc/faq#nil_error
if i.Primitive != nil {
return i.Primitive
......@@ -51,7 +51,7 @@ func (i *primitiveItem) GetMeta() openapi.Schema {
// listItem contains a recorded, local, and remote list
type listItem struct {
Name string
Array *openapi.Array
Array *proto.Array
apply.ListElementData
}
......@@ -60,7 +60,7 @@ func (i *listItem) CreateElement(v ItemVisitor) (apply.Element, error) {
return v.CreateListElement(i)
}
func (i *listItem) GetMeta() openapi.Schema {
func (i *listItem) GetMeta() proto.Schema {
// https://golang.org/doc/faq#nil_error
if i.Array != nil {
return i.Array
......@@ -71,7 +71,7 @@ func (i *listItem) GetMeta() openapi.Schema {
// mapItem contains a recorded, local, and remote map
type mapItem struct {
Name string
Map *openapi.Map
Map *proto.Map
apply.MapElementData
}
......@@ -80,7 +80,7 @@ func (i *mapItem) CreateElement(v ItemVisitor) (apply.Element, error) {
return v.CreateMapElement(i)
}
func (i *mapItem) GetMeta() openapi.Schema {
func (i *mapItem) GetMeta() proto.Schema {
// https://golang.org/doc/faq#nil_error
if i.Map != nil {
return i.Map
......@@ -91,12 +91,12 @@ func (i *mapItem) GetMeta() openapi.Schema {
// mapItem contains a recorded, local, and remote map
type typeItem struct {
Name string
Type *openapi.Kind
Type *proto.Kind
apply.MapElementData
}
func (i *typeItem) GetMeta() openapi.Schema {
func (i *typeItem) GetMeta() proto.Schema {
// https://golang.org/doc/faq#nil_error
if i.Type != nil {
return i.Type
......
......@@ -18,8 +18,9 @@ package parse
import (
"fmt"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
// Contains the heavy lifting for finding tuples of matching elements in lists based on the merge key
......@@ -70,7 +71,7 @@ func (v ElementBuildingVisitor) doPrimitiveList(meta apply.FieldMetaImpl, item *
}
for i, l := range orderedKeys.Items {
var s openapi.Schema
var s proto.Schema
if item.Array != nil && item.Array.SubType != nil {
s = item.Array.SubType
}
......@@ -127,7 +128,7 @@ func (v ElementBuildingVisitor) doMapList(meta apply.FieldMetaImpl, item *listIt
}
for i, l := range orderedKeys.Items {
var s openapi.Schema
var s proto.Schema
if item.Array != nil && item.Array.SubType != nil {
s = item.Array.SubType
}
......@@ -171,7 +172,7 @@ func (v ElementBuildingVisitor) replaceListElement(meta apply.FieldMetaImpl, ite
}
// Create the Item
var s openapi.Schema
var s proto.Schema
if item.Array != nil && item.Array.SubType != nil {
s = item.Array.SubType
}
......
......@@ -17,14 +17,14 @@ limitations under the License.
package parse
import (
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
// mapElement builds a new mapElement from a mapItem
func (v ElementBuildingVisitor) mapElement(meta apply.FieldMetaImpl, item *mapItem) (*apply.MapElement, error) {
// Function to return schema type of the map values
var fn schemaFn = func(string) openapi.Schema {
var fn schemaFn = func(string) proto.Schema {
// All map values share the same schema
if item.Map != nil && item.Map.SubType != nil {
return item.Map.SubType
......@@ -43,7 +43,7 @@ func (v ElementBuildingVisitor) mapElement(meta apply.FieldMetaImpl, item *mapIt
}
// schemaFn returns the schema for a field or map value based on its name or key
type schemaFn func(key string) openapi.Schema
type schemaFn func(key string) proto.Schema
// createMapValues combines the recorded, local and remote values from
// data into a map of elements.
......
......@@ -18,13 +18,14 @@ package parse
import (
"fmt"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kube-openapi/pkg/util/proto"
)
// Contains functions for casting openapi interfaces to their underlying types
// getSchemaType returns the string type of the schema - e.g. array, primitive, map, kind, reference
func getSchemaType(schema openapi.Schema) string {
func getSchemaType(schema proto.Schema) string {
if schema == nil {
return ""
}
......@@ -33,8 +34,8 @@ func getSchemaType(schema openapi.Schema) string {
return visitor.Kind
}
// getKind converts schema to an *openapi.Kind object
func getKind(schema openapi.Schema) (*openapi.Kind, error) {
// getKind converts schema to an *proto.Kind object
func getKind(schema proto.Schema) (*proto.Kind, error) {
if schema == nil {
return nil, nil
}
......@@ -43,8 +44,8 @@ func getKind(schema openapi.Schema) (*openapi.Kind, error) {
return visitor.Result, visitor.Err
}
// getArray converts schema to an *openapi.Array object
func getArray(schema openapi.Schema) (*openapi.Array, error) {
// getArray converts schema to an *proto.Array object
func getArray(schema proto.Schema) (*proto.Array, error) {
if schema == nil {
return nil, nil
}
......@@ -53,8 +54,8 @@ func getArray(schema openapi.Schema) (*openapi.Array, error) {
return visitor.Result, visitor.Err
}
// getMap converts schema to an *openapi.Map object
func getMap(schema openapi.Schema) (*openapi.Map, error) {
// getMap converts schema to an *proto.Map object
func getMap(schema proto.Schema) (*proto.Map, error) {
if schema == nil {
return nil, nil
}
......@@ -63,8 +64,8 @@ func getMap(schema openapi.Schema) (*openapi.Map, error) {
return visitor.Result, visitor.Err
}
// getPrimitive converts schema to an *openapi.Primitive object
func getPrimitive(schema openapi.Schema) (*openapi.Primitive, error) {
// getPrimitive converts schema to an *proto.Primitive object
func getPrimitive(schema proto.Schema) (*proto.Primitive, error) {
if schema == nil {
return nil, nil
}
......@@ -79,95 +80,95 @@ type baseSchemaVisitor struct {
}
// VisitArray implements openapi
func (v *baseSchemaVisitor) VisitArray(array *openapi.Array) {
func (v *baseSchemaVisitor) VisitArray(array *proto.Array) {
v.Kind = "array"
v.Err = fmt.Errorf("Array type not expected")
}
// MergeMap implements openapi
func (v *baseSchemaVisitor) VisitMap(*openapi.Map) {
func (v *baseSchemaVisitor) VisitMap(*proto.Map) {
v.Kind = "map"
v.Err = fmt.Errorf("Map type not expected")
}
// MergePrimitive implements openapi
func (v *baseSchemaVisitor) VisitPrimitive(*openapi.Primitive) {
func (v *baseSchemaVisitor) VisitPrimitive(*proto.Primitive) {
v.Kind = "primitive"
v.Err = fmt.Errorf("Primitive type not expected")
}
// VisitKind implements openapi
func (v *baseSchemaVisitor) VisitKind(*openapi.Kind) {
func (v *baseSchemaVisitor) VisitKind(*proto.Kind) {
v.Kind = "kind"
v.Err = fmt.Errorf("Kind type not expected")
}
// VisitReference implements openapi
func (v *baseSchemaVisitor) VisitReference(reference openapi.Reference) {
func (v *baseSchemaVisitor) VisitReference(reference proto.Reference) {
v.Kind = "reference"
v.Err = fmt.Errorf("Reference type not expected")
}
type kindSchemaVisitor struct {
baseSchemaVisitor
Result *openapi.Kind
Result *proto.Kind
}
// VisitKind implements openapi
func (v *kindSchemaVisitor) VisitKind(result *openapi.Kind) {
func (v *kindSchemaVisitor) VisitKind(result *proto.Kind) {
v.Result = result
v.Kind = "kind"
}
// VisitReference implements openapi
func (v *kindSchemaVisitor) VisitReference(reference openapi.Reference) {
func (v *kindSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
}
type mapSchemaVisitor struct {
baseSchemaVisitor
Result *openapi.Map
Result *proto.Map
}
// MergeMap implements openapi
func (v *mapSchemaVisitor) VisitMap(result *openapi.Map) {
func (v *mapSchemaVisitor) VisitMap(result *proto.Map) {
v.Result = result
v.Kind = "map"
}
// VisitReference implements openapi
func (v *mapSchemaVisitor) VisitReference(reference openapi.Reference) {
func (v *mapSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
}
type arraySchemaVisitor struct {
baseSchemaVisitor
Result *openapi.Array
Result *proto.Array
}
// VisitArray implements openapi
func (v *arraySchemaVisitor) VisitArray(result *openapi.Array) {
func (v *arraySchemaVisitor) VisitArray(result *proto.Array) {
v.Result = result
v.Kind = "array"
}
// MergePrimitive implements openapi
func (v *arraySchemaVisitor) VisitReference(reference openapi.Reference) {
func (v *arraySchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
}
type primitiveSchemaVisitor struct {
baseSchemaVisitor
Result *openapi.Primitive
Result *proto.Primitive
}
// MergePrimitive implements openapi
func (v *primitiveSchemaVisitor) VisitPrimitive(result *openapi.Primitive) {
func (v *primitiveSchemaVisitor) VisitPrimitive(result *proto.Primitive) {
v.Result = result
v.Kind = "primitive"
}
// VisitReference implements openapi
func (v *primitiveSchemaVisitor) VisitReference(reference openapi.Reference) {
func (v *primitiveSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
}
......@@ -17,14 +17,14 @@ limitations under the License.
package parse
import (
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
// typeElement builds a new mapElement from a typeItem
func (v ElementBuildingVisitor) typeElement(meta apply.FieldMetaImpl, item *typeItem) (*apply.TypeElement, error) {
// Function to get the schema of a field from its key
var fn schemaFn = func(key string) openapi.Schema {
var fn schemaFn = func(key string) proto.Schema {
if item.Type != nil && item.Type.Fields != nil {
return item.Type.Fields[key]
}
......
......@@ -22,8 +22,8 @@ import (
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/apply"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
// nilSafeLookup returns the value from the map if the map is non-nil
......@@ -97,7 +97,7 @@ func getType(args ...interface{}) (reflect.Type, error) {
}
// getFieldMeta parses the metadata about the field from the openapi spec
func getFieldMeta(s openapi.Schema, name string) (apply.FieldMetaImpl, error) {
func getFieldMeta(s proto.Schema, name string) (apply.FieldMetaImpl, error) {
m := apply.FieldMetaImpl{}
if s != nil {
ext := s.GetExtensions()
......
......@@ -242,6 +242,7 @@ go_test(
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
],
)
......
......@@ -38,6 +38,7 @@ import (
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
......@@ -218,10 +219,10 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
}
type FakeResources struct {
resources map[schema.GroupVersionKind]openapi.Schema
resources map[schema.GroupVersionKind]proto.Schema
}
func (f FakeResources) LookupResource(s schema.GroupVersionKind) openapi.Schema {
func (f FakeResources) LookupResource(s schema.GroupVersionKind) proto.Schema {
return f.resources[s]
}
......@@ -229,12 +230,12 @@ var _ openapi.Resources = &FakeResources{}
func testOpenAPISchemaData() (openapi.Resources, error) {
return &FakeResources{
resources: map[schema.GroupVersionKind]openapi.Schema{
resources: map[schema.GroupVersionKind]proto.Schema{
{
Version: "v1",
Kind: "Pod",
}: &openapi.Primitive{
BaseSchema: openapi.BaseSchema{
}: &proto.Primitive{
BaseSchema: proto.BaseSchema{
Extensions: map[string]interface{}{
"x-kubernetes-print-columns": "custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion",
},
......
......@@ -10,7 +10,6 @@ go_library(
name = "go_default_library",
srcs = [
"doc.go",
"document.go",
"extensions.go",
"openapi.go",
"openapi_getter.go",
......@@ -19,9 +18,9 @@ go_library(
deps = [
"//vendor/github.com/go-openapi/spec:go_default_library",
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......@@ -43,6 +42,7 @@ go_test(
"//vendor/github.com/onsi/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -17,236 +17,108 @@ limitations under the License.
package openapi
import (
"fmt"
"sort"
"strings"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Defines openapi types.
const (
Integer = "integer"
Number = "number"
String = "string"
Boolean = "boolean"
// These types are private as they should never leak, and are
// represented by actual structs.
array = "array"
object = "object"
"k8s.io/kube-openapi/pkg/util/proto"
)
// Resources interface describe a resources provider, that can give you
// resource based on group-version-kind.
type Resources interface {
LookupResource(gvk schema.GroupVersionKind) Schema
}
// SchemaVisitor is an interface that you need to implement if you want
// to "visit" an openapi schema. A dispatch on the Schema type will call
// the appropriate function based on its actual type:
// - Array is a list of one and only one given subtype
// - Map is a map of string to one and only one given subtype
// - Primitive can be string, integer, number and boolean.
// - Kind is an object with specific fields mapping to specific types.
// - Reference is a link to another definition.
type SchemaVisitor interface {
VisitArray(*Array)
VisitMap(*Map)
VisitPrimitive(*Primitive)
VisitKind(*Kind)
VisitReference(Reference)
LookupResource(gvk schema.GroupVersionKind) proto.Schema
}
// Schema is the base definition of an openapi type.
type Schema interface {
// Giving a visitor here will let you visit the actual type.
Accept(SchemaVisitor)
// Pretty print the name of the type.
GetName() string
// Describes how to access this field.
GetPath() *Path
// Describes the field.
GetDescription() string
// Returns type extensions.
GetExtensions() map[string]interface{}
}
// groupVersionKindExtensionKey is the key used to lookup the
// GroupVersionKind value for an object definition from the
// definition's "extensions" map.
const groupVersionKindExtensionKey = "x-kubernetes-group-version-kind"
// Path helps us keep track of type paths
type Path struct {
parent *Path
key string
// document is an implementation of `Resources`. It looks for
// resources in an openapi Schema.
type document struct {
// Maps gvk to model name
resources map[schema.GroupVersionKind]string
models proto.Models
}
func NewPath(key string) Path {
return Path{key: key}
}
var _ Resources = &document{}
func (p *Path) Get() []string {
if p == nil {
return []string{}
func NewOpenAPIData(doc *openapi_v2.Document) (Resources, error) {
models, err := proto.NewOpenAPIData(doc)
if err != nil {
return nil, err
}
if p.key == "" {
return p.parent.Get()
}
return append(p.parent.Get(), p.key)
}
func (p *Path) Len() int {
return len(p.Get())
}
func (p *Path) String() string {
return strings.Join(p.Get(), "")
}
// ArrayPath appends an array index and creates a new path
func (p *Path) ArrayPath(i int) Path {
return Path{
parent: p,
key: fmt.Sprintf("[%d]", i),
}
}
// FieldPath appends a field name and creates a new path
func (p *Path) FieldPath(field string) Path {
return Path{
parent: p,
key: fmt.Sprintf(".%s", field),
resources := map[schema.GroupVersionKind]string{}
for _, modelName := range models.ListModels() {
model := models.LookupModel(modelName)
if model == nil {
panic("ListModels returns a model that can't be looked-up.")
}
gvk := parseGroupVersionKind(model)
if len(gvk.Kind) > 0 {
resources[gvk] = modelName
}
}
}
// BaseSchema holds data used by each types of schema.
type BaseSchema struct {
Description string
Extensions map[string]interface{}
Path Path
}
func (b *BaseSchema) GetDescription() string {
return b.Description
}
func (b *BaseSchema) GetExtensions() map[string]interface{} {
return b.Extensions
}
func (b *BaseSchema) GetPath() *Path {
return &b.Path
}
// Array must have all its element of the same `SubType`.
type Array struct {
BaseSchema
SubType Schema
}
var _ Schema = &Array{}
func (a *Array) Accept(v SchemaVisitor) {
v.VisitArray(a)
}
func (a *Array) GetName() string {
return fmt.Sprintf("Array of %s", a.SubType.GetName())
return &document{
resources: resources,
models: models,
}, nil
}
// Kind is a complex object. It can have multiple different
// subtypes for each field, as defined in the `Fields` field. Mandatory
// fields are listed in `RequiredFields`. The key of the object is
// always of type `string`.
type Kind struct {
BaseSchema
// Lists names of required fields.
RequiredFields []string
// Maps field names to types.
Fields map[string]Schema
func (d *document) LookupResource(gvk schema.GroupVersionKind) proto.Schema {
modelName, found := d.resources[gvk]
if !found {
return nil
}
return d.models.LookupModel(modelName)
}
var _ Schema = &Kind{}
// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one.
func parseGroupVersionKind(s proto.Schema) schema.GroupVersionKind {
extensions := s.GetExtensions()
func (k *Kind) Accept(v SchemaVisitor) {
v.VisitKind(k)
}
func (k *Kind) GetName() string {
properties := []string{}
for key := range k.Fields {
properties = append(properties, key)
// Get the extensions
gvkExtension, ok := extensions[groupVersionKindExtensionKey]
if !ok {
return schema.GroupVersionKind{}
}
return fmt.Sprintf("Kind(%v)", properties)
}
// IsRequired returns true if `field` is a required field for this type.
func (k *Kind) IsRequired(field string) bool {
for _, f := range k.RequiredFields {
if f == field {
return true
}
// gvk extension must be a list of 1 element.
gvkList, ok := gvkExtension.([]interface{})
if !ok {
return schema.GroupVersionKind{}
}
return false
}
if len(gvkList) != 1 {
return schema.GroupVersionKind{}
// Keys returns a alphabetically sorted list of keys.
func (k *Kind) Keys() []string {
keys := make([]string, 0)
for key := range k.Fields {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
// Map is an object who values must all be of the same `SubType`.
// The key of the object is always of type `string`.
type Map struct {
BaseSchema
SubType Schema
}
var _ Schema = &Map{}
func (m *Map) Accept(v SchemaVisitor) {
v.VisitMap(m)
}
func (m *Map) GetName() string {
return fmt.Sprintf("Map of %s", m.SubType.GetName())
}
// Primitive is a literal. There can be multiple types of primitives,
// and this subtype can be visited through the `subType` field.
type Primitive struct {
BaseSchema
gvk := gvkList[0]
// Type of a primitive must be one of: integer, number, string, boolean.
Type string
Format string
}
var _ Schema = &Primitive{}
func (p *Primitive) Accept(v SchemaVisitor) {
v.VisitPrimitive(p)
}
func (p *Primitive) GetName() string {
if p.Format == "" {
return p.Type
// gvk extension list must be a map with group, version, and
// kind fields
gvkMap, ok := gvk.(map[interface{}]interface{})
if !ok {
return schema.GroupVersionKind{}
}
group, ok := gvkMap["group"].(string)
if !ok {
return schema.GroupVersionKind{}
}
version, ok := gvkMap["version"].(string)
if !ok {
return schema.GroupVersionKind{}
}
kind, ok := gvkMap["kind"].(string)
if !ok {
return schema.GroupVersionKind{}
}
return fmt.Sprintf("%s (%s)", p.Type, p.Format)
}
// Reference implementation depends on the type of document.
type Reference interface {
Schema
Reference() string
SubSchema() Schema
return schema.GroupVersionKind{
Group: group,
Version: version,
Kind: kind,
}
}
......@@ -23,6 +23,7 @@ import (
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
)
......@@ -44,98 +45,17 @@ var _ = Describe("Reading apps/v1beta1/Deployment from openAPIData", func() {
Group: "apps",
}
var schema openapi.Schema
var schema proto.Schema
It("should lookup the Schema by its GroupVersionKind", func() {
schema = resources.LookupResource(gvk)
Expect(schema).ToNot(BeNil())
})
var deployment *openapi.Kind
var deployment *proto.Kind
It("should be a Kind", func() {
deployment = schema.(*openapi.Kind)
deployment = schema.(*proto.Kind)
Expect(deployment).ToNot(BeNil())
})
It("should have a path", func() {
Expect(deployment.GetPath().Get()).To(Equal([]string{"io.k8s.api.apps.v1beta1.Deployment"}))
})
It("should have a kind key of type string", func() {
Expect(deployment.Fields).To(HaveKey("kind"))
key := deployment.Fields["kind"].(*openapi.Primitive)
Expect(key).ToNot(BeNil())
Expect(key.Type).To(Equal("string"))
Expect(key.GetPath().Get()).To(Equal([]string{"io.k8s.api.apps.v1beta1.Deployment", ".kind"}))
})
It("should have a apiVersion key of type string", func() {
Expect(deployment.Fields).To(HaveKey("apiVersion"))
key := deployment.Fields["apiVersion"].(*openapi.Primitive)
Expect(key).ToNot(BeNil())
Expect(key.Type).To(Equal("string"))
Expect(key.GetPath().Get()).To(Equal([]string{"io.k8s.api.apps.v1beta1.Deployment", ".apiVersion"}))
})
It("should have a metadata key of type Reference", func() {
Expect(deployment.Fields).To(HaveKey("metadata"))
key := deployment.Fields["metadata"].(openapi.Reference)
Expect(key).ToNot(BeNil())
Expect(key.Reference()).To(Equal("io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"))
subSchema := key.SubSchema().(*openapi.Kind)
Expect(subSchema).ToNot(BeNil())
})
var status *openapi.Kind
It("should have a status key of type Reference", func() {
Expect(deployment.Fields).To(HaveKey("status"))
key := deployment.Fields["status"].(openapi.Reference)
Expect(key).ToNot(BeNil())
Expect(key.Reference()).To(Equal("io.k8s.api.apps.v1beta1.DeploymentStatus"))
status = key.SubSchema().(*openapi.Kind)
Expect(status).ToNot(BeNil())
})
It("should have a valid DeploymentStatus", func() {
By("having availableReplicas key")
Expect(status.Fields).To(HaveKey("availableReplicas"))
replicas := status.Fields["availableReplicas"].(*openapi.Primitive)
Expect(replicas).ToNot(BeNil())
Expect(replicas.Type).To(Equal("integer"))
By("having conditions key")
Expect(status.Fields).To(HaveKey("conditions"))
conditions := status.Fields["conditions"].(*openapi.Array)
Expect(conditions).ToNot(BeNil())
Expect(conditions.GetName()).To(Equal(`Array of Reference to "io.k8s.api.apps.v1beta1.DeploymentCondition"`))
Expect(conditions.GetExtensions()).To(Equal(map[string]interface{}{
"x-kubernetes-patch-merge-key": "type",
"x-kubernetes-patch-strategy": "merge",
}))
condition := conditions.SubType.(openapi.Reference)
Expect(condition.Reference()).To(Equal("io.k8s.api.apps.v1beta1.DeploymentCondition"))
})
var spec *openapi.Kind
It("should have a spec key of type Reference", func() {
Expect(deployment.Fields).To(HaveKey("spec"))
key := deployment.Fields["spec"].(openapi.Reference)
Expect(key).ToNot(BeNil())
Expect(key.Reference()).To(Equal("io.k8s.api.apps.v1beta1.DeploymentSpec"))
spec = key.SubSchema().(*openapi.Kind)
Expect(spec).ToNot(BeNil())
})
It("should have a spec with no gvk", func() {
_, found := spec.GetExtensions()["x-kubernetes-group-version-kind"]
Expect(found).To(BeFalse())
})
It("should have a spec with a PodTemplateSpec sub-field", func() {
Expect(spec.Fields).To(HaveKey("template"))
key := spec.Fields["template"].(openapi.Reference)
Expect(key).ToNot(BeNil())
Expect(key.Reference()).To(Equal("io.k8s.api.core.v1.PodTemplateSpec"))
})
})
var _ = Describe("Reading authorization.k8s.io/v1/SubjectAccessReview from openAPIData", func() {
......@@ -153,66 +73,21 @@ var _ = Describe("Reading authorization.k8s.io/v1/SubjectAccessReview from openA
Group: "authorization.k8s.io",
}
var schema openapi.Schema
var schema proto.Schema
It("should lookup the Schema by its GroupVersionKind", func() {
schema = resources.LookupResource(gvk)
Expect(schema).ToNot(BeNil())
})
var sarspec *openapi.Kind
var sarspec *proto.Kind
It("should be a Kind and have a spec", func() {
sar := schema.(*openapi.Kind)
sar := schema.(*proto.Kind)
Expect(sar).ToNot(BeNil())
Expect(sar.Fields).To(HaveKey("spec"))
specRef := sar.Fields["spec"].(openapi.Reference)
specRef := sar.Fields["spec"].(proto.Reference)
Expect(specRef).ToNot(BeNil())
Expect(specRef.Reference()).To(Equal("io.k8s.api.authorization.v1.SubjectAccessReviewSpec"))
sarspec = specRef.SubSchema().(*openapi.Kind)
sarspec = specRef.SubSchema().(*proto.Kind)
Expect(sarspec).ToNot(BeNil())
})
It("should have a valid SubjectAccessReviewSpec", func() {
Expect(sarspec.Fields).To(HaveKey("extra"))
extra := sarspec.Fields["extra"].(*openapi.Map)
Expect(extra).ToNot(BeNil())
Expect(extra.GetName()).To(Equal("Map of Array of string"))
Expect(extra.GetPath().Get()).To(Equal([]string{"io.k8s.api.authorization.v1.SubjectAccessReviewSpec", ".extra"}))
array := extra.SubType.(*openapi.Array)
Expect(array).ToNot(BeNil())
Expect(array.GetName()).To(Equal("Array of string"))
Expect(array.GetPath().Get()).To(Equal([]string{"io.k8s.api.authorization.v1.SubjectAccessReviewSpec", ".extra"}))
str := array.SubType.(*openapi.Primitive)
Expect(str).ToNot(BeNil())
Expect(str.Type).To(Equal("string"))
Expect(str.GetName()).To(Equal("string"))
Expect(str.GetPath().Get()).To(Equal([]string{"io.k8s.api.authorization.v1.SubjectAccessReviewSpec", ".extra"}))
})
})
var _ = Describe("Path", func() {
It("can be created by NewPath", func() {
path := openapi.NewPath("key")
Expect(path.String()).To(Equal("key"))
})
It("can create and print complex paths", func() {
key := openapi.NewPath("key")
array := key.ArrayPath(12)
field := array.FieldPath("subKey")
Expect(field.String()).To(Equal("key[12].subKey"))
})
It("has a length", func() {
key := openapi.NewPath("key")
array := key.ArrayPath(12)
field := array.FieldPath("subKey")
Expect(field.Len()).To(Equal(3))
})
It("can look like an array", func() {
key := openapi.NewPath("key")
array := key.ArrayPath(12)
field := array.FieldPath("subKey")
Expect(field.Get()).To(Equal([]string{"key", "[12]", ".subKey"}))
})
})
......@@ -15,6 +15,7 @@ go_library(
"//vendor/github.com/googleapis/gnostic/compiler:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -22,6 +22,7 @@ import (
"sync"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
yaml "gopkg.in/yaml.v2"
......@@ -109,7 +110,7 @@ func NewFakeResources(path string) *FakeResources {
// LookupResource will read the schema, parse it and return the
// resources. It doesn't return errors and will panic instead.
func (f *FakeResources) LookupResource(gvk schema.GroupVersionKind) openapi.Schema {
func (f *FakeResources) LookupResource(gvk schema.GroupVersionKind) proto.Schema {
s, err := f.fake.OpenAPISchema()
if err != nil {
panic(err)
......
......@@ -20,6 +20,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -20,19 +20,19 @@ import (
"reflect"
"sort"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kube-openapi/pkg/util/proto"
)
type ValidationItem interface {
openapi.SchemaVisitor
proto.SchemaVisitor
Errors() []error
Path() *openapi.Path
Path() *proto.Path
}
type baseItem struct {
errors Errors
path openapi.Path
path proto.Path
}
// Errors returns the list of errors found for this item.
......@@ -58,7 +58,7 @@ func (item *baseItem) CopyErrors(errs []error) {
}
// Path returns the path of this item, helps print useful errors.
func (item *baseItem) Path() *openapi.Path {
func (item *baseItem) Path() *proto.Path {
return &item.path
}
......@@ -80,15 +80,15 @@ func (item *mapItem) sortedKeys() []string {
var _ ValidationItem = &mapItem{}
func (item *mapItem) VisitPrimitive(schema *openapi.Primitive) {
func (item *mapItem) VisitPrimitive(schema *proto.Primitive) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: schema.Type, Actual: "map"})
}
func (item *mapItem) VisitArray(schema *openapi.Array) {
func (item *mapItem) VisitArray(schema *proto.Array) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "array", Actual: "map"})
}
func (item *mapItem) VisitMap(schema *openapi.Map) {
func (item *mapItem) VisitMap(schema *proto.Map) {
for _, key := range item.sortedKeys() {
subItem, err := itemFactory(item.Path().FieldPath(key), item.Map[key])
if err != nil {
......@@ -100,7 +100,7 @@ func (item *mapItem) VisitMap(schema *openapi.Map) {
}
}
func (item *mapItem) VisitKind(schema *openapi.Kind) {
func (item *mapItem) VisitKind(schema *proto.Kind) {
// Verify each sub-field.
for _, key := range item.sortedKeys() {
if item.Map[key] == nil {
......@@ -127,7 +127,7 @@ func (item *mapItem) VisitKind(schema *openapi.Kind) {
}
}
func (item *mapItem) VisitReference(schema openapi.Reference) {
func (item *mapItem) VisitReference(schema proto.Reference) {
// passthrough
schema.SubSchema().Accept(item)
}
......@@ -141,11 +141,11 @@ type arrayItem struct {
var _ ValidationItem = &arrayItem{}
func (item *arrayItem) VisitPrimitive(schema *openapi.Primitive) {
func (item *arrayItem) VisitPrimitive(schema *proto.Primitive) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: schema.Type, Actual: "array"})
}
func (item *arrayItem) VisitArray(schema *openapi.Array) {
func (item *arrayItem) VisitArray(schema *proto.Array) {
for i, v := range item.Array {
path := item.Path().ArrayPath(i)
if v == nil {
......@@ -162,15 +162,15 @@ func (item *arrayItem) VisitArray(schema *openapi.Array) {
}
}
func (item *arrayItem) VisitMap(schema *openapi.Map) {
func (item *arrayItem) VisitMap(schema *proto.Map) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "array", Actual: "map"})
}
func (item *arrayItem) VisitKind(schema *openapi.Kind) {
func (item *arrayItem) VisitKind(schema *proto.Kind) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "array", Actual: "map"})
}
func (item *arrayItem) VisitReference(schema openapi.Reference) {
func (item *arrayItem) VisitReference(schema proto.Reference) {
// passthrough
schema.SubSchema().Accept(item)
}
......@@ -185,54 +185,54 @@ type primitiveItem struct {
var _ ValidationItem = &primitiveItem{}
func (item *primitiveItem) VisitPrimitive(schema *openapi.Primitive) {
func (item *primitiveItem) VisitPrimitive(schema *proto.Primitive) {
// Some types of primitives can match more than one (a number
// can be a string, but not the other way around). Return from
// the switch if we have a valid possible type conversion
// NOTE(apelisse): This logic is blindly copied from the
// existing swagger logic, and I'm not sure I agree with it.
switch schema.Type {
case openapi.Boolean:
case proto.Boolean:
switch item.Kind {
case openapi.Boolean:
case proto.Boolean:
return
}
case openapi.Integer:
case proto.Integer:
switch item.Kind {
case openapi.Integer, openapi.Number:
case proto.Integer, proto.Number:
return
}
case openapi.Number:
case proto.Number:
switch item.Kind {
case openapi.Number:
case proto.Number:
return
}
case openapi.String:
case proto.String:
return
}
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: schema.Type, Actual: item.Kind})
}
func (item *primitiveItem) VisitArray(schema *openapi.Array) {
func (item *primitiveItem) VisitArray(schema *proto.Array) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "array", Actual: item.Kind})
}
func (item *primitiveItem) VisitMap(schema *openapi.Map) {
func (item *primitiveItem) VisitMap(schema *proto.Map) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "map", Actual: item.Kind})
}
func (item *primitiveItem) VisitKind(schema *openapi.Kind) {
func (item *primitiveItem) VisitKind(schema *proto.Kind) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: "map", Actual: item.Kind})
}
func (item *primitiveItem) VisitReference(schema openapi.Reference) {
func (item *primitiveItem) VisitReference(schema proto.Reference) {
// passthrough
schema.SubSchema().Accept(item)
}
// itemFactory creates the relevant item type/visitor based on the current yaml type.
func itemFactory(path openapi.Path, v interface{}) (ValidationItem, error) {
func itemFactory(path proto.Path, v interface{}) (ValidationItem, error) {
// We need to special case for no-type fields in yaml (e.g. empty item in list)
if v == nil {
return nil, InvalidObjectTypeError{Type: "nil", Path: path.String()}
......@@ -243,7 +243,7 @@ func itemFactory(path openapi.Path, v interface{}) (ValidationItem, error) {
return &primitiveItem{
baseItem: baseItem{path: path},
Value: v,
Kind: openapi.Boolean,
Kind: proto.Boolean,
}, nil
case reflect.Int,
reflect.Int8,
......@@ -258,20 +258,20 @@ func itemFactory(path openapi.Path, v interface{}) (ValidationItem, error) {
return &primitiveItem{
baseItem: baseItem{path: path},
Value: v,
Kind: openapi.Integer,
Kind: proto.Integer,
}, nil
case reflect.Float32,
reflect.Float64:
return &primitiveItem{
baseItem: baseItem{path: path},
Value: v,
Kind: openapi.Number,
Kind: proto.Number,
}, nil
case reflect.String:
return &primitiveItem{
baseItem: baseItem{path: path},
Value: v,
Kind: openapi.String,
Kind: proto.String,
}, nil
case reflect.Array,
reflect.Slice:
......
......@@ -24,6 +24,7 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
......@@ -79,7 +80,7 @@ func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVer
return nil
}
rootValidation, err := itemFactory(openapi.NewPath(gvk.Kind), obj)
rootValidation, err := itemFactory(proto.NewPath(gvk.Kind), obj)
if err != nil {
return []error{err}
}
......
......@@ -15,8 +15,8 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubectl/explain",
visibility = ["//visibility:public"],
deps = [
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -21,11 +21,11 @@ import (
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kube-openapi/pkg/util/proto"
)
type fieldsPrinter interface {
PrintFields(openapi.Schema) error
PrintFields(proto.Schema) error
}
func splitDotNotation(model string) (string, []string) {
......@@ -47,7 +47,7 @@ func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (st
// PrintModelDescription prints the description of a specific model or dot path.
// If recursive, all components nested within the fields of the schema will be
// printed.
func PrintModelDescription(fieldsPath []string, w io.Writer, schema openapi.Schema, recursive bool) error {
func PrintModelDescription(fieldsPath []string, w io.Writer, schema proto.Schema, recursive bool) error {
fieldName := ""
if len(fieldsPath) != 0 {
fieldName = fieldsPath[len(fieldsPath)-1]
......
......@@ -19,7 +19,7 @@ package explain
import (
"fmt"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kube-openapi/pkg/util/proto"
)
// fieldLookup walks through a schema by following a path, and returns
......@@ -29,13 +29,13 @@ type fieldLookup struct {
Path []string
// Return information: Schema found, or error.
Schema openapi.Schema
Schema proto.Schema
Error error
}
// SaveLeafSchema is used to detect if we are done walking the path, and
// saves the schema as a match.
func (f *fieldLookup) SaveLeafSchema(schema openapi.Schema) bool {
func (f *fieldLookup) SaveLeafSchema(schema proto.Schema) bool {
if len(f.Path) != 0 {
return false
}
......@@ -46,7 +46,7 @@ func (f *fieldLookup) SaveLeafSchema(schema openapi.Schema) bool {
}
// VisitArray is mostly a passthrough.
func (f *fieldLookup) VisitArray(a *openapi.Array) {
func (f *fieldLookup) VisitArray(a *proto.Array) {
if f.SaveLeafSchema(a) {
return
}
......@@ -56,7 +56,7 @@ func (f *fieldLookup) VisitArray(a *openapi.Array) {
}
// VisitMap is mostly a passthrough.
func (f *fieldLookup) VisitMap(m *openapi.Map) {
func (f *fieldLookup) VisitMap(m *proto.Map) {
if f.SaveLeafSchema(m) {
return
}
......@@ -67,14 +67,14 @@ func (f *fieldLookup) VisitMap(m *openapi.Map) {
// VisitPrimitive stops the operation and returns itself as the found
// schema, even if it had more path to walk.
func (f *fieldLookup) VisitPrimitive(p *openapi.Primitive) {
func (f *fieldLookup) VisitPrimitive(p *proto.Primitive) {
// Even if Path is not empty (we're not expecting a leaf),
// return that primitive.
f.Schema = p
}
// VisitKind unstacks fields as it finds them.
func (f *fieldLookup) VisitKind(k *openapi.Kind) {
func (f *fieldLookup) VisitKind(k *proto.Kind) {
if f.SaveLeafSchema(k) {
return
}
......@@ -90,7 +90,7 @@ func (f *fieldLookup) VisitKind(k *openapi.Kind) {
}
// VisitReference is mostly a passthrough.
func (f *fieldLookup) VisitReference(r openapi.Reference) {
func (f *fieldLookup) VisitReference(r proto.Reference) {
if f.SaveLeafSchema(r) {
return
}
......@@ -100,7 +100,7 @@ func (f *fieldLookup) VisitReference(r openapi.Reference) {
}
// LookupSchemaForField looks for the schema of a given path in a base schema.
func LookupSchemaForField(schema openapi.Schema, path []string) (openapi.Schema, error) {
func LookupSchemaForField(schema proto.Schema, path []string) (proto.Schema, error) {
f := &fieldLookup{Path: path}
schema.Accept(f)
return f.Schema, f.Error
......
......@@ -16,9 +16,7 @@ limitations under the License.
package explain
import (
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
import "k8s.io/kube-openapi/pkg/util/proto"
// indentDesc is the level of indentation for descriptions.
const indentDesc = 2
......@@ -29,17 +27,17 @@ type regularFieldsPrinter struct {
Error error
}
var _ openapi.SchemaVisitor = &regularFieldsPrinter{}
var _ proto.SchemaVisitor = &regularFieldsPrinter{}
var _ fieldsPrinter = &regularFieldsPrinter{}
// VisitArray prints a Array type. It is just a passthrough.
func (f *regularFieldsPrinter) VisitArray(a *openapi.Array) {
func (f *regularFieldsPrinter) VisitArray(a *proto.Array) {
a.SubType.Accept(f)
}
// VisitKind prints a Kind type. It prints each key in the kind, with
// the type, the required flag, and the description.
func (f *regularFieldsPrinter) VisitKind(k *openapi.Kind) {
func (f *regularFieldsPrinter) VisitKind(k *proto.Kind) {
for _, key := range k.Keys() {
v := k.Fields[key]
required := ""
......@@ -63,22 +61,22 @@ func (f *regularFieldsPrinter) VisitKind(k *openapi.Kind) {
}
// VisitMap prints a Map type. It is just a passthrough.
func (f *regularFieldsPrinter) VisitMap(m *openapi.Map) {
func (f *regularFieldsPrinter) VisitMap(m *proto.Map) {
m.SubType.Accept(f)
}
// VisitPrimitive prints a Primitive type. It stops the recursion.
func (f *regularFieldsPrinter) VisitPrimitive(p *openapi.Primitive) {
func (f *regularFieldsPrinter) VisitPrimitive(p *proto.Primitive) {
// Nothing to do. Shouldn't really happen.
}
// VisitReference prints a Reference type. It is just a passthrough.
func (f *regularFieldsPrinter) VisitReference(r openapi.Reference) {
func (f *regularFieldsPrinter) VisitReference(r proto.Reference) {
r.SubSchema().Accept(f)
}
// PrintFields will write the types from schema.
func (f *regularFieldsPrinter) PrintFields(schema openapi.Schema) error {
func (f *regularFieldsPrinter) PrintFields(schema proto.Schema) error {
schema.Accept(f)
return f.Error
}
......@@ -16,9 +16,7 @@ limitations under the License.
package explain
import (
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
import "k8s.io/kube-openapi/pkg/util/proto"
// fieldIndentLevel is the level of indentation for fields.
const fieldIndentLevel = 3
......@@ -38,12 +36,12 @@ type modelPrinter struct {
Error error
}
var _ openapi.SchemaVisitor = &modelPrinter{}
var _ proto.SchemaVisitor = &modelPrinter{}
// PrintDescription prints the description for a given schema. There
// might be multiple description, since we collect descriptions when we
// go through references, arrays and maps.
func (m *modelPrinter) PrintDescription(schema openapi.Schema) error {
func (m *modelPrinter) PrintDescription(schema proto.Schema) error {
if err := m.Writer.Write("DESCRIPTION:"); err != nil {
return err
}
......@@ -65,7 +63,7 @@ func (m *modelPrinter) PrintDescription(schema openapi.Schema) error {
// VisitArray recurses inside the subtype, while collecting the type if
// not done yet, and the description.
func (m *modelPrinter) VisitArray(a *openapi.Array) {
func (m *modelPrinter) VisitArray(a *proto.Array) {
m.Descriptions = append(m.Descriptions, a.GetDescription())
if m.Type == "" {
m.Type = GetTypeName(a)
......@@ -74,7 +72,7 @@ func (m *modelPrinter) VisitArray(a *openapi.Array) {
}
// VisitKind prints a full resource with its fields.
func (m *modelPrinter) VisitKind(k *openapi.Kind) {
func (m *modelPrinter) VisitKind(k *proto.Kind) {
if m.Type == "" {
m.Type = GetTypeName(k)
}
......@@ -95,7 +93,7 @@ func (m *modelPrinter) VisitKind(k *openapi.Kind) {
// VisitMap recurses inside the subtype, while collecting the type if
// not done yet, and the description.
func (m *modelPrinter) VisitMap(om *openapi.Map) {
func (m *modelPrinter) VisitMap(om *proto.Map) {
m.Descriptions = append(m.Descriptions, om.GetDescription())
if m.Type == "" {
m.Type = GetTypeName(om)
......@@ -104,7 +102,7 @@ func (m *modelPrinter) VisitMap(om *openapi.Map) {
}
// VisitPrimitive prints a field type and its description.
func (m *modelPrinter) VisitPrimitive(p *openapi.Primitive) {
func (m *modelPrinter) VisitPrimitive(p *proto.Primitive) {
if m.Type == "" {
m.Type = GetTypeName(p)
}
......@@ -116,13 +114,13 @@ func (m *modelPrinter) VisitPrimitive(p *openapi.Primitive) {
}
// VisitReference recurses inside the subtype, while collecting the description.
func (m *modelPrinter) VisitReference(r openapi.Reference) {
func (m *modelPrinter) VisitReference(r proto.Reference) {
m.Descriptions = append(m.Descriptions, r.GetDescription())
r.SubSchema().Accept(m)
}
// PrintModel prints the description of a schema in writer.
func PrintModel(name string, writer *Formatter, builder fieldsPrinterBuilder, schema openapi.Schema) error {
func PrintModel(name string, writer *Formatter, builder fieldsPrinterBuilder, schema proto.Schema) error {
m := &modelPrinter{Name: name, Writer: writer, Builder: builder}
schema.Accept(m)
return m.Error
......
......@@ -16,9 +16,7 @@ limitations under the License.
package explain
import (
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
import "k8s.io/kube-openapi/pkg/util/proto"
// indentPerLevel is the level of indentation for each field recursion.
const indentPerLevel = 3
......@@ -30,17 +28,17 @@ type recursiveFieldsPrinter struct {
Error error
}
var _ openapi.SchemaVisitor = &recursiveFieldsPrinter{}
var _ proto.SchemaVisitor = &recursiveFieldsPrinter{}
var _ fieldsPrinter = &recursiveFieldsPrinter{}
// VisitArray is just a passthrough.
func (f *recursiveFieldsPrinter) VisitArray(a *openapi.Array) {
func (f *recursiveFieldsPrinter) VisitArray(a *proto.Array) {
a.SubType.Accept(f)
}
// VisitKind prints all its fields with their type, and then recurses
// inside each of these (pre-order).
func (f *recursiveFieldsPrinter) VisitKind(k *openapi.Kind) {
func (f *recursiveFieldsPrinter) VisitKind(k *proto.Kind) {
for _, key := range k.Keys() {
v := k.Fields[key]
f.Writer.Write("%s\t<%s>", key, GetTypeName(v))
......@@ -55,23 +53,23 @@ func (f *recursiveFieldsPrinter) VisitKind(k *openapi.Kind) {
}
// VisitMap is just a passthrough.
func (f *recursiveFieldsPrinter) VisitMap(m *openapi.Map) {
func (f *recursiveFieldsPrinter) VisitMap(m *proto.Map) {
m.SubType.Accept(f)
}
// VisitPrimitive does nothing, since it doesn't have sub-fields.
func (f *recursiveFieldsPrinter) VisitPrimitive(p *openapi.Primitive) {
func (f *recursiveFieldsPrinter) VisitPrimitive(p *proto.Primitive) {
// Nothing to do.
}
// VisitReference is just a passthrough.
func (f *recursiveFieldsPrinter) VisitReference(r openapi.Reference) {
func (f *recursiveFieldsPrinter) VisitReference(r proto.Reference) {
r.SubSchema().Accept(f)
}
// PrintFields will recursively print all the fields for the given
// schema.
func (f *recursiveFieldsPrinter) PrintFields(schema openapi.Schema) error {
func (f *recursiveFieldsPrinter) PrintFields(schema proto.Schema) error {
schema.Accept(f)
return f.Error
}
......@@ -19,7 +19,7 @@ package explain
import (
"fmt"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kube-openapi/pkg/util/proto"
)
// typeName finds the name of a schema
......@@ -27,39 +27,39 @@ type typeName struct {
Name string
}
var _ openapi.SchemaVisitor = &typeName{}
var _ proto.SchemaVisitor = &typeName{}
// VisitArray adds the [] prefix and recurses.
func (t *typeName) VisitArray(a *openapi.Array) {
func (t *typeName) VisitArray(a *proto.Array) {
s := &typeName{}
a.SubType.Accept(s)
t.Name = fmt.Sprintf("[]%s", s.Name)
}
// VisitKind just returns "Object".
func (t *typeName) VisitKind(k *openapi.Kind) {
func (t *typeName) VisitKind(k *proto.Kind) {
t.Name = "Object"
}
// VisitMap adds the map[string] prefix and recurses.
func (t *typeName) VisitMap(m *openapi.Map) {
func (t *typeName) VisitMap(m *proto.Map) {
s := &typeName{}
m.SubType.Accept(s)
t.Name = fmt.Sprintf("map[string]%s", s.Name)
}
// VisitPrimitive returns the name of the primitive.
func (t *typeName) VisitPrimitive(p *openapi.Primitive) {
func (t *typeName) VisitPrimitive(p *proto.Primitive) {
t.Name = p.Type
}
// VisitReference is just a passthrough.
func (t *typeName) VisitReference(r openapi.Reference) {
func (t *typeName) VisitReference(r proto.Reference) {
r.SubSchema().Accept(t)
}
// GetTypeName returns the type of a schema.
func GetTypeName(schema openapi.Schema) string {
func GetTypeName(schema proto.Schema) string {
t := &typeName{}
schema.Accept(t)
return t.Name
......
{
"ImportPath": "k8s.io/api",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -216,7 +216,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
......
{
"ImportPath": "k8s.io/apiextensions-apiserver",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -1548,19 +1548,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
......
{
"ImportPath": "k8s.io/apimachinery",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -216,7 +216,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/apiserver",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -1608,19 +1608,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/client-go/discovery",
......
{
"ImportPath": "k8s.io/client-go",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -672,7 +672,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/code-generator",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -252,11 +252,11 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/kube-aggregator",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -1536,23 +1536,23 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/metrics",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -520,7 +520,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/sample-apiserver",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -1524,19 +1524,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
{
"ImportPath": "k8s.io/sample-controller",
"GoVersion": "go1.8",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"Packages": [
"./..."
......@@ -940,7 +940,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
"Rev": "89ae48fe8691077463af5b7fb3b6f194632c5946"
}
]
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["auth.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["auth.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["auth.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = [
"etcdserver.proto",
"raft_internal.proto",
"rpc.proto",
],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -24,16 +34,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = [
"etcdserver.proto",
"raft_internal.proto",
"rpc.proto",
],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["lease.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["lease.pb.go"],
......@@ -12,12 +18,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["lease.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["kv.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["kv.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["kv.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["raft.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["raft.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["raft.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["snap.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["snap.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["snap.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["record.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -12,12 +18,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["record.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["api.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["api.pb.go"],
......@@ -13,12 +19,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["api.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["gogo.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -16,12 +22,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["gogo.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["any.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["any.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["any.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["duration.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["duration.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["duration.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["timestamp.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["timestamp.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["timestamp.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["OpenAPIv2.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -17,12 +23,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["OpenAPIv2.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["extension.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -16,12 +22,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["extension.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["stream_chunk.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["stream_chunk.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["stream_chunk.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["api.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = [
......@@ -17,12 +23,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["api.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["criurpc.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["criurpc.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["criurpc.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "go_default_library_protos",
srcs = ["grpclb.proto"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["grpclb.pb.go"],
......@@ -9,12 +15,6 @@ go_library(
)
filegroup(
name = "go_default_library_protos",
srcs = ["grpclb.proto"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
......
......@@ -89,6 +89,30 @@ type Config struct {
DefaultSecurity []map[string][]string
}
var schemaTypeFormatMap = map[string][]string{
"uint": {"integer", "int32"},
"uint8": {"integer", "byte"},
"uint16": {"integer", "int32"},
"uint32": {"integer", "int64"},
"uint64": {"integer", "int64"},
"int": {"integer", "int32"},
"int8": {"integer", "byte"},
"int16": {"integer", "int32"},
"int32": {"integer", "int32"},
"int64": {"integer", "int64"},
"byte": {"integer", "byte"},
"float64": {"number", "double"},
"float32": {"number", "float"},
"bool": {"boolean", ""},
"time.Time": {"string", "date-time"},
"string": {"string", ""},
"integer": {"integer", ""},
"number": {"number", ""},
"boolean": {"boolean", ""},
"[]byte": {"string", "byte"}, // base64 encoded characters
"interface{}": {"object", ""},
}
// This function is a reference for converting go (or any custom type) to a simple open API type,format pair. There are
// two ways to customize spec for a type. If you add it here, a type will be converted to a simple type and the type
// comment (the comment that is added before type definition) will be lost. The spec will still have the property
......@@ -129,29 +153,6 @@ type Config struct {
// }
//
func GetOpenAPITypeFormat(typeName string) (string, string) {
schemaTypeFormatMap := map[string][]string{
"uint": {"integer", "int32"},
"uint8": {"integer", "byte"},
"uint16": {"integer", "int32"},
"uint32": {"integer", "int64"},
"uint64": {"integer", "int64"},
"int": {"integer", "int32"},
"int8": {"integer", "byte"},
"int16": {"integer", "int32"},
"int32": {"integer", "int32"},
"int64": {"integer", "int64"},
"byte": {"integer", "byte"},
"float64": {"number", "double"},
"float32": {"number", "float"},
"bool": {"boolean", ""},
"time.Time": {"string", "date-time"},
"string": {"string", ""},
"integer": {"integer", ""},
"number": {"number", ""},
"boolean": {"boolean", ""},
"[]byte": {"string", "byte"}, // base64 encoded characters
"interface{}": {"object", ""},
}
mapped, ok := schemaTypeFormatMap[typeName]
if !ok {
return "", ""
......
......@@ -16,7 +16,10 @@ filegroup(
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
srcs = [
":package-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"document.go",
"openapi.go",
],
importpath = "k8s.io/kube-openapi/pkg/util/proto",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package proto is a collection of libraries for parsing and indexing the type definitions.
// The openapi spec contains the object model definitions and extensions metadata.
package proto
......@@ -14,16 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package openapi
package proto
import (
"fmt"
"sort"
"strings"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
yaml "gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func newSchemaError(path *Path, format string, a ...interface{}) error {
......@@ -34,12 +33,8 @@ func newSchemaError(path *Path, format string, a ...interface{}) error {
return fmt.Errorf("SchemaError(%v): %v", path, err)
}
// groupVersionKindExtensionKey is the key used to lookup the
// GroupVersionKind value for an object definition from the
// definition's "extensions" map.
const groupVersionKindExtensionKey = "x-kubernetes-group-version-kind"
func vendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
// VendorExtensionToMap converts openapi VendorExtension to a map.
func VendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
values := map[string]interface{}{}
for _, na := range e {
......@@ -61,67 +56,18 @@ func vendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
return values
}
// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one.
func parseGroupVersionKind(s *openapi_v2.Schema) schema.GroupVersionKind {
extensionMap := vendorExtensionToMap(s.GetVendorExtension())
// Get the extensions
gvkExtension, ok := extensionMap[groupVersionKindExtensionKey]
if !ok {
return schema.GroupVersionKind{}
}
// gvk extension must be a list of 1 element.
gvkList, ok := gvkExtension.([]interface{})
if !ok {
return schema.GroupVersionKind{}
}
if len(gvkList) != 1 {
return schema.GroupVersionKind{}
}
gvk := gvkList[0]
// gvk extension list must be a map with group, version, and
// kind fields
gvkMap, ok := gvk.(map[interface{}]interface{})
if !ok {
return schema.GroupVersionKind{}
}
group, ok := gvkMap["group"].(string)
if !ok {
return schema.GroupVersionKind{}
}
version, ok := gvkMap["version"].(string)
if !ok {
return schema.GroupVersionKind{}
}
kind, ok := gvkMap["kind"].(string)
if !ok {
return schema.GroupVersionKind{}
}
return schema.GroupVersionKind{
Group: group,
Version: version,
Kind: kind,
}
}
// Definitions is an implementation of `Resources`. It looks for
// resources in an openapi Schema.
// Definitions is an implementation of `Models`. It looks for
// models in an openapi Schema.
type Definitions struct {
models map[string]Schema
resources map[schema.GroupVersionKind]string
models map[string]Schema
}
var _ Resources = &Definitions{}
var _ Models = &Definitions{}
// NewOpenAPIData creates a new `Resources` out of the openapi document.
func NewOpenAPIData(doc *openapi_v2.Document) (Resources, error) {
// NewOpenAPIData creates a new `Models` out of the openapi document.
func NewOpenAPIData(doc *openapi_v2.Document) (Models, error) {
definitions := Definitions{
models: map[string]Schema{},
resources: map[schema.GroupVersionKind]string{},
models: map[string]Schema{},
}
// Save the list of all models first. This will allow us to
......@@ -138,10 +84,6 @@ func NewOpenAPIData(doc *openapi_v2.Document) (Resources, error) {
return nil, err
}
definitions.models[namedSchema.GetName()] = schema
gvk := parseGroupVersionKind(namedSchema.GetValue())
if len(gvk.Kind) > 0 {
definitions.resources[gvk] = namedSchema.GetName()
}
}
return &definitions, nil
......@@ -174,7 +116,7 @@ func (d *Definitions) parseReference(s *openapi_v2.Schema, path *Path) (Schema,
func (d *Definitions) parseBaseSchema(s *openapi_v2.Schema, path *Path) BaseSchema {
return BaseSchema{
Description: s.GetDescription(),
Extensions: vendorExtensionToMap(s.GetVendorExtension()),
Extensions: VendorExtensionToMap(s.GetVendorExtension()),
Path: *path,
}
}
......@@ -290,18 +232,21 @@ func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, err
return d.parsePrimitive(s, path)
}
// LookupResource is public through the interface of Resources. It
// returns a visitable schema from the given group-version-kind.
func (d *Definitions) LookupResource(gvk schema.GroupVersionKind) Schema {
modelName, found := d.resources[gvk]
if !found {
return nil
}
model, found := d.models[modelName]
if !found {
return nil
// LookupModel is public through the interface of Models. It
// returns a visitable schema from the given model name.
func (d *Definitions) LookupModel(model string) Schema {
return d.models[model]
}
func (d *Definitions) ListModels() []string {
models := []string{}
for model := range d.models {
models = append(models, model)
}
return model
sort.Strings(models)
return models
}
type Ref struct {
......
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
import (
"fmt"
"sort"
"strings"
)
// Defines openapi types.
const (
Integer = "integer"
Number = "number"
String = "string"
Boolean = "boolean"
// These types are private as they should never leak, and are
// represented by actual structs.
array = "array"
object = "object"
)
// Models interface describe a model provider. They can give you the
// schema for a specific model.
type Models interface {
LookupModel(string) Schema
ListModels() []string
}
// SchemaVisitor is an interface that you need to implement if you want
// to "visit" an openapi schema. A dispatch on the Schema type will call
// the appropriate function based on its actual type:
// - Array is a list of one and only one given subtype
// - Map is a map of string to one and only one given subtype
// - Primitive can be string, integer, number and boolean.
// - Kind is an object with specific fields mapping to specific types.
// - Reference is a link to another definition.
type SchemaVisitor interface {
VisitArray(*Array)
VisitMap(*Map)
VisitPrimitive(*Primitive)
VisitKind(*Kind)
VisitReference(Reference)
}
// Schema is the base definition of an openapi type.
type Schema interface {
// Giving a visitor here will let you visit the actual type.
Accept(SchemaVisitor)
// Pretty print the name of the type.
GetName() string
// Describes how to access this field.
GetPath() *Path
// Describes the field.
GetDescription() string
// Returns type extensions.
GetExtensions() map[string]interface{}
}
// Path helps us keep track of type paths
type Path struct {
parent *Path
key string
}
func NewPath(key string) Path {
return Path{key: key}
}
func (p *Path) Get() []string {
if p == nil {
return []string{}
}
if p.key == "" {
return p.parent.Get()
}
return append(p.parent.Get(), p.key)
}
func (p *Path) Len() int {
return len(p.Get())
}
func (p *Path) String() string {
return strings.Join(p.Get(), "")
}
// ArrayPath appends an array index and creates a new path
func (p *Path) ArrayPath(i int) Path {
return Path{
parent: p,
key: fmt.Sprintf("[%d]", i),
}
}
// FieldPath appends a field name and creates a new path
func (p *Path) FieldPath(field string) Path {
return Path{
parent: p,
key: fmt.Sprintf(".%s", field),
}
}
// BaseSchema holds data used by each types of schema.
type BaseSchema struct {
Description string
Extensions map[string]interface{}
Path Path
}
func (b *BaseSchema) GetDescription() string {
return b.Description
}
func (b *BaseSchema) GetExtensions() map[string]interface{} {
return b.Extensions
}
func (b *BaseSchema) GetPath() *Path {
return &b.Path
}
// Array must have all its element of the same `SubType`.
type Array struct {
BaseSchema
SubType Schema
}
var _ Schema = &Array{}
func (a *Array) Accept(v SchemaVisitor) {
v.VisitArray(a)
}
func (a *Array) GetName() string {
return fmt.Sprintf("Array of %s", a.SubType.GetName())
}
// Kind is a complex object. It can have multiple different
// subtypes for each field, as defined in the `Fields` field. Mandatory
// fields are listed in `RequiredFields`. The key of the object is
// always of type `string`.
type Kind struct {
BaseSchema
// Lists names of required fields.
RequiredFields []string
// Maps field names to types.
Fields map[string]Schema
}
var _ Schema = &Kind{}
func (k *Kind) Accept(v SchemaVisitor) {
v.VisitKind(k)
}
func (k *Kind) GetName() string {
properties := []string{}
for key := range k.Fields {
properties = append(properties, key)
}
return fmt.Sprintf("Kind(%v)", properties)
}
// IsRequired returns true if `field` is a required field for this type.
func (k *Kind) IsRequired(field string) bool {
for _, f := range k.RequiredFields {
if f == field {
return true
}
}
return false
}
// Keys returns a alphabetically sorted list of keys.
func (k *Kind) Keys() []string {
keys := make([]string, 0)
for key := range k.Fields {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
// Map is an object who values must all be of the same `SubType`.
// The key of the object is always of type `string`.
type Map struct {
BaseSchema
SubType Schema
}
var _ Schema = &Map{}
func (m *Map) Accept(v SchemaVisitor) {
v.VisitMap(m)
}
func (m *Map) GetName() string {
return fmt.Sprintf("Map of %s", m.SubType.GetName())
}
// Primitive is a literal. There can be multiple types of primitives,
// and this subtype can be visited through the `subType` field.
type Primitive struct {
BaseSchema
// Type of a primitive must be one of: integer, number, string, boolean.
Type string
Format string
}
var _ Schema = &Primitive{}
func (p *Primitive) Accept(v SchemaVisitor) {
v.VisitPrimitive(p)
}
func (p *Primitive) GetName() string {
if p.Format == "" {
return p.Type
}
return fmt.Sprintf("%s (%s)", p.Type, p.Format)
}
// Reference implementation depends on the type of document.
type Reference interface {
Schema
Reference() string
SubSchema() Schema
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment