mirror of https://github.com/k3s-io/k3s
Merge pull request #46317 from monopole/kubectlValidator
Automatic merge from submit-queue Remove kubectl's dependence on schema file in pkg/api/validation. **What this PR does / why we need it**: Makes functions in validation/schema.go private to kubectl, further isolating kubectl. This move revealed a "hidden" dependence (a dependence not expressed in a BUILD or make file) from a feature level test in /hack/make-rules on a kubectl test data file. So this PR also adds some BUILD rules around the relevant hack targets, to make the dependence official. A later PR will move the kubectl aspect of this "hack" test into a kubectl test directory. Leaving it in place for now after establishing and "official" dependency, since moving the test beyond PR scope. The test also depends on a small sh file in //cluster, which makes no sense. **Which issue this PR fixes** Part of a series of PRs to address kubernetes/community#598 **Release note**: ```release-note NONE ```pull/6/head
commit
225b9119d6
|
@ -525,7 +525,7 @@ bazel-build:
|
|||
@echo "$$BAZEL_BUILD_HELP_INFO"
|
||||
else
|
||||
bazel-build:
|
||||
bazel build //cmd/... //pkg/... //federation/... //plugin/... //third_party/... //examples/... //test/... //vendor/k8s.io/...
|
||||
bazel build //cmd/... //hack/... //pkg/... //federation/... //plugin/... //third_party/... //examples/... //test/... //vendor/k8s.io/...
|
||||
endif
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ package_group(
|
|||
package_group(
|
||||
name = "COMMON_testing",
|
||||
packages = [
|
||||
"//hack",
|
||||
"//hack/lib",
|
||||
"//hack/make-rules",
|
||||
"//test/e2e",
|
||||
"//test/e2e/framework",
|
||||
"//test/e2e/kubectl",
|
||||
|
@ -69,6 +72,13 @@ package_group(
|
|||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "cluster",
|
||||
packages = [
|
||||
"//cluster/...",
|
||||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "KUBEADM_BAD",
|
||||
packages = [
|
||||
|
@ -363,6 +373,16 @@ package_group(
|
|||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "pkg_kubectl_validation_CONSUMERS",
|
||||
packages = [
|
||||
"//pkg/kubectl",
|
||||
"//pkg/kubectl/cmd/testing",
|
||||
"//pkg/kubectl/cmd/util",
|
||||
"//pkg/kubectl/resource",
|
||||
],
|
||||
)
|
||||
|
||||
# Added by ./hack/verify-bazel.sh; should be excluded from
|
||||
# that script since it makes no sense here.
|
||||
filegroup(
|
||||
|
|
|
@ -18,6 +18,7 @@ filegroup(
|
|||
"//cluster/images/etcd-version-monitor:all-srcs",
|
||||
"//cluster/images/etcd/attachlease:all-srcs",
|
||||
"//cluster/images/etcd/rollback:all-srcs",
|
||||
"//cluster/lib:all-srcs",
|
||||
"//cluster/saltbase:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
sh_library(
|
||||
name = "lib",
|
||||
srcs = [
|
||||
"logging.sh",
|
||||
],
|
||||
visibility = [
|
||||
"//build/visible_to:COMMON_testing",
|
||||
"//build/visible_to:cluster",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = [
|
||||
"//build/visible_to:cluster",
|
||||
],
|
||||
)
|
|
@ -22,6 +22,7 @@ filegroup(
|
|||
"//hack/cmd/teststale:all-srcs",
|
||||
"//hack/e2e-internal:all-srcs",
|
||||
"//hack/lib:all-srcs",
|
||||
"//hack/make-rules:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
sh_library(
|
||||
name = "lib",
|
||||
srcs = [
|
||||
"etcd.sh",
|
||||
"golang.sh",
|
||||
"init.sh",
|
||||
"swagger.sh",
|
||||
"test.sh",
|
||||
"util.sh",
|
||||
"version.sh",
|
||||
],
|
||||
deps = [
|
||||
"//cluster/lib",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
# Scripts runnable from make, e.g.
|
||||
#
|
||||
# cd $GOPATH/src/k8s.io/kubernetes
|
||||
# make test-e2e-node
|
||||
#
|
||||
# The sh_binary rules below exist only to validate
|
||||
# dependencies; if a shell dependency is accidentally
|
||||
# deleted, a presubmit BUILD will fail.
|
||||
#
|
||||
# If the scripts sourced their dependencies from
|
||||
# $RUNFILES (rather than $BASH_SOURCE/../.. or
|
||||
# whatever), then bazel build hack/... would install
|
||||
# runnable, hermetically sealed shell "binaries".
|
||||
# E.g. the following command would work:
|
||||
#
|
||||
# ./bazel-bin/hack/make-rules/test-e2e-node
|
||||
#
|
||||
# TODO(#47064): Should be a sh_test instead of sh_binary
|
||||
sh_binary(
|
||||
name = "test-cmd",
|
||||
srcs = ["test-cmd.sh"],
|
||||
deps = [
|
||||
":test-cmd-util",
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "test-e2e-node",
|
||||
srcs = ["test-e2e-node.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "test-federation-cmd",
|
||||
srcs = ["test-federation-cmd.sh"],
|
||||
deps = [
|
||||
":test-cmd-util",
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "test-integration",
|
||||
srcs = ["test-cmd.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "test-kubeadm-cmd",
|
||||
srcs = ["test-kubeadm-cmd.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "build",
|
||||
srcs = ["build.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "cross",
|
||||
srcs = ["cross.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "test",
|
||||
srcs = ["test.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "vet",
|
||||
srcs = ["vet.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "verify",
|
||||
srcs = ["verify.sh"],
|
||||
deps = [
|
||||
"//hack/lib",
|
||||
],
|
||||
)
|
||||
|
||||
sh_library(
|
||||
name = "test-cmd-util",
|
||||
srcs = [
|
||||
"test-cmd-util.sh",
|
||||
],
|
||||
data = ["//pkg/kubectl/validation:testdata/v1/validPod.yaml"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -687,7 +687,7 @@ run_pod_tests() {
|
|||
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
|
||||
|
||||
## Patch can modify a local object
|
||||
kubectl patch --local -f pkg/api/validation/testdata/v1/validPod.yaml --patch='{"spec": {"restartPolicy":"Never"}}' -o jsonpath='{.spec.restartPolicy}' | grep -q "Never"
|
||||
kubectl patch --local -f pkg/kubectl/validation/testdata/v1/validPod.yaml --patch='{"spec": {"restartPolicy":"Never"}}' -o jsonpath='{.spec.restartPolicy}' | grep -q "Never"
|
||||
|
||||
## Patch pod can change image
|
||||
# Command
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
|
@ -11,9 +9,9 @@ go_library(
|
|||
srcs = [
|
||||
"doc.go",
|
||||
"events.go",
|
||||
"schema.go",
|
||||
"validation.go",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/helper:go_default_library",
|
||||
|
@ -24,8 +22,6 @@ go_library(
|
|||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
||||
"//vendor/github.com/exponent-io/jsonpath:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
|
@ -33,16 +29,13 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels: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/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -51,38 +44,22 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = [
|
||||
"events_test.go",
|
||||
"schema_test.go",
|
||||
"validation_test.go",
|
||||
],
|
||||
data = [
|
||||
"testdata/v1/invalidPod.yaml",
|
||||
"testdata/v1/invalidPod1.json",
|
||||
"testdata/v1/invalidPod2.json",
|
||||
"testdata/v1/invalidPod3.json",
|
||||
"testdata/v1/invalidPod4.yaml",
|
||||
"testdata/v1/validPod.yaml",
|
||||
"//api/swagger-spec",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/helper:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -91,11 +68,11 @@ filegroup(
|
|||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/helper"
|
||||
_ "k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
)
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["doc.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
|
@ -22,3 +12,10 @@ filegroup(
|
|||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["doc.go"],
|
||||
)
|
||||
|
|
|
@ -191,6 +191,7 @@ filegroup(
|
|||
"//pkg/kubectl/resource:all-srcs",
|
||||
"//pkg/kubectl/testing:all-srcs",
|
||||
"//pkg/kubectl/util:all-srcs",
|
||||
"//pkg/kubectl/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
|
|
@ -16,13 +16,13 @@ go_library(
|
|||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/plugins:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/kubectl/validation:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
|
|
|
@ -39,13 +39,13 @@ import (
|
|||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ go_library(
|
|||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
|
@ -37,6 +36,7 @@ go_library(
|
|||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/plugins:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/kubectl/validation:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/printers/internalversion:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
|
@ -93,7 +93,6 @@ go_test(
|
|||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
|
@ -102,6 +101,7 @@ go_test(
|
|||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/kubectl/validation:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
||||
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
|
|
|
@ -29,7 +29,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
swagger "github.com/emicklei/go-restful-swagger12"
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -48,13 +48,13 @@ import (
|
|||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import (
|
|||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
|
@ -49,6 +48,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
)
|
||||
|
|
|
@ -45,12 +45,12 @@ import (
|
|||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
)
|
||||
|
||||
func TestNewFactoryDefaultFlagBindings(t *testing.T) {
|
||||
|
|
|
@ -22,7 +22,7 @@ go_library(
|
|||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/kubectl/validation:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
||||
"//vendor/golang.org/x/text/transform:go_default_library",
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
)
|
||||
|
||||
var FileExtensions = []string{".json", ".yaml", ".yml"}
|
||||
|
|
|
@ -38,7 +38,7 @@ import (
|
|||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
exports_files(
|
||||
srcs = [
|
||||
"testdata/v1/validPod.yaml",
|
||||
],
|
||||
visibility = ["//build/visible_to:COMMON_testing"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "testdata",
|
||||
srcs = [
|
||||
"testdata/v1/invalidPod.yaml",
|
||||
"testdata/v1/invalidPod1.json",
|
||||
"testdata/v1/invalidPod2.json",
|
||||
"testdata/v1/invalidPod3.json",
|
||||
"testdata/v1/invalidPod4.yaml",
|
||||
"testdata/v1/validPod.yaml",
|
||||
],
|
||||
visibility = ["//build/visible_to:COMMON_testing"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["schema_test.go"],
|
||||
data = [
|
||||
":testdata",
|
||||
"//api/swagger-spec",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["schema.go"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//build/visible_to:pkg_kubectl_validation_CONSUMERS"],
|
||||
deps = [
|
||||
"//pkg/api/util:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful-swagger12:go_default_library",
|
||||
"//vendor/github.com/exponent-io/jsonpath:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//build/visible_to:pkg_kubectl_validation_CONSUMERS"],
|
||||
)
|
|
@ -24,7 +24,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
swagger "github.com/emicklei/go-restful-swagger12"
|
||||
ejson "github.com/exponent-io/jsonpath"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -33,6 +33,7 @@ import (
|
|||
apiutil "k8s.io/kubernetes/pkg/api/util"
|
||||
)
|
||||
|
||||
// InvalidTypeError records information about an invalid type.
|
||||
type InvalidTypeError struct {
|
||||
ExpectedKind reflect.Kind
|
||||
ObservedKind reflect.Kind
|
||||
|
@ -43,6 +44,7 @@ func (i *InvalidTypeError) Error() string {
|
|||
return fmt.Sprintf("expected type %s, for field %s, got %s", i.ExpectedKind.String(), i.FieldName, i.ObservedKind.String())
|
||||
}
|
||||
|
||||
// NewInvalidTypeError returns an instance of NewInvalidTypeError.
|
||||
func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName string) error {
|
||||
return &InvalidTypeError{expected, observed, fieldName}
|
||||
}
|
||||
|
@ -60,14 +62,18 @@ type Schema interface {
|
|||
ValidateBytes(data []byte) error
|
||||
}
|
||||
|
||||
// NullSchema always validates bytes.
|
||||
type NullSchema struct{}
|
||||
|
||||
// ValidateBytes never fails for NullSchema.
|
||||
func (NullSchema) ValidateBytes(data []byte) error { return nil }
|
||||
|
||||
// NoDoubleKeySchema is a schema that disallows double keys.
|
||||
type NoDoubleKeySchema struct{}
|
||||
|
||||
// ValidateBytes validates bytes.
|
||||
func (NoDoubleKeySchema) ValidateBytes(data []byte) error {
|
||||
var list []error = nil
|
||||
var list []error
|
||||
if err := validateNoDuplicateKeys(data, "metadata", "labels"); err != nil {
|
||||
list = append(list, err)
|
||||
}
|
||||
|
@ -107,17 +113,18 @@ func validateNoDuplicateKeys(data []byte, path ...string) error {
|
|||
case ejson.KeyString:
|
||||
if seen[string(t)] {
|
||||
return fmt.Errorf("duplicate key: %s", string(t))
|
||||
} else {
|
||||
seen[string(t)] = true
|
||||
}
|
||||
seen[string(t)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConjunctiveSchema encapsulates a schema list.
|
||||
type ConjunctiveSchema []Schema
|
||||
|
||||
// ValidateBytes validates bytes per a ConjunctiveSchema.
|
||||
func (c ConjunctiveSchema) ValidateBytes(data []byte) error {
|
||||
var list []error = nil
|
||||
var list []error
|
||||
schemas := []Schema(c)
|
||||
for ix := range schemas {
|
||||
if err := schemas[ix].ValidateBytes(data); err != nil {
|
||||
|
@ -127,11 +134,13 @@ func (c ConjunctiveSchema) ValidateBytes(data []byte) error {
|
|||
return utilerrors.NewAggregate(list)
|
||||
}
|
||||
|
||||
// SwaggerSchema is a schema based on an OpenAPI spec.
|
||||
type SwaggerSchema struct {
|
||||
api swagger.ApiDeclaration
|
||||
delegate Schema // For delegating to other api groups
|
||||
}
|
||||
|
||||
// NewSwaggerSchemaFromBytes creates an instance of SwaggerSchema from bytes.
|
||||
func NewSwaggerSchemaFromBytes(data []byte, factory Schema) (Schema, error) {
|
||||
schema := &SwaggerSchema{}
|
||||
err := json.Unmarshal(data, &schema.api)
|
||||
|
@ -201,6 +210,7 @@ func (s *SwaggerSchema) validateItems(items interface{}) []error {
|
|||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateBytes validates bytes in a SwaggerSchema.
|
||||
func (s *SwaggerSchema) ValidateBytes(data []byte) error {
|
||||
var obj interface{}
|
||||
out, err := yaml.ToJSON(data)
|
||||
|
@ -240,6 +250,7 @@ func (s *SwaggerSchema) ValidateBytes(data []byte) error {
|
|||
return utilerrors.NewAggregate(allErrs)
|
||||
}
|
||||
|
||||
// ValidateObject returns no errors for a valid object.
|
||||
func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName string) []error {
|
||||
allErrs := []error{}
|
||||
models := s.api.Models
|
||||
|
@ -249,13 +260,13 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri
|
|||
// s.api only has schema for 1 api version (the parent object type's version).
|
||||
// e.g. an extensions/v1beta1 Template embedding a /v1 Service requires the schema for the extensions/v1beta1
|
||||
// api to delegate to the schema for the /v1 api.
|
||||
// Only do this for !ok objects so that cross ApiVersion vendored types take precedence.
|
||||
// Only do this for !ok objects so that cross APIVersion vendored types take precedence.
|
||||
if !ok && s.delegate != nil {
|
||||
fields, mapOk := obj.(map[string]interface{})
|
||||
if !mapOk {
|
||||
return append(allErrs, fmt.Errorf("field %s for %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, typeName, obj))
|
||||
}
|
||||
if delegated, err := s.delegateIfDifferentApiVersion(&unstructured.Unstructured{Object: fields}); delegated {
|
||||
if delegated, err := s.delegateIfDifferentAPIVersion(&unstructured.Unstructured{Object: fields}); delegated {
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
|
@ -322,13 +333,13 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri
|
|||
return allErrs
|
||||
}
|
||||
|
||||
// delegateIfDifferentApiVersion delegates the validation of an object if its ApiGroup does not match the
|
||||
// delegateIfDifferentAPIVersion delegates the validation of an object if its ApiGroup does not match the
|
||||
// current SwaggerSchema.
|
||||
// First return value is true if the validation was delegated (by a different ApiGroup SwaggerSchema)
|
||||
// Second return value is the result of the delegated validation if performed.
|
||||
func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj *unstructured.Unstructured) (bool, error) {
|
||||
// Never delegate objects in the same ApiVersion or we will get infinite recursion
|
||||
if !s.isDifferentApiVersion(obj) {
|
||||
func (s *SwaggerSchema) delegateIfDifferentAPIVersion(obj *unstructured.Unstructured) (bool, error) {
|
||||
// Never delegate objects in the same APIVersion or we will get infinite recursion
|
||||
if !s.isDifferentAPIVersion(obj) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
@ -342,9 +353,9 @@ func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj *unstructured.Unstruct
|
|||
return true, s.delegate.ValidateBytes(m)
|
||||
}
|
||||
|
||||
// isDifferentApiVersion Returns true if obj lives in a different ApiVersion than the SwaggerSchema does.
|
||||
// The SwaggerSchema will not be able to process objects in different ApiVersions unless they are vendored.
|
||||
func (s *SwaggerSchema) isDifferentApiVersion(obj *unstructured.Unstructured) bool {
|
||||
// isDifferentAPIVersion Returns true if obj lives in a different APIVersion than the SwaggerSchema does.
|
||||
// The SwaggerSchema will not be able to process objects in different APIVersions unless they are vendored.
|
||||
func (s *SwaggerSchema) isDifferentAPIVersion(obj *unstructured.Unstructured) bool {
|
||||
groupVersion := obj.GetAPIVersion()
|
||||
return len(groupVersion) > 0 && s.api.ApiVersion != groupVersion
|
||||
}
|
|
@ -42,10 +42,10 @@ func readPod(filename string) ([]byte, error) {
|
|||
}
|
||||
|
||||
func readSwaggerFile() ([]byte, error) {
|
||||
return readSwaggerApiFile(testapi.Default)
|
||||
return readSwaggerAPIFile(testapi.Default)
|
||||
}
|
||||
|
||||
func readSwaggerApiFile(group testapi.TestGroup) ([]byte, error) {
|
||||
func readSwaggerAPIFile(group testapi.TestGroup) ([]byte, error) {
|
||||
// TODO: Figure out a better way of finding these files
|
||||
var pathToSwaggerSpec string
|
||||
if group.GroupVersion().Group == "" {
|
||||
|
@ -102,7 +102,7 @@ func loadSchemaForTest() (Schema, error) {
|
|||
}
|
||||
|
||||
func loadSchemaForTestWithFactory(group testapi.TestGroup, factory Schema) (Schema, error) {
|
||||
data, err := readSwaggerApiFile(group)
|
||||
data, err := readSwaggerAPIFile(group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -187,15 +187,15 @@ func TestValidateDifferentApiVersions(t *testing.T) {
|
|||
}
|
||||
err = schema.ValidateBytes(bytes)
|
||||
if err == nil {
|
||||
t.Error(fmt.Errorf("Expected error when validating different api version and no delegate exists."))
|
||||
t.Error(fmt.Errorf("expected error when validating different api version and no delegate exists"))
|
||||
}
|
||||
f, err := NewFactory()
|
||||
if err != nil {
|
||||
t.Error(fmt.Errorf("Failed to create Schema factory %v.", err))
|
||||
t.Error(fmt.Errorf("failed to create Schema factory %v", err))
|
||||
}
|
||||
err = f.ValidateBytes(bytes)
|
||||
if err != nil {
|
||||
t.Error(fmt.Errorf("Failed to validate object with multiple ApiGroups: %v.", err))
|
||||
t.Error(fmt.Errorf("failed to validate object with multiple ApiGroups: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,10 +377,12 @@ func TestValidateDuplicateLabelsPassCases(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// AlwaysInvalidSchema is always invalid.
|
||||
type AlwaysInvalidSchema struct{}
|
||||
|
||||
// ValidateBytes always fails to validate.
|
||||
func (AlwaysInvalidSchema) ValidateBytes([]byte) error {
|
||||
return fmt.Errorf("Always invalid!")
|
||||
return fmt.Errorf("always invalid")
|
||||
}
|
||||
|
||||
func TestConjunctiveSchema(t *testing.T) {
|
Loading…
Reference in New Issue