diff --git a/build/root/Makefile b/build/root/Makefile index 08ae44eb25b..b0c59bf24f2 100644 --- a/build/root/Makefile +++ b/build/root/Makefile @@ -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 diff --git a/build/visible_to/BUILD b/build/visible_to/BUILD index 137ba266703..fef19852b3c 100644 --- a/build/visible_to/BUILD +++ b/build/visible_to/BUILD @@ -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( diff --git a/cluster/BUILD b/cluster/BUILD index f438392f5be..d2b7027f8c2 100644 --- a/cluster/BUILD +++ b/cluster/BUILD @@ -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"], diff --git a/cluster/lib/BUILD b/cluster/lib/BUILD new file mode 100644 index 00000000000..9634d17f6f4 --- /dev/null +++ b/cluster/lib/BUILD @@ -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", + ], +) diff --git a/hack/BUILD b/hack/BUILD index d6c48907976..e07e77cb048 100644 --- a/hack/BUILD +++ b/hack/BUILD @@ -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"], ) diff --git a/hack/lib/BUILD b/hack/lib/BUILD index 7e76248ad95..4c3122fb09f 100644 --- a/hack/lib/BUILD +++ b/hack/lib/BUILD @@ -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(["**"]), diff --git a/hack/make-rules/BUILD b/hack/make-rules/BUILD new file mode 100644 index 00000000000..47fdd3b5eb6 --- /dev/null +++ b/hack/make-rules/BUILD @@ -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"], +) diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh old mode 100644 new mode 100755 index 763e8f116e5..0cd61775f1f --- a/hack/make-rules/test-cmd-util.sh +++ b/hack/make-rules/test-cmd-util.sh @@ -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 diff --git a/pkg/api/validation/BUILD b/pkg/api/validation/BUILD index 7c1615d1782..c0b1cbd9485 100644 --- a/pkg/api/validation/BUILD +++ b/pkg/api/validation/BUILD @@ -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"], ) diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index a849df8445f..5a55f5aa4e8 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -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" ) diff --git a/pkg/hyperkube/BUILD b/pkg/hyperkube/BUILD index df044c0ebf9..b07624e5623 100644 --- a/pkg/hyperkube/BUILD +++ b/pkg/hyperkube/BUILD @@ -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"], +) diff --git a/pkg/kubectl/BUILD b/pkg/kubectl/BUILD index de5db2ae0bd..35f8eff04c8 100644 --- a/pkg/kubectl/BUILD +++ b/pkg/kubectl/BUILD @@ -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"], ) diff --git a/pkg/kubectl/cmd/testing/BUILD b/pkg/kubectl/cmd/testing/BUILD index 62f5708a2d0..aabfba74673 100644 --- a/pkg/kubectl/cmd/testing/BUILD +++ b/pkg/kubectl/cmd/testing/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 595d07552ea..5b8731b66d6 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -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" ) diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index 99473b51dc0..1035d9aaf83 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 13419716ce5..1fdae62c9ab 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -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" ) diff --git a/pkg/kubectl/cmd/util/factory_object_mapping.go b/pkg/kubectl/cmd/util/factory_object_mapping.go index 83cb1b30dbf..5976982da67 100644 --- a/pkg/kubectl/cmd/util/factory_object_mapping.go +++ b/pkg/kubectl/cmd/util/factory_object_mapping.go @@ -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" ) diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index bfeaf5ee32d..66304691467 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -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) { diff --git a/pkg/kubectl/resource/BUILD b/pkg/kubectl/resource/BUILD index 2e7ce43f1a0..1858e130ba4 100644 --- a/pkg/kubectl/resource/BUILD +++ b/pkg/kubectl/resource/BUILD @@ -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", diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 64940731a2e..eb563fb51bf 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -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"} diff --git a/pkg/kubectl/resource/visitor.go b/pkg/kubectl/resource/visitor.go index b01619e613a..5e5a73a3160 100644 --- a/pkg/kubectl/resource/visitor.go +++ b/pkg/kubectl/resource/visitor.go @@ -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 ( diff --git a/pkg/kubectl/validation/BUILD b/pkg/kubectl/validation/BUILD new file mode 100644 index 00000000000..3b2de79ad25 --- /dev/null +++ b/pkg/kubectl/validation/BUILD @@ -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"], +) diff --git a/pkg/api/validation/schema.go b/pkg/kubectl/validation/schema.go similarity index 90% rename from pkg/api/validation/schema.go rename to pkg/kubectl/validation/schema.go index 3f98345c38c..b75907aefbe 100644 --- a/pkg/api/validation/schema.go +++ b/pkg/kubectl/validation/schema.go @@ -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 } diff --git a/pkg/api/validation/schema_test.go b/pkg/kubectl/validation/schema_test.go similarity index 95% rename from pkg/api/validation/schema_test.go rename to pkg/kubectl/validation/schema_test.go index 39090bcd712..74a9cd38f73 100644 --- a/pkg/api/validation/schema_test.go +++ b/pkg/kubectl/validation/schema_test.go @@ -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) { diff --git a/pkg/api/validation/testdata/v1/invalidPod.yaml b/pkg/kubectl/validation/testdata/v1/invalidPod.yaml similarity index 100% rename from pkg/api/validation/testdata/v1/invalidPod.yaml rename to pkg/kubectl/validation/testdata/v1/invalidPod.yaml diff --git a/pkg/api/validation/testdata/v1/invalidPod1.json b/pkg/kubectl/validation/testdata/v1/invalidPod1.json similarity index 100% rename from pkg/api/validation/testdata/v1/invalidPod1.json rename to pkg/kubectl/validation/testdata/v1/invalidPod1.json diff --git a/pkg/api/validation/testdata/v1/invalidPod2.json b/pkg/kubectl/validation/testdata/v1/invalidPod2.json similarity index 100% rename from pkg/api/validation/testdata/v1/invalidPod2.json rename to pkg/kubectl/validation/testdata/v1/invalidPod2.json diff --git a/pkg/api/validation/testdata/v1/invalidPod3.json b/pkg/kubectl/validation/testdata/v1/invalidPod3.json similarity index 100% rename from pkg/api/validation/testdata/v1/invalidPod3.json rename to pkg/kubectl/validation/testdata/v1/invalidPod3.json diff --git a/pkg/api/validation/testdata/v1/invalidPod4.yaml b/pkg/kubectl/validation/testdata/v1/invalidPod4.yaml similarity index 100% rename from pkg/api/validation/testdata/v1/invalidPod4.yaml rename to pkg/kubectl/validation/testdata/v1/invalidPod4.yaml diff --git a/pkg/api/validation/testdata/v1/validPod.yaml b/pkg/kubectl/validation/testdata/v1/validPod.yaml similarity index 100% rename from pkg/api/validation/testdata/v1/validPod.yaml rename to pkg/kubectl/validation/testdata/v1/validPod.yaml