Commit c16ff84e authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #52042 from mengqiy/revert_update_vendor

Automatic merge from submit-queue Revert update vendor kube-openapi Revert https://github.com/kubernetes/kubernetes/pull/51762 since https://github.com/kubernetes/kubernetes/pull/51321 are not going to get in this release. Will revert https://github.com/kubernetes/kube-openapi/pull/10 after this PR merged. fixes: #52135 ```release-note NONE ``` /assign @apelisse @liggitt
parents 92e1f446 c17103f1
......@@ -3151,35 +3151,27 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto/testing",
"Rev": "76a6671bcfb1d229fc7fd543aee23ddff6b5fc7e"
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
},
{
"ImportPath": "k8s.io/utils/exec",
......
......@@ -203,6 +203,7 @@ go_test(
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/plugins:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library",
......@@ -236,7 +237,6 @@ 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",
],
)
......
......@@ -578,7 +578,7 @@ func outputOptsForMappingFromOpenAPI(f cmdutil.Factory, mapping *meta.RESTMappin
return nil, false
}
// Found openapi metadata for this resource
schema := api.LookupResource(mapping.GroupVersionKind.String())
schema := api.LookupResource(mapping.GroupVersionKind)
if schema == nil {
// Schema not found, return empty columns
return nil, false
......
......@@ -38,11 +38,11 @@ import (
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch"
openapi "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
apitesting "k8s.io/kubernetes/pkg/api/testing"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
......@@ -217,10 +217,10 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
}
type FakeResources struct {
resources map[string]openapi.Schema
resources map[schema.GroupVersionKind]openapi.Schema
}
func (f FakeResources) LookupResource(s string) openapi.Schema {
func (f FakeResources) LookupResource(s schema.GroupVersionKind) openapi.Schema {
return f.resources[s]
}
......@@ -228,11 +228,11 @@ var _ openapi.Resources = &FakeResources{}
func testOpenAPISchemaData() (openapi.Resources, error) {
return &FakeResources{
resources: map[string]openapi.Schema{
schema.GroupVersionKind{
resources: map[schema.GroupVersionKind]openapi.Schema{
{
Version: "v1",
Kind: "Pod",
}.String(): &openapi.Primitive{
}: &openapi.Primitive{
BaseSchema: openapi.BaseSchema{
Extensions: map[string]interface{}{
"x-kubernetes-print-columns": "custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion",
......
......@@ -19,6 +19,7 @@ go_library(
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/plugins:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/validation:go_default_library",
......@@ -37,7 +38,6 @@ go_library(
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......
......@@ -37,13 +37,13 @@ import (
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
openapi "k8s.io/kube-openapi/pkg/util/proto"
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/validation"
......
......@@ -71,7 +71,6 @@ go_library(
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/util/homedir:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
)
......
......@@ -46,13 +46,13 @@ import (
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
openapi "k8s.io/kube-openapi/pkg/util/proto"
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"k8s.io/kubernetes/pkg/api"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/validation"
......
......@@ -39,7 +39,6 @@ import (
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
restclient "k8s.io/client-go/rest"
oapi "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/federation/apis/federation"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/apps"
......@@ -459,7 +458,7 @@ func (f *ring1Factory) SwaggerSchema(gvk schema.GroupVersionKind) (*swagger.ApiD
}
// OpenAPISchema returns metadata and structural information about Kubernetes object definitions.
func (f *ring1Factory) OpenAPISchema() (oapi.Resources, error) {
func (f *ring1Factory) OpenAPISchema() (openapi.Resources, error) {
discovery, err := f.clientAccessFactory.DiscoveryClient()
if err != nil {
return nil, err
......
......@@ -10,16 +10,17 @@ go_library(
name = "go_default_library",
srcs = [
"doc.go",
"document.go",
"extensions.go",
"gvk.go",
"openapi.go",
"openapi_getter.go",
],
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",
],
)
......@@ -29,16 +30,17 @@ go_test(
srcs = [
"openapi_getter_test.go",
"openapi_suite_test.go",
"openapi_test.go",
],
data = ["//api/openapi-spec:swagger-spec"],
deps = [
":go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/ginkgo/config:go_default_library",
"//vendor/github.com/onsi/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
],
)
......@@ -53,6 +55,7 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/kubectl/cmd/util/openapi/testing:all-srcs",
"//pkg/kubectl/cmd/util/openapi/validation:all-srcs",
],
tags = ["automanaged"],
......
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
package openapi
import (
"fmt"
......@@ -22,6 +22,8 @@ import (
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 {
......@@ -32,8 +34,12 @@ func newSchemaError(path *Path, format string, a ...interface{}) error {
return fmt.Errorf("SchemaError(%v): %v", path, err)
}
// VendorExtensionToMap converts openapi VendorExtension to a map.
func VendorExtensionToMap(e []*openapi_v2.NamedAny) 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"
func vendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
values := map[string]interface{}{}
for _, na := range e {
......@@ -55,20 +61,67 @@ 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.
type Definitions struct {
models map[string]Schema
resources map[string]string
resources map[schema.GroupVersionKind]string
}
var _ Resources = &Definitions{}
// NewOpenAPIData creates a new `Resources` out of the openapi document.
func NewOpenAPIData(doc *openapi_v2.Document, getIdFromSchema func(s *openapi_v2.Schema) string) (Resources, error) {
func NewOpenAPIData(doc *openapi_v2.Document) (Resources, error) {
definitions := Definitions{
models: map[string]Schema{},
resources: map[string]string{},
resources: map[schema.GroupVersionKind]string{},
}
// Save the list of all models first. This will allow us to
......@@ -85,8 +138,10 @@ func NewOpenAPIData(doc *openapi_v2.Document, getIdFromSchema func(s *openapi_v2
return nil, err
}
definitions.models[namedSchema.GetName()] = schema
id := getIdFromSchema(namedSchema.GetValue())
definitions.resources[id] = namedSchema.GetName()
gvk := parseGroupVersionKind(namedSchema.GetValue())
if len(gvk.Kind) > 0 {
definitions.resources[gvk] = namedSchema.GetName()
}
}
return &definitions, nil
......@@ -119,7 +174,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,
}
}
......@@ -237,7 +292,7 @@ func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, err
// LookupResource is public through the interface of Resources. It
// returns a visitable schema from the given group-version-kind.
func (d *Definitions) LookupResource(gvk string) Schema {
func (d *Definitions) LookupResource(gvk schema.GroupVersionKind) Schema {
modelName, found := d.resources[gvk]
if !found {
return nil
......
/*
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 openapi
import (
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
"k8s.io/apimachinery/pkg/runtime/schema"
openapi "k8s.io/kube-openapi/pkg/util/proto"
)
const groupVersionKindExtensionKey = "x-kubernetes-group-version-kind"
// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one.
func ParseGroupVersionKind(s *openapi_v2.Schema) string {
extensionMap := openapi.VendorExtensionToMap(s.GetVendorExtension())
// Get the extensions
gvkExtension, ok := extensionMap[groupVersionKindExtensionKey]
if !ok {
return ""
}
// gvk extension must be a list of 1 element.
gvkList, ok := gvkExtension.([]interface{})
if !ok {
return ""
}
if len(gvkList) != 1 {
return ""
}
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 ""
}
group, ok := gvkMap["group"].(string)
if !ok {
return ""
}
version, ok := gvkMap["version"].(string)
if !ok {
return ""
}
kind, ok := gvkMap["kind"].(string)
if !ok {
return ""
}
return schema.GroupVersionKind{
Group: group,
Version: version,
Kind: kind,
}.String()
}
......@@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package proto
package openapi
import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Defines openapi types.
......@@ -37,7 +39,7 @@ const (
// Resources interface describe a resources provider, that can give you
// resource based on group-version-kind.
type Resources interface {
LookupResource(string) Schema
LookupResource(gvk schema.GroupVersionKind) Schema
}
// SchemaVisitor is an interface that you need to implement if you want
......
......@@ -20,14 +20,13 @@ import (
"sync"
"k8s.io/client-go/discovery"
openapi "k8s.io/kube-openapi/pkg/util/proto"
)
// synchronizedOpenAPIGetter fetches the openapi schema once and then caches it in memory
type synchronizedOpenAPIGetter struct {
// Cached results
sync.Once
openAPISchema openapi.Resources
openAPISchema Resources
err error
openAPIClient discovery.OpenAPISchemaInterface
......@@ -38,7 +37,7 @@ var _ Getter = &synchronizedOpenAPIGetter{}
// Getter is an interface for fetching openapi specs and parsing them into an Resources struct
type Getter interface {
// OpenAPIData returns the parsed OpenAPIData
Get() (openapi.Resources, error)
Get() (Resources, error)
}
// NewOpenAPIGetter returns an object to return OpenAPIDatas which reads
......@@ -50,7 +49,7 @@ func NewOpenAPIGetter(openAPIClient discovery.OpenAPISchemaInterface) Getter {
}
// Resources implements Getter
func (g *synchronizedOpenAPIGetter) Get() (openapi.Resources, error) {
func (g *synchronizedOpenAPIGetter) Get() (Resources, error) {
g.Do(func() {
s, err := g.openAPIClient.OpenAPISchema()
if err != nil {
......@@ -58,7 +57,7 @@ func (g *synchronizedOpenAPIGetter) Get() (openapi.Resources, error) {
return
}
g.openAPISchema, g.err = openapi.NewOpenAPIData(s, ParseGroupVersionKind)
g.openAPISchema, g.err = NewOpenAPIData(s)
})
// Return the save result
......
......@@ -18,21 +18,17 @@ package openapi_test
import (
"fmt"
"path/filepath"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
oapi "k8s.io/kube-openapi/pkg/util/proto"
tst "k8s.io/kube-openapi/pkg/util/proto/testing"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
)
var fakeSchema = tst.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
var _ = Describe("Getting the Resources", func() {
var client *tst.FakeClient
var expectedData oapi.Resources
var expectedData openapi.Resources
var instance openapi.Getter
BeforeEach(func() {
......@@ -40,7 +36,7 @@ var _ = Describe("Getting the Resources", func() {
d, err := fakeSchema.OpenAPISchema()
Expect(err).To(BeNil())
expectedData, err = oapi.NewOpenAPIData(d, openapi.ParseGroupVersionKind)
expectedData, err = openapi.NewOpenAPIData(d)
Expect(err).To(BeNil())
instance = openapi.NewOpenAPIGetter(client)
......
/*
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 openapi_test
import (
"path/filepath"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
)
var fakeSchema = tst.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
var _ = Describe("Reading apps/v1beta1/Deployment from openAPIData", func() {
var resources openapi.Resources
BeforeEach(func() {
s, err := fakeSchema.OpenAPISchema()
Expect(err).To(BeNil())
resources, err = openapi.NewOpenAPIData(s)
Expect(err).To(BeNil())
})
gvk := schema.GroupVersionKind{
Kind: "Deployment",
Version: "v1beta1",
Group: "apps",
}
var schema openapi.Schema
It("should lookup the Schema by its GroupVersionKind", func() {
schema = resources.LookupResource(gvk)
Expect(schema).ToNot(BeNil())
})
var deployment *openapi.Kind
It("should be a Kind", func() {
deployment = schema.(*openapi.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() {
var resources openapi.Resources
BeforeEach(func() {
s, err := fakeSchema.OpenAPISchema()
Expect(err).To(BeNil())
resources, err = openapi.NewOpenAPIData(s)
Expect(err).To(BeNil())
})
gvk := schema.GroupVersionKind{
Kind: "SubjectAccessReview",
Version: "v1",
Group: "authorization.k8s.io",
}
var schema openapi.Schema
It("should lookup the Schema by its GroupVersionKind", func() {
schema = resources.LookupResource(gvk)
Expect(schema).ToNot(BeNil())
})
var sarspec *openapi.Kind
It("should be a Kind and have a spec", func() {
sar := schema.(*openapi.Kind)
Expect(sar).ToNot(BeNil())
Expect(sar.Fields).To(HaveKey("spec"))
specRef := sar.Fields["spec"].(openapi.Reference)
Expect(specRef).ToNot(BeNil())
Expect(specRef.Reference()).To(Equal("io.k8s.api.authorization.v1.SubjectAccessReviewSpec"))
sarspec = specRef.SubSchema().(*openapi.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"}))
})
})
load("@io_bazel_rules_go//go:def.bzl", "go_library")
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"gvk.go",
"openapi.go",
],
visibility = ["//visibility:public"],
srcs = ["openapi.go"],
tags = ["automanaged"],
deps = [
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/github.com/googleapis/gnostic/compiler:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
......@@ -26,5 +29,4 @@ filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
......@@ -19,11 +19,11 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/api/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_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",
],
)
......@@ -39,13 +39,12 @@ go_test(
":go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/ginkgo/config:go_default_library",
"//vendor/github.com/onsi/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library",
],
)
......
......@@ -20,7 +20,7 @@ import (
"reflect"
"sort"
openapi "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
type ValidationItem interface {
......
......@@ -25,9 +25,9 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/yaml"
openapi "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kubernetes/pkg/api"
apiutil "k8s.io/kubernetes/pkg/api/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
)
type SchemaValidation struct {
......@@ -82,7 +82,7 @@ func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVer
return nil
}
resource := v.resources.LookupResource(gvk.String())
resource := v.resources.LookupResource(gvk)
if resource == nil {
return []error{fmt.Errorf("unknown object type %#v", gvk)}
}
......
......@@ -24,10 +24,9 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
// This dependency is needed to register API types.
oapi "k8s.io/kube-openapi/pkg/util/proto"
tst "k8s.io/kube-openapi/pkg/util/proto/testing"
_ "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation"
)
......@@ -38,7 +37,7 @@ var _ = Describe("resource validation using OpenAPI Schema", func() {
BeforeEach(func() {
s, err := fakeSchema.OpenAPISchema()
Expect(err).To(BeNil())
resources, err := oapi.NewOpenAPIData(s, openapi.ParseGroupVersionKind)
resources, err := openapi.NewOpenAPIData(s)
Expect(err).To(BeNil())
validator = validation.NewSchemaValidation(resources)
Expect(validator).ToNot(BeNil())
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
......@@ -11,7 +18,7 @@ go_library(
],
"//conditions:default": [],
}),
visibility = ["//visibility:public"],
tags = ["automanaged"],
)
filegroup(
......@@ -25,5 +32,4 @@ filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
......@@ -15,10 +15,7 @@ filegroup(
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:all-srcs",
],
srcs = [":package-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",
],
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",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:all-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
/*
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 testing
import (
"github.com/googleapis/gnostic/OpenAPIv2"
"k8s.io/kube-openapi/pkg/util/proto"
)
// tesingExtensionKey is the key used only for testing.
// We use some kubernetes openapi spec for testing that has this key.
const tesingExtensionKey = "x-kubernetes-group-version-kind"
// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one.
func ParseGroupVersionKind(s *openapi_v2.Schema) string {
extensionMap := proto.VendorExtensionToMap(s.GetVendorExtension())
// Get the extensions
gvkExtension, ok := extensionMap[tesingExtensionKey]
if !ok {
return ""
}
// gvk extension must be a list of 1 element.
gvkList, ok := gvkExtension.([]interface{})
if !ok {
return ""
}
if len(gvkList) != 1 {
return ""
}
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 ""
}
group, ok := gvkMap["group"].(string)
if !ok {
return ""
}
version, ok := gvkMap["version"].(string)
if !ok {
return ""
}
kind, ok := gvkMap["kind"].(string)
if !ok {
return ""
}
return GvkString(group, version, kind)
}
func GvkString(group, version, kind string) string {
return group + "/" + version + ", Kind=" + kind
}
This source diff could not be displayed because it is too large. You can view the blob instead.
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