diff --git a/test/integration/etcd/BUILD b/test/integration/etcd/BUILD index bb8b85daf02..7bdff725faf 100644 --- a/test/integration/etcd/BUILD +++ b/test/integration/etcd/BUILD @@ -21,7 +21,6 @@ go_test( "//cmd/kube-apiserver/app/options:go_default_library", "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/core:go_default_library", - "//pkg/kubectl/cmd/util:go_default_library", "//pkg/master:go_default_library", "//test/integration:go_default_library", "//test/integration/framework:go_default_library", @@ -38,10 +37,10 @@ go_test( "//vendor/k8s.io/apiserver/pkg/server:go_default_library", "//vendor/k8s.io/apiserver/pkg/server/options:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library", + "//vendor/k8s.io/client-go/discovery:go_default_library", + "//vendor/k8s.io/client-go/discovery/cached:go_default_library", "//vendor/k8s.io/client-go/kubernetes:go_default_library", "//vendor/k8s.io/client-go/rest:go_default_library", - "//vendor/k8s.io/client-go/tools/clientcmd:go_default_library", - "//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library", "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library", ], ) diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 711f37c5519..6c8d212aca0 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -43,16 +43,15 @@ import ( genericapiserver "k8s.io/apiserver/pkg/server" genericapiserveroptions "k8s.io/apiserver/pkg/server/options" "k8s.io/apiserver/pkg/storage/storagebackend" + "k8s.io/client-go/discovery" + cacheddiscovery "k8s.io/client-go/discovery/cached" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/cmd/kube-apiserver/app" "k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/pkg/api/legacyscheme" kapi "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/test/integration" "k8s.io/kubernetes/test/integration/framework" @@ -434,84 +433,84 @@ var etcdStorageData = map[schema.GroupVersionResource]struct { var ephemeralWhiteList = createEphemeralWhiteList( // k8s.io/kubernetes/pkg/api/v1 - gvr("", "v1", "bindings"), // annotation on pod, not stored in etcd - gvr("", "v1", "rangeallocations"), // stored in various places in etcd but cannot be directly created - gvr("", "v1", "componentstatuses"), // status info not stored in etcd - gvr("", "v1", "serializedreferences"), // used for serilization, not stored in etcd - gvr("", "v1", "nodeconfigsources"), // subfield of node.spec, but shouldn't be directly created - gvr("", "v1", "podstatusresults"), // wrapper object not stored in etcd + gvk("", "v1", "Binding"), // annotation on pod, not stored in etcd + gvk("", "v1", "RangeAllocation"), // stored in various places in etcd but cannot be directly created + gvk("", "v1", "ComponentStatus"), // status info not stored in etcd + gvk("", "v1", "SerializedReference"), // used for serilization, not stored in etcd + gvk("", "v1", "NodeConfigSource"), // subfield of node.spec, but shouldn't be directly created + gvk("", "v1", "PodStatusResult"), // wrapper object not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/authentication/v1beta1 - gvr("authentication.k8s.io", "v1beta1", "tokenreviews"), // not stored in etcd + gvk("authentication.k8s.io", "v1beta1", "TokenReview"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/authentication/v1 - gvr("authentication.k8s.io", "v1", "tokenreviews"), // not stored in etcd - gvr("authentication.k8s.io", "v1", "tokenrequests"), // not stored in etcd + gvk("authentication.k8s.io", "v1", "TokenReview"), // not stored in etcd + gvk("authentication.k8s.io", "v1", "TokenRequest"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/authorization/v1beta1 // SRR objects that are not stored in etcd - gvr("authorization.k8s.io", "v1beta1", "selfsubjectrulesreviews"), + gvk("authorization.k8s.io", "v1beta1", "SelfSubjectRulesReview"), // SAR objects that are not stored in etcd - gvr("authorization.k8s.io", "v1beta1", "selfsubjectaccessreviews"), - gvr("authorization.k8s.io", "v1beta1", "localsubjectaccessreviews"), - gvr("authorization.k8s.io", "v1beta1", "subjectaccessreviews"), + gvk("authorization.k8s.io", "v1beta1", "SelfSubjectAccessReview"), + gvk("authorization.k8s.io", "v1beta1", "LocalSubjectAccessReview"), + gvk("authorization.k8s.io", "v1beta1", "SubjectAccessReview"), // -- // k8s.io/kubernetes/pkg/apis/authorization/v1 // SRR objects that are not stored in etcd - gvr("authorization.k8s.io", "v1", "selfsubjectrulesreviews"), + gvk("authorization.k8s.io", "v1", "SelfSubjectRulesReview"), // SAR objects that are not stored in etcd - gvr("authorization.k8s.io", "v1", "selfsubjectaccessreviews"), - gvr("authorization.k8s.io", "v1", "localsubjectaccessreviews"), - gvr("authorization.k8s.io", "v1", "subjectaccessreviews"), + gvk("authorization.k8s.io", "v1", "SelfSubjectAccessReview"), + gvk("authorization.k8s.io", "v1", "LocalSubjectAccessReview"), + gvk("authorization.k8s.io", "v1", "SubjectAccessReview"), // -- // k8s.io/kubernetes/pkg/apis/autoscaling/v1 - gvr("autoscaling", "v1", "scales"), // not stored in etcd, part of kapiv1.ReplicationController + gvk("autoscaling", "v1", "Scale"), // not stored in etcd, part of kapiv1.ReplicationController // -- // k8s.io/kubernetes/pkg/apis/apps/v1beta1 - gvr("apps", "v1beta1", "scales"), // not stored in etcd, part of kapiv1.ReplicationController - gvr("apps", "v1beta1", "deploymentrollbacks"), // used to rollback deployment, not stored in etcd + gvk("apps", "v1beta1", "Scale"), // not stored in etcd, part of kapiv1.ReplicationController + gvk("apps", "v1beta1", "DeploymentRollback"), // used to rollback deployment, not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/apps/v1beta2 - gvr("apps", "v1beta2", "scales"), // not stored in etcd, part of kapiv1.ReplicationController + gvk("apps", "v1beta2", "Scale"), // not stored in etcd, part of kapiv1.ReplicationController // -- // k8s.io/kubernetes/pkg/apis/batch/v1beta1 - gvr("batch", "v1beta1", "jobtemplates"), // not stored in etcd + gvk("batch", "v1beta1", "JobTemplate"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/batch/v2alpha1 - gvr("batch", "v2alpha1", "jobtemplates"), // not stored in etcd + gvk("batch", "v2alpha1", "JobTemplate"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1 - gvr("componentconfig", "v1alpha1", "kubeschedulerconfigurations"), // not stored in etcd + gvk("componentconfig", "v1alpha1", "KubeSchedulerConfiguration"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/extensions/v1beta1 - gvr("extensions", "v1beta1", "deploymentrollbacks"), // used to rollback deployment, not stored in etcd - gvr("extensions", "v1beta1", "replicationcontrollerdummies"), // not stored in etcd - gvr("extensions", "v1beta1", "scales"), // not stored in etcd, part of kapiv1.ReplicationController + gvk("extensions", "v1beta1", "DeploymentRollback"), // used to rollback deployment, not stored in etcd + gvk("extensions", "v1beta1", "ReplicationControllerDummy"), // not stored in etcd + gvk("extensions", "v1beta1", "Scale"), // not stored in etcd, part of kapiv1.ReplicationController // -- // k8s.io/kubernetes/pkg/apis/imagepolicy/v1alpha1 - gvr("imagepolicy.k8s.io", "v1alpha1", "imagereviews"), // not stored in etcd + gvk("imagepolicy.k8s.io", "v1alpha1", "ImageReview"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/policy/v1beta1 - gvr("policy", "v1beta1", "evictions"), // not stored in etcd, deals with evicting kapiv1.Pod + gvk("policy", "v1beta1", "Eviction"), // not stored in etcd, deals with evicting kapiv1.Pod // -- // k8s.io/kubernetes/pkg/apis/admission/v1beta1 - gvr("admission.k8s.io", "v1beta1", "admissionreviews"), // not stored in etcd, call out to webhooks. + gvk("admission.k8s.io", "v1beta1", "AdmissionReview"), // not stored in etcd, call out to webhooks. // -- ) @@ -561,7 +560,7 @@ func TestEtcdStoragePath(t *testing.T) { kindSeen := sets.NewString() pathSeen := map[string][]schema.GroupVersionResource{} etcdSeen := map[schema.GroupVersionResource]empty{} - ephemeralSeen := map[schema.GroupVersionResource]empty{} + ephemeralSeen := map[schema.GroupVersionKind]empty{} cohabitatingResources := map[string]map[schema.GroupVersionKind]empty{} for gvk, apiType := range legacyscheme.Scheme.AllKnownTypes() { @@ -577,6 +576,11 @@ func TestEtcdStoragePath(t *testing.T) { kindSeen.Insert(kind) continue } + _, isEphemeral := ephemeralWhiteList[gvk] + if isEphemeral { + ephemeralSeen[gvk] = empty{} + continue + } mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { @@ -588,25 +592,12 @@ func TestEtcdStoragePath(t *testing.T) { etcdSeen[gvResource] = empty{} testData, hasTest := etcdStorageData[gvResource] - _, isEphemeral := ephemeralWhiteList[gvResource] - if !hasTest && !isEphemeral { + if !hasTest { t.Errorf("no test data for %s from %s. Please add a test for your new type to etcdStorageData.", kind, pkgPath) continue } - if hasTest && isEphemeral { - t.Errorf("duplicate test data for %s from %s. Object has both test data and is ephemeral.", kind, pkgPath) - continue - } - - if isEphemeral { // TODO it would be nice if we could remove this and infer if an object is not stored in etcd - // t.Logf("Skipping test for %s from %s", kind, pkgPath) - ephemeralSeen[gvResource] = empty{} - delete(etcdSeen, gvResource) - continue - } - if len(testData.expectedEtcdPath) == 0 { t.Errorf("empty test data for %s from %s", kind, pkgPath) continue @@ -811,10 +802,11 @@ func startRealMasterOrDie(t *testing.T, certDir string) (*allClient, clientv3.KV t.Fatal(err) } - mapper, err := util.NewFactory(clientcmd.NewDefaultClientConfig(*clientcmdapi.NewConfig(), &clientcmd.ConfigOverrides{})).RESTMapper() - if err != nil { - t.Fatal(err) - } + discoveryClient := cacheddiscovery.NewMemCacheClient(kubeClient.Discovery()) + restMapper := discovery.NewDeferredDiscoveryRESTMapper(discoveryClient) + restMapper.Reset() + // allow conversion between typed and unstructured objects + mapper := discovery.NewDeferredDiscoveryRESTMapper(discoveryClient) return client, kvClient, mapper } @@ -891,17 +883,21 @@ func gvr(g, v, r string) schema.GroupVersionResource { return schema.GroupVersionResource{Group: g, Version: v, Resource: r} } +func gvk(g, v, k string) schema.GroupVersionKind { + return schema.GroupVersionKind{Group: g, Version: v, Kind: k} +} + func gvkP(g, v, k string) *schema.GroupVersionKind { return &schema.GroupVersionKind{Group: g, Version: v, Kind: k} } -func createEphemeralWhiteList(gvrs ...schema.GroupVersionResource) map[schema.GroupVersionResource]empty { - ephemeral := map[schema.GroupVersionResource]empty{} - for _, gvResource := range gvrs { - if _, ok := ephemeral[gvResource]; ok { +func createEphemeralWhiteList(gvks ...schema.GroupVersionKind) map[schema.GroupVersionKind]empty { + ephemeral := map[schema.GroupVersionKind]empty{} + for _, gvKind := range gvks { + if _, ok := ephemeral[gvKind]; ok { panic("invalid ephemeral whitelist contains duplicate keys") } - ephemeral[gvResource] = empty{} + ephemeral[gvKind] = empty{} } return ephemeral }