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

Merge pull request #54957 from apelisse/update-kube-openapi

Automatic merge from submit-queue (batch tested with PRs 55004, 54957). 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>. Update kube-openapi to use validation **What this PR does / why we need it**: Moves openapi validation code to kube-openapi, so that we can move the rest of the code to apimachinery repository, so that later we can use it from both the client and the server. **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 #Nothing **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
parents 6232f365 8f7262e8
......@@ -3052,31 +3052,35 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto/validation",
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/utils/exec",
......
......@@ -8,11 +8,7 @@ load(
go_library(
name = "go_default_library",
srcs = [
"errors.go",
"types.go",
"validation.go",
],
srcs = ["validation.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation",
deps = [
"//pkg/kubectl/cmd/util/openapi:go_default_library",
......@@ -20,20 +16,20 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:go_default_library",
],
)
go_test(
name = "go_default_xtest",
name = "go_default_test",
srcs = [
"validation_suite_test.go",
"validation_test.go",
],
data = ["//api/openapi-spec:swagger-spec"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation_test",
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation",
library = ":go_default_library",
deps = [
":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",
......@@ -42,6 +38,7 @@ go_test(
"//vendor/github.com/onsi/ginkgo/types:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:go_default_library",
],
)
......
......@@ -24,20 +24,25 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/kube-openapi/pkg/util/proto"
"k8s.io/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 {
......@@ -80,12 +85,7 @@ func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVer
return nil
}
rootValidation, err := itemFactory(proto.NewPath(gvk.Kind), obj)
if err != nil {
return []error{err}
}
resource.Accept(rootValidation)
return rootValidation.Errors()
return validation.ValidateModel(obj, resource, gvk.Kind)
}
func parse(data []byte) (interface{}, error) {
......
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package validation_test
package validation
import (
. "github.com/onsi/ginkgo"
......
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package validation_test
package validation
import (
"path/filepath"
......@@ -23,23 +23,23 @@ import (
. "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/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"
)
var fakeSchema = tst.Fake{Path: filepath.Join("..", "..", "..", "..", "..", "..", "api", "openapi-spec", "swagger.json")}
var _ = Describe("resource validation using OpenAPI Schema", func() {
var validator *validation.SchemaValidation
var validator *SchemaValidation
BeforeEach(func() {
s, err := fakeSchema.OpenAPISchema()
Expect(err).To(BeNil())
resources, err := openapi.NewOpenAPIData(s)
Expect(err).To(BeNil())
validator = validation.NewSchemaValidation(resources)
validator = NewSchemaValidation(resources)
Expect(validator).ToNot(BeNil())
})
......
......@@ -216,7 +216,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
......
......@@ -1556,19 +1556,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
......
......@@ -216,7 +216,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -1612,19 +1612,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/client-go/discovery",
......
......@@ -692,7 +692,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -252,11 +252,11 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -1544,23 +1544,23 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -520,7 +520,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -1532,19 +1532,19 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -940,7 +940,7 @@
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "61b46af70dfed79c6d24530cd23b41440a7f22a5"
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
}
]
}
......@@ -41,8 +41,6 @@ filegroup(
"//vendor/github.com/aws/aws-sdk-go/service/elb:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/service/kms:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/service/sts:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/vendor/github.com/jmespath/go-jmespath:all-srcs",
"//vendor/github.com/beorn7/perks/quantile:all-srcs",
"//vendor/github.com/blang/semver:all-srcs",
"//vendor/github.com/boltdb/bolt:all-srcs",
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["waiter.go"],
importpath = "github.com/aws/aws-sdk-go/private/waiter",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awsutil:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request: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"],
)
......@@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["trie.go"],
srcs = [
"trie.go",
"util.go",
],
importpath = "k8s.io/kube-openapi/pkg/util",
visibility = ["//visibility:public"],
)
......
......@@ -24,7 +24,10 @@ filegroup(
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
srcs = [
":package-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util/proto/validation:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
......@@ -3,16 +3,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"api.go",
"astnodetype_string.go",
"functions.go",
"interpreter.go",
"lexer.go",
"parser.go",
"toktype_string.go",
"util.go",
"errors.go",
"types.go",
"validation.go",
],
importpath = "k8s.io/kube-openapi/pkg/util/proto/validation",
visibility = ["//visibility:public"],
deps = ["//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library"],
)
filegroup(
......
......@@ -20,15 +20,15 @@ import (
"fmt"
)
type Errors struct {
type errors struct {
errors []error
}
func (e *Errors) Errors() []error {
func (e *errors) Errors() []error {
return e.errors
}
func (e *Errors) AppendErrors(err ...error) {
func (e *errors) AppendErrors(err ...error) {
e.errors = append(e.errors, err...)
}
......
......@@ -23,7 +23,7 @@ import (
"k8s.io/kube-openapi/pkg/util/proto"
)
type ValidationItem interface {
type validationItem interface {
proto.SchemaVisitor
Errors() []error
......@@ -31,7 +31,7 @@ type ValidationItem interface {
}
type baseItem struct {
errors Errors
errors errors
path proto.Path
}
......@@ -78,7 +78,7 @@ func (item *mapItem) sortedKeys() []string {
return sortedKeys
}
var _ ValidationItem = &mapItem{}
var _ validationItem = &mapItem{}
func (item *mapItem) VisitPrimitive(schema *proto.Primitive) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: schema.Type, Actual: "map"})
......@@ -139,7 +139,7 @@ type arrayItem struct {
Array []interface{}
}
var _ ValidationItem = &arrayItem{}
var _ validationItem = &arrayItem{}
func (item *arrayItem) VisitPrimitive(schema *proto.Primitive) {
item.AddValidationError(InvalidTypeError{Path: schema.GetPath().String(), Expected: schema.Type, Actual: "array"})
......@@ -183,7 +183,7 @@ type primitiveItem struct {
Kind string
}
var _ ValidationItem = &primitiveItem{}
var _ validationItem = &primitiveItem{}
func (item *primitiveItem) VisitPrimitive(schema *proto.Primitive) {
// Some types of primitives can match more than one (a number
......@@ -232,7 +232,7 @@ func (item *primitiveItem) VisitReference(schema proto.Reference) {
}
// itemFactory creates the relevant item type/visitor based on the current yaml type.
func itemFactory(path proto.Path, v interface{}) (ValidationItem, error) {
func itemFactory(path proto.Path, v interface{}) (validationItem, error) {
// We need to special case for no-type fields in yaml (e.g. empty item in list)
if v == nil {
return nil, InvalidObjectTypeError{Type: "nil", Path: path.String()}
......
/*
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 (
"k8s.io/kube-openapi/pkg/util/proto"
)
func ValidateModel(obj interface{}, schema proto.Schema, name string) []error {
rootValidation, err := itemFactory(proto.NewPath(name), obj)
if err != nil {
return []error{err}
}
schema.Accept(rootValidation)
return rootValidation.Errors()
}
/*
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 util
import "strings"
// ToCanonicalName converts Golang package/type name into canonical OpenAPI name.
// Examples:
// Input: k8s.io/api/core/v1.Pod
// Output: io.k8s.api.core.v1.Pod
//
// Input: k8s.io/api/core/v1
// Output: io.k8s.api.core.v1
func ToCanonicalName(name string) string {
nameParts := strings.Split(name, "/")
// Reverse first part. e.g., io.k8s... instead of k8s.io...
if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") {
parts := strings.Split(nameParts[0], ".")
for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {
parts[i], parts[j] = parts[j], parts[i]
}
nameParts[0] = strings.Join(parts, ".")
}
return strings.Join(nameParts, ".")
}
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