Move pkg/kubectl/cmd/util/openapi to staging
This commit is contained in:
@@ -17,8 +17,8 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl/apply:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@@ -21,8 +21,8 @@ import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// Factory creates an Element by combining object values from recorded, local and remote sources with
|
||||
|
@@ -17,8 +17,8 @@ limitations under the License.
|
||||
package parse
|
||||
|
||||
import (
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// ItemVisitor provides an interface for Items to Accept and call
|
||||
|
@@ -38,9 +38,9 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/kubectl/apply:go_default_library",
|
||||
"//pkg/kubectl/apply/parse:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/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",
|
||||
|
@@ -19,9 +19,9 @@ package strategy_test
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
tst "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply/strategy"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
)
|
||||
|
||||
var _ = Describe("Merging fields of type list-of-map with openapi", func() {
|
||||
|
@@ -19,9 +19,9 @@ package strategy_test
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
tst "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply/strategy"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
)
|
||||
|
||||
var _ = Describe("Replacing fields of type map with openapi for some fields", func() {
|
||||
|
@@ -26,10 +26,10 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
tst "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply"
|
||||
"k8s.io/kubernetes/pkg/kubectl/apply/parse"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -14,7 +14,6 @@ go_library(
|
||||
"//pkg/kubectl/cmd/delete:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
@@ -36,6 +35,7 @@ go_library(
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/validation:go_default_library",
|
||||
"//vendor/github.com/jonboulle/clockwork:go_default_library",
|
||||
@@ -57,7 +57,6 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
@@ -73,6 +72,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/rest/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
|
@@ -49,11 +49,11 @@ import (
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/delete"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// ApplyOptions defines flags and other configuration parameters for the `apply` command
|
||||
|
@@ -47,9 +47,9 @@ import (
|
||||
"k8s.io/client-go/rest/fake"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
|
@@ -8,7 +8,6 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/apply:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
@@ -22,6 +21,7 @@ go_library(
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
|
||||
"//vendor/github.com/jonboulle/clockwork:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
|
@@ -39,10 +39,10 @@ import (
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/utils/exec"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
@@ -7,12 +7,12 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/explain:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
],
|
||||
|
@@ -25,9 +25,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/explain"
|
||||
)
|
||||
|
||||
|
@@ -30,7 +30,6 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
@@ -54,6 +53,7 @@ go_library(
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/i18n:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/interrupt:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/printers:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
|
||||
"//vendor/github.com/liggitt/tabwriter:go_default_library",
|
||||
@@ -82,8 +82,6 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||
@@ -105,6 +103,8 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/rest/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest/watch:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/printers:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
|
@@ -25,7 +25,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
)
|
||||
|
||||
// PrintFlags composes common printer flag structs
|
||||
|
@@ -48,9 +48,9 @@ import (
|
||||
restclientwatch "k8s.io/client-go/rest/watch"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
openapitesting "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@@ -12,8 +12,6 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
@@ -35,6 +33,8 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@@ -45,11 +45,11 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
openapitesting "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
)
|
||||
|
||||
// InternalType is the schema for internal type
|
||||
|
@@ -13,8 +13,6 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util",
|
||||
visibility = ["//build/visible_to:pkg_kubectl_cmd_util_CONSUMERS"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi/validation:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
@@ -34,6 +32,8 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/scale:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi/validation:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/validation:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/version:go_default_library",
|
||||
@@ -79,7 +79,6 @@ filegroup(
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubectl/cmd/util/editor:all-srcs",
|
||||
"//pkg/kubectl/cmd/util/openapi:all-srcs",
|
||||
"//pkg/kubectl/cmd/util/sanity:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
@@ -23,8 +23,8 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
// Factory provides abstractions that allow the Kubectl command to be extended across multiple types
|
||||
|
@@ -30,9 +30,9 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
openapivalidation "k8s.io/kubectl/pkg/util/openapi/validation"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
openapivalidation "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation"
|
||||
)
|
||||
|
||||
type factoryImpl struct {
|
||||
|
@@ -1,72 +0,0 @@
|
||||
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",
|
||||
"dryrun.go",
|
||||
"extensions.go",
|
||||
"openapi.go",
|
||||
"openapi_getter.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||
"//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/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"dryrun_test.go",
|
||||
"openapi_getter_test.go",
|
||||
"openapi_suite_test.go",
|
||||
"openapi_test.go",
|
||||
],
|
||||
data = ["//api/openapi-spec"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema: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/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/*"]),
|
||||
)
|
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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 // k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi
|
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"errors"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func hasGVKExtension(extensions []*openapi_v2.NamedAny, gvk schema.GroupVersionKind) bool {
|
||||
for _, extension := range extensions {
|
||||
if extension.GetValue().GetYaml() == "" ||
|
||||
extension.GetName() != "x-kubernetes-group-version-kind" {
|
||||
continue
|
||||
}
|
||||
var value map[string]string
|
||||
err := yaml.Unmarshal([]byte(extension.GetValue().GetYaml()), &value)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if value["group"] == gvk.Group && value["kind"] == gvk.Kind && value["version"] == gvk.Version {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SupportsDryRun is a method that let's us look in the OpenAPI if the
|
||||
// specific group-version-kind supports the dryRun query parameter for
|
||||
// the PATCH end-point.
|
||||
func SupportsDryRun(doc *openapi_v2.Document, gvk schema.GroupVersionKind) (bool, error) {
|
||||
for _, path := range doc.GetPaths().GetPath() {
|
||||
// Is this describing the gvk we're looking for?
|
||||
if !hasGVKExtension(path.GetValue().GetPatch().GetVendorExtension(), gvk) {
|
||||
continue
|
||||
}
|
||||
for _, param := range path.GetValue().GetPatch().GetParameters() {
|
||||
if param.GetParameter().GetNonBodyParameter().GetQueryParameterSubSchema().GetName() == "dryRun" {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, errors.New("couldn't find GVK in openapi")
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
)
|
||||
|
||||
func TestSupportsDryRun(t *testing.T) {
|
||||
doc, err := fakeSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get OpenAPI Schema: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
gvk schema.GroupVersionKind
|
||||
success bool
|
||||
supports bool
|
||||
}{
|
||||
{
|
||||
gvk: schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Kind: "Pod",
|
||||
},
|
||||
success: true,
|
||||
supports: true,
|
||||
},
|
||||
{
|
||||
gvk: schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Kind: "UnknownKind",
|
||||
},
|
||||
success: false,
|
||||
supports: false,
|
||||
},
|
||||
{
|
||||
gvk: schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Kind: "NodeProxyOptions",
|
||||
},
|
||||
success: true,
|
||||
supports: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
supports, err := openapi.SupportsDryRun(doc, test.gvk)
|
||||
if supports != test.supports || ((err == nil) != test.success) {
|
||||
errStr := "nil"
|
||||
if test.success == false {
|
||||
errStr = "err"
|
||||
}
|
||||
t.Errorf("SupportsDryRun(doc, %v) = (%v, %v), expected (%v, %v)",
|
||||
test.gvk,
|
||||
supports, err,
|
||||
test.supports, errStr,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
// PrintColumnsKey is the key that defines which columns should be printed
|
||||
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)
|
||||
}
|
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
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{}
|
||||
|
||||
// NewOpenAPIData creates a new `Resources` out of the openapi 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
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
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
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
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))
|
||||
})
|
||||
})
|
||||
})
|
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
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") }
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
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())
|
||||
})
|
||||
})
|
@@ -1,31 +0,0 @@
|
||||
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",
|
||||
"//staging/src/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"],
|
||||
)
|
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
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
|
||||
}
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
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",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//staging/src/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"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors: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/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"],
|
||||
)
|
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
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
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
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") }
|
@@ -1,412 +0,0 @@
|
||||
/*
|
||||
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/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: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
name: redis-master
|
||||
name: name
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
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())
|
||||
})
|
||||
})
|
@@ -52,9 +52,9 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
tst "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
)
|
||||
|
||||
func TestRecursiveFields(t *testing.T) {
|
||||
|
@@ -20,7 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
tst "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
|
||||
tst "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
)
|
||||
|
||||
var resources = tst.NewFakeResources("test-swagger.json")
|
||||
|
Reference in New Issue
Block a user