Unverified Commit c3bb41ad authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #64596 from apelisse/openapi-some-cleanup

Automatic merge from submit-queue (batch tested with PRs 64613, 64596, 64573, 64154, 64639). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Openapi some cleanup Clean-up some OpenAPI code, mostly test related (there are two implementations of "Fake"). This is going for master, but I'll probably also cherry-pick/create a similar PR for feature-serverside-apply branch since we'll need that to move some code around. **What this PR does / why we need it**: **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
parents a19062a6 000510d9
...@@ -35,13 +35,14 @@ go_test( ...@@ -35,13 +35,14 @@ go_test(
data = ["//api/openapi-spec:swagger-spec"], data = ["//api/openapi-spec:swagger-spec"],
deps = [ deps = [
":go_default_library", ":go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library", "//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/github.com/onsi/ginkgo: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/config:go_default_library",
"//vendor/github.com/onsi/ginkgo/types:go_default_library", "//vendor/github.com/onsi/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto: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",
], ],
) )
......
...@@ -19,27 +19,36 @@ package openapi_test ...@@ -19,27 +19,36 @@ package openapi_test
import ( import (
"fmt" "fmt"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
) )
// FakeCounter returns a "null" document and the specified error. It
// also counts how many times the OpenAPISchema method has been called.
type FakeCounter struct {
Calls int
Err error
}
func (f *FakeCounter) OpenAPISchema() (*openapi_v2.Document, error) {
f.Calls = f.Calls + 1
return nil, f.Err
}
var _ = Describe("Getting the Resources", func() { var _ = Describe("Getting the Resources", func() {
var client *tst.FakeClient var client FakeCounter
var expectedData openapi.Resources
var instance openapi.Getter var instance openapi.Getter
var expectedData openapi.Resources
BeforeEach(func() { BeforeEach(func() {
client = tst.NewFakeClient(&fakeSchema) client = FakeCounter{}
d, err := fakeSchema.OpenAPISchema() instance = openapi.NewOpenAPIGetter(&client)
var err error
expectedData, err = openapi.NewOpenAPIData(nil)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
expectedData, err = openapi.NewOpenAPIData(d)
Expect(err).To(BeNil())
instance = openapi.NewOpenAPIGetter(client)
}) })
Context("when the server returns a successful result", func() { Context("when the server returns a successful result", func() {
......
...@@ -24,11 +24,11 @@ import ( ...@@ -24,11 +24,11 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto" "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kube-openapi/pkg/util/proto/testing"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "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 fakeSchema = testing.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
var _ = Describe("Reading apps/v1beta1/Deployment from openAPIData", func() { var _ = Describe("Reading apps/v1beta1/Deployment from openAPIData", func() {
var resources openapi.Resources var resources openapi.Resources
......
...@@ -11,11 +11,9 @@ go_library( ...@@ -11,11 +11,9 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing", importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing",
deps = [ deps = [
"//pkg/kubectl/cmd/util/openapi:go_default_library", "//pkg/kubectl/cmd/util/openapi:go_default_library",
"//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/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto: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",
], ],
) )
......
...@@ -17,86 +17,17 @@ limitations under the License. ...@@ -17,86 +17,17 @@ limitations under the License.
package testing package testing
import ( import (
"io/ioutil"
"os"
"sync"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kube-openapi/pkg/util/proto" "k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/kube-openapi/pkg/util/proto/testing"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
yaml "gopkg.in/yaml.v2"
"github.com/googleapis/gnostic/OpenAPIv2"
"github.com/googleapis/gnostic/compiler"
) )
// Fake opens and returns a openapi swagger from a file Path. It will
// parse only once and then return the same copy everytime.
type Fake struct {
Path string
once sync.Once
document *openapi_v2.Document
err error
}
// OpenAPISchema returns the openapi document and a potential error.
func (f *Fake) OpenAPISchema() (*openapi_v2.Document, error) {
f.once.Do(func() {
_, err := os.Stat(f.Path)
if err != nil {
f.err = err
return
}
spec, err := ioutil.ReadFile(f.Path)
if err != nil {
f.err = err
return
}
var info yaml.MapSlice
err = yaml.Unmarshal(spec, &info)
if err != nil {
f.err = err
return
}
f.document, f.err = openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
})
return f.document, f.err
}
// FakeClient implements a dummy OpenAPISchemaInterface that uses the
// fake OpenAPI schema given as a parameter, and count the number of
// call to the function.
type FakeClient struct {
Calls int
Err error
fake *Fake
}
// NewFakeClient creates a new FakeClient from the given Fake.
func NewFakeClient(f *Fake) *FakeClient {
return &FakeClient{fake: f}
}
// OpenAPISchema returns a OpenAPI Document as returned by the fake, but
// it also counts the number of calls.
func (f *FakeClient) OpenAPISchema() (*openapi_v2.Document, error) {
f.Calls = f.Calls + 1
if f.Err != nil {
return nil, f.Err
}
return f.fake.OpenAPISchema()
}
// FakeResources is a wrapper to directly load the openapi schema from a // FakeResources is a wrapper to directly load the openapi schema from a
// file, and get the schema for given GVK. This is only for test since // file, and get the schema for given GVK. This is only for test since
// it's assuming that the file is there and everything will go fine. // it's assuming that the file is there and everything will go fine.
type FakeResources struct { type FakeResources struct {
fake Fake fake testing.Fake
} }
var _ openapi.Resources = &FakeResources{} var _ openapi.Resources = &FakeResources{}
...@@ -104,7 +35,7 @@ var _ openapi.Resources = &FakeResources{} ...@@ -104,7 +35,7 @@ var _ openapi.Resources = &FakeResources{}
// NewFakeResources creates a new FakeResources. // NewFakeResources creates a new FakeResources.
func NewFakeResources(path string) *FakeResources { func NewFakeResources(path string) *FakeResources {
return &FakeResources{ return &FakeResources{
fake: Fake{Path: path}, fake: testing.Fake{Path: path},
} }
} }
......
...@@ -31,12 +31,12 @@ go_test( ...@@ -31,12 +31,12 @@ go_test(
deps = [ deps = [
"//pkg/api/testapi:go_default_library", "//pkg/api/testapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi: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:go_default_library",
"//vendor/github.com/onsi/ginkgo/config: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/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library", "//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:go_default_library",
], ],
) )
......
...@@ -25,12 +25,12 @@ import ( ...@@ -25,12 +25,12 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kube-openapi/pkg/util/proto/validation" "k8s.io/kube-openapi/pkg/util/proto/validation"
// This dependency is needed to register API types. // This dependency is needed to register API types.
"k8s.io/kube-openapi/pkg/util/proto/testing"
_ "k8s.io/kubernetes/pkg/api/testapi" _ "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "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 fakeSchema = testing.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
var _ = Describe("resource validation using OpenAPI Schema", func() { var _ = Describe("resource validation using OpenAPI Schema", func() {
var validator *SchemaValidation var validator *SchemaValidation
......
...@@ -2032,23 +2032,23 @@ ...@@ -2032,23 +2032,23 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/builder", "ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/common", "ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/handler", "ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util", "ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/equality", "ImportPath": "k8s.io/apimachinery/pkg/api/equality",
......
...@@ -180,7 +180,7 @@ ...@@ -180,7 +180,7 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -1760,23 +1760,23 @@ ...@@ -1760,23 +1760,23 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/builder", "ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/common", "ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/handler", "ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util", "ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/client-go/discovery", "ImportPath": "k8s.io/client-go/discovery",
......
...@@ -588,7 +588,7 @@ ...@@ -588,7 +588,7 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -260,11 +260,11 @@ ...@@ -260,11 +260,11 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/common", "ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/generators", "ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -1680,27 +1680,27 @@ ...@@ -1680,27 +1680,27 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator", "ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/builder", "ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/common", "ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/handler", "ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util", "ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -488,7 +488,7 @@ ...@@ -488,7 +488,7 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -1644,23 +1644,23 @@ ...@@ -1644,23 +1644,23 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/builder", "ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/common", "ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/handler", "ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util", "ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -1072,7 +1072,7 @@ ...@@ -1072,7 +1072,7 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
...@@ -58,7 +58,6 @@ type OpenAPIService struct { ...@@ -58,7 +58,6 @@ type OpenAPIService struct {
// rwMutex protects All members of this service. // rwMutex protects All members of this service.
rwMutex sync.RWMutex rwMutex sync.RWMutex
orgSpec *spec.Swagger
lastModified time.Time lastModified time.Time
specBytes []byte specBytes []byte
...@@ -161,7 +160,6 @@ func (o *OpenAPIService) getSwaggerPbGzBytes() ([]byte, string, time.Time) { ...@@ -161,7 +160,6 @@ func (o *OpenAPIService) getSwaggerPbGzBytes() ([]byte, string, time.Time) {
} }
func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) { func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
orgSpec := openapiSpec
specBytes, err := json.MarshalIndent(openapiSpec, " ", " ") specBytes, err := json.MarshalIndent(openapiSpec, " ", " ")
if err != nil { if err != nil {
return err return err
...@@ -181,7 +179,6 @@ func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) { ...@@ -181,7 +179,6 @@ func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
o.rwMutex.Lock() o.rwMutex.Lock()
defer o.rwMutex.Unlock() defer o.rwMutex.Unlock()
o.orgSpec = orgSpec
o.specBytes = specBytes o.specBytes = specBytes
o.specPb = specPb o.specPb = specPb
o.specPbGz = specPbGz o.specPbGz = specPbGz
......
...@@ -26,6 +26,7 @@ filegroup( ...@@ -26,6 +26,7 @@ filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [ srcs = [
":package-srcs", ":package-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:all-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:all-srcs", "//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
......
...@@ -21,8 +21,8 @@ import ( ...@@ -21,8 +21,8 @@ import (
"sort" "sort"
"strings" "strings"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2" "github.com/googleapis/gnostic/OpenAPIv2"
yaml "gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
func newSchemaError(path *Path, format string, a ...interface{}) error { func newSchemaError(path *Path, format string, a ...interface{}) error {
...@@ -126,12 +126,17 @@ func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error) ...@@ -126,12 +126,17 @@ func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error)
if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object { if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
return nil, newSchemaError(path, "invalid object type") return nil, newSchemaError(path, "invalid object type")
} }
var sub Schema
if s.GetAdditionalProperties().GetSchema() == nil { if s.GetAdditionalProperties().GetSchema() == nil {
return nil, newSchemaError(path, "invalid object doesn't have additional properties") sub = &Arbitrary{
} BaseSchema: d.parseBaseSchema(s, path),
sub, err := d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path) }
if err != nil { } else {
return nil, err var err error
sub, err = d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path)
if err != nil {
return nil, err
}
} }
return &Map{ return &Map{
BaseSchema: d.parseBaseSchema(s, path), BaseSchema: d.parseBaseSchema(s, path),
...@@ -148,12 +153,10 @@ func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema, ...@@ -148,12 +153,10 @@ func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema,
t = s.GetType().GetValue()[0] t = s.GetType().GetValue()[0]
} }
switch t { switch t {
case String: case String: // do nothing
case Number: case Number: // do nothing
case Integer: case Integer: // do nothing
case Boolean: case Boolean: // do nothing
case "": // Some models are completely empty, and can be safely ignored.
// Do nothing
default: default:
return nil, newSchemaError(path, "Unknown primitive type: %q", t) return nil, newSchemaError(path, "Unknown primitive type: %q", t)
} }
...@@ -219,27 +222,38 @@ func (d *Definitions) parseArbitrary(s *openapi_v2.Schema, path *Path) (Schema, ...@@ -219,27 +222,38 @@ func (d *Definitions) parseArbitrary(s *openapi_v2.Schema, path *Path) (Schema,
// ParseSchema creates a walkable Schema from an openapi schema. While // ParseSchema creates a walkable Schema from an openapi schema. While
// this function is public, it doesn't leak through the interface. // this function is public, it doesn't leak through the interface.
func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) { func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) {
if s.GetXRef() != "" {
return d.parseReference(s, path)
}
objectTypes := s.GetType().GetValue() objectTypes := s.GetType().GetValue()
if len(objectTypes) == 1 { switch len(objectTypes) {
case 0:
// in the OpenAPI schema served by older k8s versions, object definitions created from structs did not include
// the type:object property (they only included the "properties" property), so we need to handle this case
if s.GetProperties() != nil {
return d.parseKind(s, path)
} else {
// Definition has no type and no properties. Treat it as an arbitrary value
// TODO: what if it has additionalProperties or patternProperties?
return d.parseArbitrary(s, path)
}
case 1:
t := objectTypes[0] t := objectTypes[0]
switch t { switch t {
case object: case object:
return d.parseMap(s, path) if s.GetProperties() != nil {
return d.parseKind(s, path)
} else {
return d.parseMap(s, path)
}
case array: case array:
return d.parseArray(s, path) return d.parseArray(s, path)
} }
return d.parsePrimitive(s, path)
} default:
if s.GetXRef() != "" { // the OpenAPI generator never generates (nor it ever did in the past) OpenAPI type definitions with multiple types
return d.parseReference(s, path) return nil, newSchemaError(path, "definitions with multiple types aren't supported")
}
if s.GetProperties() != nil {
return d.parseKind(s, path)
}
if len(objectTypes) == 0 || (len(objectTypes) == 1 && objectTypes[0] == "") {
return d.parseArbitrary(s, path)
} }
return d.parsePrimitive(s, path)
} }
// LookupModel is public through the interface of Models. It // LookupModel is public through the interface of Models. It
......
...@@ -59,7 +59,7 @@ type SchemaVisitor interface { ...@@ -59,7 +59,7 @@ type SchemaVisitor interface {
} }
// SchemaVisitorArbitrary is an additional visitor interface which handles // SchemaVisitorArbitrary is an additional visitor interface which handles
// arbitrary types. For backwards compatability, it's a separate interface // arbitrary types. For backwards compatibility, it's a separate interface
// which is checked for at runtime. // which is checked for at runtime.
type SchemaVisitorArbitrary interface { type SchemaVisitorArbitrary interface {
SchemaVisitor SchemaVisitor
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["openapi.go"],
importpath = "k8s.io/kube-openapi/pkg/util/proto/testing",
visibility = ["//visibility:public"],
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",
],
)
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 testing
import (
"io/ioutil"
"os"
"sync"
yaml "gopkg.in/yaml.v2"
"github.com/googleapis/gnostic/OpenAPIv2"
"github.com/googleapis/gnostic/compiler"
)
// Fake opens and returns a openapi swagger from a file Path. It will
// parse only once and then return the same copy everytime.
type Fake struct {
Path string
once sync.Once
document *openapi_v2.Document
err error
}
// OpenAPISchema returns the openapi document and a potential error.
func (f *Fake) OpenAPISchema() (*openapi_v2.Document, error) {
f.once.Do(func() {
_, err := os.Stat(f.Path)
if err != nil {
f.err = err
return
}
spec, err := ioutil.ReadFile(f.Path)
if err != nil {
f.err = err
return
}
var info yaml.MapSlice
err = yaml.Unmarshal(spec, &info)
if err != nil {
f.err = err
return
}
f.document, f.err = openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
})
return f.document, f.err
}
type Empty struct{}
func (Empty) OpenAPISchema() (*openapi_v2.Document, error) {
return nil, nil
}
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