Add generated file
This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
69
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/BUILD
generated
vendored
Normal file
69
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/BUILD
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"extensions.go",
|
||||
"openapi.go",
|
||||
"openapi_getter.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi",
|
||||
deps = [
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/googleapis/gnostic/OpenAPIv2: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",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"openapi_getter_test.go",
|
||||
"openapi_suite_test.go",
|
||||
"openapi_test.go",
|
||||
],
|
||||
data = ["//api/openapi-spec:swagger-spec"],
|
||||
deps = [
|
||||
":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/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/runtime/schema: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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
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"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "testdata",
|
||||
srcs = glob(["testdata/*"]),
|
||||
)
|
4
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/OWNERS
generated
vendored
Normal file
4
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
approvers:
|
||||
- apelisse
|
||||
reviewers:
|
||||
- apelisse
|
21
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/doc.go
generated
vendored
Normal file
21
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/doc.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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 is a collection of libraries for fetching the openapi spec
|
||||
// from a Kubernetes server and then indexing the type definitions.
|
||||
// The openapi spec contains the object model definitions and extensions metadata
|
||||
// such as the patchStrategy and patchMergeKey for creating patches.
|
||||
package openapi
|
26
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/extensions.go
generated
vendored
Normal file
26
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/extensions.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
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 "github.com/go-openapi/spec"
|
||||
|
||||
const PrintColumnsKey = "x-kubernetes-print-columns"
|
||||
|
||||
// GetPrintColumns looks for the open API extension for the display columns.
|
||||
func GetPrintColumns(extensions spec.Extensions) (string, bool) {
|
||||
return extensions.GetString(PrintColumnsKey)
|
||||
}
|
127
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi.go
generated
vendored
Normal file
127
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
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"
|
||||
"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) proto.Schema
|
||||
}
|
||||
|
||||
// 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"
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
var _ Resources = &document{}
|
||||
|
||||
func NewOpenAPIData(doc *openapi_v2.Document) (Resources, error) {
|
||||
models, err := proto.NewOpenAPIData(doc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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.")
|
||||
}
|
||||
gvkList := parseGroupVersionKind(model)
|
||||
for _, gvk := range gvkList {
|
||||
if len(gvk.Kind) > 0 {
|
||||
resources[gvk] = modelName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &document{
|
||||
resources: resources,
|
||||
models: models,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *document) LookupResource(gvk schema.GroupVersionKind) proto.Schema {
|
||||
modelName, found := d.resources[gvk]
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
return d.models.LookupModel(modelName)
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
gvkListResult := []schema.GroupVersionKind{}
|
||||
|
||||
// Get the extensions
|
||||
gvkExtension, ok := extensions[groupVersionKindExtensionKey]
|
||||
if !ok {
|
||||
return []schema.GroupVersionKind{}
|
||||
}
|
||||
|
||||
// gvk extension must be a list of at least 1 element.
|
||||
gvkList, ok := gvkExtension.([]interface{})
|
||||
if !ok {
|
||||
return []schema.GroupVersionKind{}
|
||||
}
|
||||
|
||||
for _, gvk := range gvkList {
|
||||
// gvk extension list must be a map with group, version, and
|
||||
// kind fields
|
||||
gvkMap, ok := gvk.(map[interface{}]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
group, ok := gvkMap["group"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
version, ok := gvkMap["version"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
kind, ok := gvkMap["kind"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
gvkListResult = append(gvkListResult, schema.GroupVersionKind{
|
||||
Group: group,
|
||||
Version: version,
|
||||
Kind: kind,
|
||||
})
|
||||
}
|
||||
|
||||
return gvkListResult
|
||||
}
|
65
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_getter.go
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_getter.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 (
|
||||
"sync"
|
||||
|
||||
"k8s.io/client-go/discovery"
|
||||
)
|
||||
|
||||
// synchronizedOpenAPIGetter fetches the openapi schema once and then caches it in memory
|
||||
type synchronizedOpenAPIGetter struct {
|
||||
// Cached results
|
||||
sync.Once
|
||||
openAPISchema Resources
|
||||
err error
|
||||
|
||||
openAPIClient discovery.OpenAPISchemaInterface
|
||||
}
|
||||
|
||||
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() (Resources, error)
|
||||
}
|
||||
|
||||
// NewOpenAPIGetter returns an object to return OpenAPIDatas which reads
|
||||
// from a server, and then stores in memory for subsequent invocations
|
||||
func NewOpenAPIGetter(openAPIClient discovery.OpenAPISchemaInterface) Getter {
|
||||
return &synchronizedOpenAPIGetter{
|
||||
openAPIClient: openAPIClient,
|
||||
}
|
||||
}
|
||||
|
||||
// Resources implements Getter
|
||||
func (g *synchronizedOpenAPIGetter) Get() (Resources, error) {
|
||||
g.Do(func() {
|
||||
s, err := g.openAPIClient.OpenAPISchema()
|
||||
if err != nil {
|
||||
g.err = err
|
||||
return
|
||||
}
|
||||
|
||||
g.openAPISchema, g.err = NewOpenAPIData(s)
|
||||
})
|
||||
|
||||
// Return the save result
|
||||
return g.openAPISchema, g.err
|
||||
}
|
86
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_getter_test.go
generated
vendored
Normal file
86
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_getter_test.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// 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 client FakeCounter
|
||||
var instance openapi.Getter
|
||||
var expectedData openapi.Resources
|
||||
|
||||
BeforeEach(func() {
|
||||
client = FakeCounter{}
|
||||
instance = openapi.NewOpenAPIGetter(&client)
|
||||
var err error
|
||||
expectedData, err = openapi.NewOpenAPIData(nil)
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
Context("when the server returns a successful result", func() {
|
||||
It("should return the same data for multiple calls", func() {
|
||||
Expect(client.Calls).To(Equal(0))
|
||||
|
||||
result, err := instance.Get()
|
||||
Expect(err).To(BeNil())
|
||||
Expect(result).To(Equal(expectedData))
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
|
||||
result, err = instance.Get()
|
||||
Expect(err).To(BeNil())
|
||||
Expect(result).To(Equal(expectedData))
|
||||
// No additional client calls expected
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the server returns an unsuccessful result", func() {
|
||||
It("should return the same instance for multiple calls.", func() {
|
||||
Expect(client.Calls).To(Equal(0))
|
||||
|
||||
client.Err = fmt.Errorf("expected error")
|
||||
_, err := instance.Get()
|
||||
Expect(err).To(Equal(client.Err))
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
|
||||
_, err = instance.Get()
|
||||
Expect(err).To(Equal(client.Err))
|
||||
// No additional client calls expected
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
49
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_suite_test.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_suite_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
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 (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/config"
|
||||
. "github.com/onsi/ginkgo/types"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpenapi(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecsWithDefaultAndCustomReporters(t, "Openapi Suite", []Reporter{newlineReporter{}})
|
||||
}
|
||||
|
||||
// Print a newline after the default newlineReporter due to issue
|
||||
// https://github.com/jstemmer/go-junit-report/issues/31
|
||||
type newlineReporter struct{}
|
||||
|
||||
func (newlineReporter) SpecSuiteWillBegin(config GinkgoConfigType, summary *SuiteSummary) {}
|
||||
|
||||
func (newlineReporter) BeforeSuiteDidRun(setupSummary *SetupSummary) {}
|
||||
|
||||
func (newlineReporter) AfterSuiteDidRun(setupSummary *SetupSummary) {}
|
||||
|
||||
func (newlineReporter) SpecWillRun(specSummary *SpecSummary) {}
|
||||
|
||||
func (newlineReporter) SpecDidComplete(specSummary *SpecSummary) {}
|
||||
|
||||
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:"
|
||||
func (newlineReporter) SpecSuiteDidEnd(summary *SuiteSummary) { fmt.Printf("\n") }
|
93
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_test.go
generated
vendored
Normal file
93
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/openapi_test.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/util/proto/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
var fakeSchema = testing.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 proto.Schema
|
||||
It("should lookup the Schema by its GroupVersionKind", func() {
|
||||
schema = resources.LookupResource(gvk)
|
||||
Expect(schema).ToNot(BeNil())
|
||||
})
|
||||
|
||||
var deployment *proto.Kind
|
||||
It("should be a Kind", func() {
|
||||
deployment = schema.(*proto.Kind)
|
||||
Expect(deployment).ToNot(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
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 proto.Schema
|
||||
It("should lookup the Schema by its GroupVersionKind", func() {
|
||||
schema = resources.LookupResource(gvk)
|
||||
Expect(schema).ToNot(BeNil())
|
||||
})
|
||||
|
||||
var sarspec *proto.Kind
|
||||
It("should be a Kind and have a spec", func() {
|
||||
sar := schema.(*proto.Kind)
|
||||
Expect(sar).ToNot(BeNil())
|
||||
Expect(sar.Fields).To(HaveKey("spec"))
|
||||
specRef := sar.Fields["spec"].(proto.Reference)
|
||||
Expect(specRef).ToNot(BeNil())
|
||||
Expect(specRef.Reference()).To(Equal("io.k8s.api.authorization.v1.SubjectAccessReviewSpec"))
|
||||
sarspec = specRef.SubSchema().(*proto.Kind)
|
||||
Expect(sarspec).ToNot(BeNil())
|
||||
})
|
||||
})
|
31
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing/BUILD
generated
vendored
Normal file
31
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing/BUILD
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["openapi.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing",
|
||||
deps = [
|
||||
"//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",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
71
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing/openapi.go
generated
vendored
Normal file
71
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing/openapi.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
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 (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/util/proto/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// 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
|
||||
// it's assuming that the file is there and everything will go fine.
|
||||
type FakeResources struct {
|
||||
fake testing.Fake
|
||||
}
|
||||
|
||||
var _ openapi.Resources = &FakeResources{}
|
||||
|
||||
// NewFakeResources creates a new FakeResources.
|
||||
func NewFakeResources(path string) *FakeResources {
|
||||
return &FakeResources{
|
||||
fake: testing.Fake{Path: path},
|
||||
}
|
||||
}
|
||||
|
||||
// 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) proto.Schema {
|
||||
s, err := f.fake.OpenAPISchema()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resources, err := openapi.NewOpenAPIData(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return resources.LookupResource(gvk)
|
||||
}
|
||||
|
||||
// EmptyResources implement a Resources that just doesn't have any resources.
|
||||
type EmptyResources struct{}
|
||||
|
||||
var _ openapi.Resources = EmptyResources{}
|
||||
|
||||
// LookupResource will always return nil. It doesn't have any resources.
|
||||
func (f EmptyResources) LookupResource(gvk schema.GroupVersionKind) proto.Schema {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateOpenAPISchemaFunc returns a function useful for the TestFactory.
|
||||
func CreateOpenAPISchemaFunc(path string) func() (openapi.Resources, error) {
|
||||
return func() (openapi.Resources, error) {
|
||||
return NewFakeResources(path), nil
|
||||
}
|
||||
}
|
55
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/BUILD
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/BUILD
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validation.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation",
|
||||
deps = [
|
||||
"//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/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"validation_suite_test.go",
|
||||
"validation_test.go",
|
||||
],
|
||||
data = ["//api/openapi-spec:swagger-spec"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi: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/testing:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
140
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation.go
generated
vendored
Normal file
140
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation.go
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
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/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// SchemaValidation validates the object against an OpenAPI schema.
|
||||
type SchemaValidation struct {
|
||||
resources openapi.Resources
|
||||
}
|
||||
|
||||
// NewSchemaValidation creates a new SchemaValidation that can be used
|
||||
// to validate objects.
|
||||
func NewSchemaValidation(resources openapi.Resources) *SchemaValidation {
|
||||
return &SchemaValidation{
|
||||
resources: resources,
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateBytes will validates the object against using the Resources
|
||||
// object.
|
||||
func (v *SchemaValidation) ValidateBytes(data []byte) error {
|
||||
obj, err := parse(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gvk, errs := getObjectKind(obj)
|
||||
if errs != nil {
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
if (gvk == schema.GroupVersionKind{Version: "v1", Kind: "List"}) {
|
||||
return utilerrors.NewAggregate(v.validateList(obj))
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(v.validateResource(obj, gvk))
|
||||
}
|
||||
|
||||
func (v *SchemaValidation) validateList(object interface{}) []error {
|
||||
fields, ok := object.(map[string]interface{})
|
||||
if !ok || fields == nil {
|
||||
return []error{errors.New("invalid object to validate")}
|
||||
}
|
||||
|
||||
allErrors := []error{}
|
||||
if _, ok := fields["items"].([]interface{}); !ok {
|
||||
return []error{errors.New("invalid object to validate")}
|
||||
}
|
||||
for _, item := range fields["items"].([]interface{}) {
|
||||
if gvk, errs := getObjectKind(item); errs != nil {
|
||||
allErrors = append(allErrors, errs...)
|
||||
} else {
|
||||
allErrors = append(allErrors, v.validateResource(item, gvk)...)
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVersionKind) []error {
|
||||
resource := v.resources.LookupResource(gvk)
|
||||
if resource == nil {
|
||||
// resource is not present, let's just skip validation.
|
||||
return nil
|
||||
}
|
||||
|
||||
return validation.ValidateModel(obj, resource, gvk.Kind)
|
||||
}
|
||||
|
||||
func parse(data []byte) (interface{}, error) {
|
||||
var obj interface{}
|
||||
out, err := yaml.ToJSON(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(out, &obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func getObjectKind(object interface{}) (schema.GroupVersionKind, []error) {
|
||||
var listErrors []error
|
||||
fields, ok := object.(map[string]interface{})
|
||||
if !ok || fields == nil {
|
||||
listErrors = append(listErrors, errors.New("invalid object to validate"))
|
||||
return schema.GroupVersionKind{}, listErrors
|
||||
}
|
||||
|
||||
var group string
|
||||
var version string
|
||||
apiVersion := fields["apiVersion"]
|
||||
if apiVersion == nil {
|
||||
listErrors = append(listErrors, errors.New("apiVersion not set"))
|
||||
} else if _, ok := apiVersion.(string); !ok {
|
||||
listErrors = append(listErrors, errors.New("apiVersion isn't string type"))
|
||||
} else {
|
||||
gv, err := schema.ParseGroupVersion(apiVersion.(string))
|
||||
if err != nil {
|
||||
listErrors = append(listErrors, err)
|
||||
} else {
|
||||
group = gv.Group
|
||||
version = gv.Version
|
||||
}
|
||||
}
|
||||
kind := fields["kind"]
|
||||
if kind == nil {
|
||||
listErrors = append(listErrors, errors.New("kind not set"))
|
||||
} else if _, ok := kind.(string); !ok {
|
||||
listErrors = append(listErrors, errors.New("kind isn't string type"))
|
||||
}
|
||||
if listErrors != nil {
|
||||
return schema.GroupVersionKind{}, listErrors
|
||||
}
|
||||
|
||||
return schema.GroupVersionKind{Group: group, Version: version, Kind: kind.(string)}, nil
|
||||
}
|
49
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation_suite_test.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation_suite_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/config"
|
||||
. "github.com/onsi/ginkgo/types"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpenapi(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecsWithDefaultAndCustomReporters(t, "Openapi Suite", []Reporter{newlineReporter{}})
|
||||
}
|
||||
|
||||
// Print a newline after the default newlineReporter due to issue
|
||||
// https://github.com/jstemmer/go-junit-report/issues/31
|
||||
type newlineReporter struct{}
|
||||
|
||||
func (newlineReporter) SpecSuiteWillBegin(config GinkgoConfigType, summary *SuiteSummary) {}
|
||||
|
||||
func (newlineReporter) BeforeSuiteDidRun(setupSummary *SetupSummary) {}
|
||||
|
||||
func (newlineReporter) AfterSuiteDidRun(setupSummary *SetupSummary) {}
|
||||
|
||||
func (newlineReporter) SpecWillRun(specSummary *SpecSummary) {}
|
||||
|
||||
func (newlineReporter) SpecDidComplete(specSummary *SpecSummary) {}
|
||||
|
||||
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:"
|
||||
func (newlineReporter) SpecSuiteDidEnd(summary *SuiteSummary) { fmt.Printf("\n") }
|
409
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation_test.go
generated
vendored
Normal file
409
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation/validation_test.go
generated
vendored
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/kube-openapi/pkg/util/proto/validation"
|
||||
// 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/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
var fakeSchema = testing.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
|
||||
|
||||
var _ = Describe("resource validation using OpenAPI Schema", func() {
|
||||
var validator *SchemaValidation
|
||||
BeforeEach(func() {
|
||||
s, err := fakeSchema.OpenAPISchema()
|
||||
Expect(err).To(BeNil())
|
||||
resources, err := openapi.NewOpenAPIData(s)
|
||||
Expect(err).To(BeNil())
|
||||
validator = NewSchemaValidation(resources)
|
||||
Expect(validator).ToNot(BeNil())
|
||||
})
|
||||
|
||||
It("finds Deployment in Schema and validates it", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- image: redis
|
||||
name: redis
|
||||
`))
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
It("validates a valid pod", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- this
|
||||
- is
|
||||
- an
|
||||
- ok
|
||||
- command
|
||||
image: gcr.io/fake_project/fake_image:fake_tag
|
||||
name: master
|
||||
`))
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
It("finds invalid command (string instead of []string) in Json Pod", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
{
|
||||
"kind": "Pod",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "name",
|
||||
"labels": {
|
||||
"name": "redis-master"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "master",
|
||||
"image": "gcr.io/fake_project/fake_image:fake_tag",
|
||||
"args": "this is a bad command"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`))
|
||||
Expect(err).To(Equal(utilerrors.NewAggregate([]error{
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0].args",
|
||||
Err: validation.InvalidTypeError{
|
||||
Path: "io.k8s.api.core.v1.Container.args",
|
||||
Expected: "array",
|
||||
Actual: "string",
|
||||
},
|
||||
},
|
||||
})))
|
||||
})
|
||||
|
||||
It("fails because hostPort is string instead of int", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
{
|
||||
"kind": "Pod",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "apache-php",
|
||||
"labels": {
|
||||
"name": "apache-php"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [{
|
||||
"name": "shared-disk"
|
||||
}],
|
||||
"containers": [
|
||||
{
|
||||
"name": "apache-php",
|
||||
"image": "gcr.io/fake_project/fake_image:fake_tag",
|
||||
"ports": [
|
||||
{
|
||||
"name": "apache",
|
||||
"hostPort": "13380",
|
||||
"containerPort": 80,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "shared-disk",
|
||||
"mountPath": "/var/www/html"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`))
|
||||
|
||||
Expect(err).To(Equal(utilerrors.NewAggregate([]error{
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0].ports[0].hostPort",
|
||||
Err: validation.InvalidTypeError{
|
||||
Path: "io.k8s.api.core.v1.ContainerPort.hostPort",
|
||||
Expected: "integer",
|
||||
Actual: "string",
|
||||
},
|
||||
},
|
||||
})))
|
||||
|
||||
})
|
||||
|
||||
It("fails because volume is not an array of object", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
{
|
||||
"kind": "Pod",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "apache-php",
|
||||
"labels": {
|
||||
"name": "apache-php"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
"name": "shared-disk"
|
||||
],
|
||||
"containers": [
|
||||
{
|
||||
"name": "apache-php",
|
||||
"image": "gcr.io/fake_project/fake_image:fake_tag",
|
||||
"ports": [
|
||||
{
|
||||
"name": "apache",
|
||||
"hostPort": 13380,
|
||||
"containerPort": 80,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "shared-disk",
|
||||
"mountPath": "/var/www/html"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`))
|
||||
Expect(err.Error()).To(Equal("invalid character ':' after array element"))
|
||||
})
|
||||
|
||||
It("fails because some string lists have empty strings", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/fake_project/fake_image:fake_tag
|
||||
name: master
|
||||
args:
|
||||
-
|
||||
command:
|
||||
-
|
||||
`))
|
||||
|
||||
Expect(err).To(Equal(utilerrors.NewAggregate([]error{
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0].args",
|
||||
Err: validation.InvalidObjectTypeError{
|
||||
Path: "Pod.spec.containers[0].args[0]",
|
||||
Type: "nil",
|
||||
},
|
||||
},
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0].command",
|
||||
Err: validation.InvalidObjectTypeError{
|
||||
Path: "Pod.spec.containers[0].command[0]",
|
||||
Type: "nil",
|
||||
},
|
||||
},
|
||||
})))
|
||||
})
|
||||
|
||||
It("fails if required fields are missing", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- command: ["my", "command"]
|
||||
`))
|
||||
|
||||
Expect(err).To(Equal(utilerrors.NewAggregate([]error{
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0]",
|
||||
Err: validation.MissingRequiredFieldError{
|
||||
Path: "io.k8s.api.core.v1.Container",
|
||||
Field: "name",
|
||||
},
|
||||
},
|
||||
})))
|
||||
})
|
||||
|
||||
It("fails if required fields are empty", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- image:
|
||||
name:
|
||||
`))
|
||||
|
||||
Expect(err).To(Equal(utilerrors.NewAggregate([]error{
|
||||
validation.ValidationError{
|
||||
Path: "Pod.spec.containers[0]",
|
||||
Err: validation.MissingRequiredFieldError{
|
||||
Path: "io.k8s.api.core.v1.Container",
|
||||
Field: "name",
|
||||
},
|
||||
},
|
||||
})))
|
||||
})
|
||||
|
||||
It("is fine with empty non-mandatory fields", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- image: image
|
||||
name: name
|
||||
command:
|
||||
`))
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
It("can validate lists", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: List
|
||||
items:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- name: name
|
||||
`))
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
|
||||
It("fails because apiVersion is not provided", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- name: name
|
||||
image: image
|
||||
`))
|
||||
Expect(err.Error()).To(Equal("apiVersion not set"))
|
||||
})
|
||||
|
||||
It("fails because apiVersion type is not string and kind is not provided", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: 1
|
||||
metadata:
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- name: name
|
||||
image: image
|
||||
`))
|
||||
Expect(err.Error()).To(Equal("[apiVersion isn't string type, kind not set]"))
|
||||
})
|
||||
|
||||
It("fails because List first item is missing kind and second item is missing apiVersion", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: v1
|
||||
kind: List
|
||||
items:
|
||||
- apiVersion: v1
|
||||
metadata:
|
||||
name: name
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: name
|
||||
spec:
|
||||
containers:
|
||||
- name: name
|
||||
image: image
|
||||
- kind: Service
|
||||
metadata:
|
||||
name: name
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 123
|
||||
targetPort: 1234
|
||||
name: name
|
||||
selector:
|
||||
name: name
|
||||
`))
|
||||
Expect(err.Error()).To(Equal("[kind not set, apiVersion not set]"))
|
||||
})
|
||||
|
||||
It("is fine with crd resource with List as a suffix kind name, which may not be a list of resources", func() {
|
||||
err := validator.ValidateBytes([]byte(`
|
||||
apiVersion: fake.com/v1
|
||||
kind: FakeList
|
||||
metadata:
|
||||
name: fake
|
||||
spec:
|
||||
foo: bar
|
||||
`))
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user