2018-10-18 15:47:51 -04:00
/ *
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 etcd
2018-11-04 16:44:43 -05:00
import (
2021-03-04 13:55:31 -05:00
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
2018-11-04 16:44:43 -05:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
2020-11-13 13:45:04 -05:00
"k8s.io/kubernetes/test/utils/image"
2018-11-04 16:44:43 -05:00
)
2018-10-18 15:47:51 -04:00
// GetEtcdStorageData returns etcd data for all persisted objects.
// It is exported so that it can be reused across multiple tests.
// It returns a new map on every invocation to prevent different tests from mutating shared state.
func GetEtcdStorageData ( ) map [ schema . GroupVersionResource ] StorageData {
2019-04-19 23:16:10 -04:00
return GetEtcdStorageDataForNamespace ( "etcdstoragepathtestnamespace" )
}
// GetEtcdStorageDataForNamespace returns etcd data for all persisted objects.
// It is exported so that it can be reused across multiple tests.
// It returns a new map on every invocation to prevent different tests from mutating shared state.
// Namespaced objects keys are computed for the specified namespace.
func GetEtcdStorageDataForNamespace ( namespace string ) map [ schema . GroupVersionResource ] StorageData {
2020-11-13 13:45:04 -05:00
image := image . GetE2EImage ( image . BusyBox )
2019-02-08 11:06:07 -05:00
etcdStorageData := map [ schema . GroupVersionResource ] StorageData {
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/api/v1
gvr ( "" , "v1" , "configmaps" ) : {
Stub : ` { "data": { "foo": "bar"}, "metadata": { "name": "cm1"}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/configmaps/" + namespace + "/cm1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "services" ) : {
Stub : ` { "metadata": { "name": "service1"}, "spec": { "externalName": "service1name", "ports": [ { "port": 10000, "targetPort": 11000}], "selector": { "test": "data"}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/services/specs/" + namespace + "/service1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "podtemplates" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "pt1name"}, "template": { "metadata": { "labels": { "pt": "01"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container9"}]}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/podtemplates/" + namespace + "/pt1name" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "pods" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "pod1"}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container7", "resources": { "limits": { "cpu": "1M"}, "requests": { "cpu": "1M"}}}]}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/pods/" + namespace + "/pod1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "endpoints" ) : {
Stub : ` { "metadata": { "name": "ep1name"}, "subsets": [ { "addresses": [ { "hostname": "bar-001", "ip": "192.168.3.1"}], "ports": [ { "port": 8000}]}]} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/services/endpoints/" + namespace + "/ep1name" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "resourcequotas" ) : {
Stub : ` { "metadata": { "name": "rq1name"}, "spec": { "hard": { "cpu": "5M"}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/resourcequotas/" + namespace + "/rq1name" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "limitranges" ) : {
Stub : ` { "metadata": { "name": "lr1name"}, "spec": { "limits": [ { "type": "Pod"}]}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/limitranges/" + namespace + "/lr1name" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "namespaces" ) : {
Stub : ` { "metadata": { "name": "namespace1"}, "spec": { "finalizers": ["kubernetes"]}} ` ,
ExpectedEtcdPath : "/registry/namespaces/namespace1" ,
} ,
gvr ( "" , "v1" , "nodes" ) : {
Stub : ` { "metadata": { "name": "node1"}, "spec": { "unschedulable": true}} ` ,
ExpectedEtcdPath : "/registry/minions/node1" ,
} ,
gvr ( "" , "v1" , "persistentvolumes" ) : {
Stub : ` { "metadata": { "name": "pv1name"}, "spec": { "accessModes": ["ReadWriteOnce"], "capacity": { "storage": "3M"}, "hostPath": { "path": "/tmp/test/"}}} ` ,
ExpectedEtcdPath : "/registry/persistentvolumes/pv1name" ,
} ,
gvr ( "" , "v1" , "events" ) : {
2019-04-19 23:16:10 -04:00
Stub : ` { "involvedObject": { "namespace": " ` + namespace + ` "}, "message": "some data here", "metadata": { "name": "event1"}} ` ,
ExpectedEtcdPath : "/registry/events/" + namespace + "/event1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "persistentvolumeclaims" ) : {
Stub : ` { "metadata": { "name": "pvc1"}, "spec": { "accessModes": ["ReadWriteOnce"], "resources": { "limits": { "storage": "1M"}, "requests": { "storage": "2M"}}, "selector": { "matchLabels": { "pvc": "stuff"}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/persistentvolumeclaims/" + namespace + "/pvc1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "serviceaccounts" ) : {
Stub : ` { "metadata": { "name": "sa1name"}, "secrets": [ { "name": "secret00"}]} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/serviceaccounts/" + namespace + "/sa1name" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "secrets" ) : {
Stub : ` { "data": { "key": "ZGF0YSBmaWxl"}, "metadata": { "name": "secret1"}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/secrets/" + namespace + "/secret1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "" , "v1" , "replicationcontrollers" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "rc1"}, "spec": { "selector": { "new": "stuff"}, "template": { "metadata": { "labels": { "new": "stuff"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container8"}]}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/controllers/" + namespace + "/rc1" ,
2018-10-18 15:47:51 -04:00
} ,
// --
// k8s.io/kubernetes/pkg/apis/apps/v1
gvr ( "apps" , "v1" , "daemonsets" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "ds6"}, "spec": { "selector": { "matchLabels": { "a": "b"}}, "template": { "metadata": { "labels": { "a": "b"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container6"}]}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/daemonsets/" + namespace + "/ds6" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "apps" , "v1" , "deployments" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "deployment4"}, "spec": { "selector": { "matchLabels": { "f": "z"}}, "template": { "metadata": { "labels": { "f": "z"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container6"}]}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/deployments/" + namespace + "/deployment4" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "apps" , "v1" , "statefulsets" ) : {
Stub : ` { "metadata": { "name": "ss3"}, "spec": { "selector": { "matchLabels": { "a": "b"}}, "template": { "metadata": { "labels": { "a": "b"}}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/statefulsets/" + namespace + "/ss3" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "apps" , "v1" , "replicasets" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "rs3"}, "spec": { "selector": { "matchLabels": { "g": "h"}}, "template": { "metadata": { "labels": { "g": "h"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container4"}]}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/replicasets/" + namespace + "/rs3" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "apps" , "v1" , "controllerrevisions" ) : {
Stub : ` { "metadata": { "name":"crs3"},"data": { "name":"abc","namespace":"default","creationTimestamp":null,"Spec": { "Replicas":0,"Selector": { "matchLabels": { "foo":"bar"}},"Template": { "creationTimestamp":null,"labels": { "foo":"bar"},"Spec": { "Volumes":null,"InitContainers":null,"Containers":null,"RestartPolicy":"Always","TerminationGracePeriodSeconds":null,"ActiveDeadlineSeconds":null,"DNSPolicy":"ClusterFirst","NodeSelector":null,"ServiceAccountName":"","AutomountServiceAccountToken":null,"NodeName":"","SecurityContext":null,"ImagePullSecrets":null,"Hostname":"","Subdomain":"","Affinity":null,"SchedulerName":"","Tolerations":null,"HostAliases":null}},"VolumeClaimTemplates":null,"ServiceName":""},"Status": { "ObservedGeneration":null,"Replicas":0}},"revision":0} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/controllerrevisions/" + namespace + "/crs3" ,
2018-10-18 15:47:51 -04:00
} ,
// --
// k8s.io/kubernetes/pkg/apis/autoscaling/v1
gvr ( "autoscaling" , "v1" , "horizontalpodautoscalers" ) : {
Stub : ` { "metadata": { "name": "hpa2"}, "spec": { "maxReplicas": 3, "scaleTargetRef": { "kind": "something", "name": "cross"}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/horizontalpodautoscalers/" + namespace + "/hpa2" ,
2018-10-18 15:47:51 -04:00
} ,
// --
2021-07-06 04:02:42 -04:00
// k8s.io/kubernetes/pkg/apis/autoscaling/v2
gvr ( "autoscaling" , "v2" , "horizontalpodautoscalers" ) : {
Stub : ` { "metadata": { "name": "hpa4"}, "spec": { "maxReplicas": 3, "scaleTargetRef": { "kind": "something", "name": "cross"}}} ` ,
ExpectedEtcdPath : "/registry/horizontalpodautoscalers/" + namespace + "/hpa4" ,
ExpectedGVK : gvkP ( "autoscaling" , "v1" , "HorizontalPodAutoscaler" ) ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/apis/autoscaling/v2beta1
gvr ( "autoscaling" , "v2beta1" , "horizontalpodautoscalers" ) : {
Stub : ` { "metadata": { "name": "hpa1"}, "spec": { "maxReplicas": 3, "scaleTargetRef": { "kind": "something", "name": "cross"}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/horizontalpodautoscalers/" + namespace + "/hpa1" ,
2018-10-18 15:47:51 -04:00
ExpectedGVK : gvkP ( "autoscaling" , "v1" , "HorizontalPodAutoscaler" ) ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/autoscaling/v2beta2
gvr ( "autoscaling" , "v2beta2" , "horizontalpodautoscalers" ) : {
Stub : ` { "metadata": { "name": "hpa3"}, "spec": { "maxReplicas": 3, "scaleTargetRef": { "kind": "something", "name": "cross"}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/horizontalpodautoscalers/" + namespace + "/hpa3" ,
2018-10-18 15:47:51 -04:00
ExpectedGVK : gvkP ( "autoscaling" , "v1" , "HorizontalPodAutoscaler" ) ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/batch/v1
gvr ( "batch" , "v1" , "jobs" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "job1"}, "spec": { "manualSelector": true, "selector": { "matchLabels": { "controller-uid": "uid1"}}, "template": { "metadata": { "labels": { "controller-uid": "uid1"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container1"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/jobs/" + namespace + "/job1" ,
2018-10-18 15:47:51 -04:00
} ,
2021-02-10 06:49:43 -05:00
gvr ( "batch" , "v1" , "cronjobs" ) : {
Stub : ` { "metadata": { "name": "cjv1"}, "spec": { "jobTemplate": { "spec": { "template": { "metadata": { "labels": { "controller-uid": "uid0"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container0"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}}, "schedule": "* * * * *"}} ` ,
ExpectedEtcdPath : "/registry/cronjobs/" + namespace + "/cjv1" ,
} ,
2018-10-18 15:47:51 -04:00
// --
// k8s.io/kubernetes/pkg/apis/batch/v1beta1
gvr ( "batch" , "v1beta1" , "cronjobs" ) : {
2020-11-13 13:45:04 -05:00
Stub : ` { "metadata": { "name": "cjv1beta1"}, "spec": { "jobTemplate": { "spec": { "template": { "metadata": { "labels": { "controller-uid": "uid0"}}, "spec": { "containers": [ { "image": " ` + image + ` ", "name": "container0"}], "dnsPolicy": "ClusterFirst", "restartPolicy": "Never"}}}}, "schedule": "* * * * *"}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/cronjobs/" + namespace + "/cjv1beta1" ,
2021-05-27 06:07:16 -04:00
ExpectedGVK : gvkP ( "batch" , "v1" , "CronJob" ) ,
2018-10-18 15:47:51 -04:00
} ,
// --
2020-06-01 21:26:28 -04:00
// k8s.io/kubernetes/pkg/apis/certificates/v1
gvr ( "certificates.k8s.io" , "v1" , "certificatesigningrequests" ) : {
Stub : ` { "metadata": { "name": "csr2"}, "spec": { "signerName":"example.com/signer", "usages":["any"], "request": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQnlqQ0NBVE1DQVFBd2dZa3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saApNUll3RkFZRFZRUUhFdzFOYjNWdWRHRnBiaUJXYVdWM01STXdFUVlEVlFRS0V3cEhiMjluYkdVZ1NXNWpNUjh3CkhRWURWUVFMRXhaSmJtWnZjbTFoZEdsdmJpQlVaV05vYm05c2IyZDVNUmN3RlFZRFZRUURFdzUzZDNjdVoyOXYKWjJ4bExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBcFp0WUpDSEo0VnBWWEhmVgpJbHN0UVRsTzRxQzAzaGpYK1prUHl2ZFlkMVE0K3FiQWVUd1htQ1VLWUhUaFZSZDVhWFNxbFB6eUlCd2llTVpyCldGbFJRZGRaMUl6WEFsVlJEV3dBbzYwS2VjcWVBWG5uVUsrNWZYb1RJL1VnV3NocmU4dEoreC9UTUhhUUtSL0oKY0lXUGhxYVFoc0p1elpidkFkR0E4MEJMeGRNQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlobAo0UHZGcStlN2lwQVJnSTVaTStHWng2bXBDejQ0RFRvMEprd2ZSRGYrQnRyc2FDMHE2OGVUZjJYaFlPc3E0ZmtIClEwdUEwYVZvZzNmNWlKeENhM0hwNWd4YkpRNnpWNmtKMFRFc3VhYU9oRWtvOXNkcENvUE9uUkJtMmkvWFJEMkQKNmlOaDhmOHowU2hHc0ZxakRnRkh5RjNvK2xVeWorVUM2SDFRVzdibgotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0="}} ` ,
ExpectedEtcdPath : "/registry/certificatesigningrequests/csr2" ,
} ,
// --
2018-12-19 10:22:05 -05:00
// k8s.io/kubernetes/pkg/apis/coordination/v1
gvr ( "coordination.k8s.io" , "v1" , "leases" ) : {
Stub : ` { "metadata": { "name": "leasev1"}, "spec": { "holderIdentity": "holder", "leaseDurationSeconds": 5}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/leases/" + namespace + "/leasev1" ,
2018-12-19 10:22:05 -05:00
} ,
// --
2021-03-03 01:47:10 -05:00
// k8s.io/kubernetes/pkg/apis/discovery/v1
gvr ( "discovery.k8s.io" , "v1" , "endpointslices" ) : {
Stub : ` { "metadata": { "name": "slicev1"}, "addressType": "IPv4", "protocol": "TCP", "ports": [], "endpoints": []} ` ,
ExpectedEtcdPath : "/registry/endpointslices/" + namespace + "/slicev1" ,
ExpectedGVK : gvkP ( "discovery.k8s.io" , "v1beta1" , "EndpointSlice" ) ,
} ,
// --
2019-10-25 17:59:10 -04:00
// k8s.io/kubernetes/pkg/apis/discovery/v1beta1
gvr ( "discovery.k8s.io" , "v1beta1" , "endpointslices" ) : {
Stub : ` { "metadata": { "name": "slicev1beta1"}, "addressType": "IPv4", "protocol": "TCP", "ports": [], "endpoints": []} ` ,
ExpectedEtcdPath : "/registry/endpointslices/" + namespace + "/slicev1beta1" ,
2019-07-30 15:48:34 -04:00
} ,
// --
2020-06-01 11:03:13 -04:00
// k8s.io/kubernetes/pkg/apis/events/v1
gvr ( "events.k8s.io" , "v1" , "events" ) : {
Stub : ` { "metadata": { "name": "event3"}, "regarding": { "namespace": " ` + namespace + ` "}, "note": "some data here", "eventTime": "2017-08-09T15:04:05.000000Z", "reportingInstance": "node-xyz", "reportingController": "k8s.io/my-controller", "action": "DidNothing", "reason": "Laziness", "type": "Normal"} ` ,
ExpectedEtcdPath : "/registry/events/" + namespace + "/event3" ,
ExpectedGVK : gvkP ( "" , "v1" , "Event" ) ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/apis/events/v1beta1
gvr ( "events.k8s.io" , "v1beta1" , "events" ) : {
2019-04-19 23:16:10 -04:00
Stub : ` { "metadata": { "name": "event2"}, "regarding": { "namespace": " ` + namespace + ` "}, "note": "some data here", "eventTime": "2017-08-09T15:04:05.000000Z", "reportingInstance": "node-xyz", "reportingController": "k8s.io/my-controller", "action": "DidNothing", "reason": "Laziness"} ` ,
ExpectedEtcdPath : "/registry/events/" + namespace + "/event2" ,
2018-10-18 15:47:51 -04:00
ExpectedGVK : gvkP ( "" , "v1" , "Event" ) ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/networking/v1
2020-04-01 14:51:04 -04:00
gvr ( "networking.k8s.io" , "v1" , "ingresses" ) : {
Stub : ` { "metadata": { "name": "ingress3"}, "spec": { "defaultBackend": { "service": { "name":"service", "port": { "number": 5000}}}}} ` ,
ExpectedEtcdPath : "/registry/ingress/" + namespace + "/ingress3" ,
} ,
gvr ( "networking.k8s.io" , "v1" , "ingressclasses" ) : {
Stub : ` { "metadata": { "name": "ingressclass3"}, "spec": { "controller": "example.com/controller"}} ` ,
ExpectedEtcdPath : "/registry/ingressclasses/ingressclass3" ,
} ,
2018-10-18 15:47:51 -04:00
gvr ( "networking.k8s.io" , "v1" , "networkpolicies" ) : {
Stub : ` { "metadata": { "name": "np2"}, "spec": { "podSelector": { "matchLabels": { "e": "f"}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/networkpolicies/" + namespace + "/np2" ,
2018-10-18 15:47:51 -04:00
} ,
// --
2021-02-20 15:56:31 -05:00
// k8s.io/kubernetes/pkg/apis/policy/v1
gvr ( "policy" , "v1" , "poddisruptionbudgets" ) : {
Stub : ` { "metadata": { "name": "pdbv1"}, "spec": { "selector": { "matchLabels": { "anokkey": "anokvalue"}}}} ` ,
ExpectedEtcdPath : "/registry/poddisruptionbudgets/" + namespace + "/pdbv1" ,
ExpectedGVK : gvkP ( "policy" , "v1beta1" , "PodDisruptionBudget" ) ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/apis/policy/v1beta1
gvr ( "policy" , "v1beta1" , "poddisruptionbudgets" ) : {
Stub : ` { "metadata": { "name": "pdb1"}, "spec": { "selector": { "matchLabels": { "anokkey": "anokvalue"}}}} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/poddisruptionbudgets/" + namespace + "/pdb1" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "policy" , "v1beta1" , "podsecuritypolicies" ) : {
Stub : ` { "metadata": { "name": "psp2"}, "spec": { "fsGroup": { "rule": "RunAsAny"}, "privileged": true, "runAsUser": { "rule": "RunAsAny"}, "seLinux": { "rule": "MustRunAs"}, "supplementalGroups": { "rule": "RunAsAny"}}} ` ,
ExpectedEtcdPath : "/registry/podsecuritypolicy/psp2" ,
} ,
// --
2021-03-03 15:01:05 -05:00
// k8s.io/kubernetes/pkg/apis/storage/v1alpha1
gvr ( "storage.k8s.io" , "v1alpha1" , "csistoragecapacities" ) : {
Stub : ` { "metadata": { "name": "csc-12345-1"}, "storageClassName": "sc1"} ` ,
ExpectedEtcdPath : "/registry/csistoragecapacities/" + namespace + "/csc-12345-1" ,
ExpectedGVK : gvkP ( "storage.k8s.io" , "v1beta1" , "CSIStorageCapacity" ) ,
} ,
// --
2020-01-19 17:16:46 -05:00
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1alpha1
gvr ( "flowcontrol.apiserver.k8s.io" , "v1alpha1" , "flowschemas" ) : {
Stub : ` { "metadata": { "name": "va1"}, "spec": { "priorityLevelConfiguration": { "name": "name1"}}} ` ,
ExpectedEtcdPath : "/registry/flowschemas/va1" ,
2020-11-04 03:33:14 -05:00
ExpectedGVK : gvkP ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "FlowSchema" ) ,
2020-01-19 17:16:46 -05:00
} ,
// --
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1alpha1
gvr ( "flowcontrol.apiserver.k8s.io" , "v1alpha1" , "prioritylevelconfigurations" ) : {
Stub : ` { "metadata": { "name": "conf1"}, "spec": { "type": "Limited", "limited": { "assuredConcurrencyShares":3, "limitResponse": { "type": "Reject"}}}} ` ,
ExpectedEtcdPath : "/registry/prioritylevelconfigurations/conf1" ,
2020-11-04 03:33:14 -05:00
ExpectedGVK : gvkP ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "PriorityLevelConfiguration" ) ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta1
gvr ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "flowschemas" ) : {
Stub : ` { "metadata": { "name": "va2"}, "spec": { "priorityLevelConfiguration": { "name": "name1"}}} ` ,
ExpectedEtcdPath : "/registry/flowschemas/va2" ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta1
gvr ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "prioritylevelconfigurations" ) : {
Stub : ` { "metadata": { "name": "conf2"}, "spec": { "type": "Limited", "limited": { "assuredConcurrencyShares":3, "limitResponse": { "type": "Reject"}}}} ` ,
ExpectedEtcdPath : "/registry/prioritylevelconfigurations/conf2" ,
2020-01-19 17:16:46 -05:00
} ,
// --
2021-08-16 16:57:07 -04:00
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2
gvr ( "flowcontrol.apiserver.k8s.io" , "v1beta2" , "flowschemas" ) : {
Stub : ` { "metadata": { "name": "fs-1"}, "spec": { "priorityLevelConfiguration": { "name": "name1"}}} ` ,
ExpectedEtcdPath : "/registry/flowschemas/fs-1" ,
ExpectedGVK : gvkP ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "FlowSchema" ) ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2
gvr ( "flowcontrol.apiserver.k8s.io" , "v1beta2" , "prioritylevelconfigurations" ) : {
Stub : ` { "metadata": { "name": "conf3"}, "spec": { "type": "Limited", "limited": { "assuredConcurrencyShares":3, "limitResponse": { "type": "Reject"}}}} ` ,
ExpectedEtcdPath : "/registry/prioritylevelconfigurations/conf3" ,
ExpectedGVK : gvkP ( "flowcontrol.apiserver.k8s.io" , "v1beta1" , "PriorityLevelConfiguration" ) ,
} ,
// --
2018-11-14 08:01:16 -05:00
// k8s.io/kubernetes/pkg/apis/storage/v1
gvr ( "storage.k8s.io" , "v1" , "volumeattachments" ) : {
Stub : ` { "metadata": { "name": "va3"}, "spec": { "attacher": "gce", "nodeName": "localhost", "source": { "persistentVolumeName": "pv3"}}} ` ,
ExpectedEtcdPath : "/registry/volumeattachments/va3" ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/apis/storage/v1beta1
2021-03-03 15:01:05 -05:00
// k8s.io/kubernetes/pkg/apis/storage/v1beta1
gvr ( "storage.k8s.io" , "v1beta1" , "csistoragecapacities" ) : {
Stub : ` { "metadata": { "name": "csc-12345-2"}, "storageClassName": "sc1"} ` ,
ExpectedEtcdPath : "/registry/csistoragecapacities/" + namespace + "/csc-12345-2" ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kubernetes/pkg/apis/storage/v1
gvr ( "storage.k8s.io" , "v1" , "storageclasses" ) : {
Stub : ` { "metadata": { "name": "sc2"}, "provisioner": "aws"} ` ,
ExpectedEtcdPath : "/registry/storageclasses/sc2" ,
} ,
// --
// k8s.io/kubernetes/pkg/apis/rbac/v1
gvr ( "rbac.authorization.k8s.io" , "v1" , "roles" ) : {
Stub : ` { "metadata": { "name": "role3"}, "rules": [ { "apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/roles/" + namespace + "/role3" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "rbac.authorization.k8s.io" , "v1" , "clusterroles" ) : {
Stub : ` { "metadata": { "name": "crole3"}, "rules": [ { "nonResourceURLs": ["/version"], "verbs": ["get"]}]} ` ,
ExpectedEtcdPath : "/registry/clusterroles/crole3" ,
} ,
gvr ( "rbac.authorization.k8s.io" , "v1" , "rolebindings" ) : {
Stub : ` { "metadata": { "name": "roleb3"}, "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [ { "apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]} ` ,
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/rolebindings/" + namespace + "/roleb3" ,
2018-10-18 15:47:51 -04:00
} ,
gvr ( "rbac.authorization.k8s.io" , "v1" , "clusterrolebindings" ) : {
Stub : ` { "metadata": { "name": "croleb3"}, "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [ { "apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]} ` ,
ExpectedEtcdPath : "/registry/clusterrolebindings/croleb3" ,
} ,
// --
2019-06-28 18:24:56 -04:00
// k8s.io/kubernetes/pkg/apis/admissionregistration/v1
gvr ( "admissionregistration.k8s.io" , "v1" , "validatingwebhookconfigurations" ) : {
2019-08-06 18:18:04 -04:00
Stub : ` { "metadata": { "name":"hook2","creationTimestamp":null},"webhooks":[ { "name":"externaladmissionhook.k8s.io","clientConfig": { "service": { "namespace":"ns","name":"n"},"caBundle":null},"rules":[ { "operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore","sideEffects":"None","admissionReviewVersions":["v1beta1"]}]} ` ,
2019-06-28 18:24:56 -04:00
ExpectedEtcdPath : "/registry/validatingwebhookconfigurations/hook2" ,
} ,
gvr ( "admissionregistration.k8s.io" , "v1" , "mutatingwebhookconfigurations" ) : {
2019-08-06 18:18:04 -04:00
Stub : ` { "metadata": { "name":"hook2","creationTimestamp":null},"webhooks":[ { "name":"externaladmissionhook.k8s.io","clientConfig": { "service": { "namespace":"ns","name":"n"},"caBundle":null},"rules":[ { "operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore","sideEffects":"None","admissionReviewVersions":["v1beta1"]}]} ` ,
2019-06-28 18:24:56 -04:00
ExpectedEtcdPath : "/registry/mutatingwebhookconfigurations/hook2" ,
} ,
// --
2019-02-20 14:42:42 -05:00
// k8s.io/kubernetes/pkg/apis/scheduling/v1
gvr ( "scheduling.k8s.io" , "v1" , "priorityclasses" ) : {
Stub : ` { "metadata": { "name":"pc3"},"Value":1000} ` ,
ExpectedEtcdPath : "/registry/priorityclasses/pc3" ,
} ,
// --
2018-10-18 15:47:51 -04:00
// k8s.io/kube-aggregator/pkg/apis/apiregistration/v1
// depends on aggregator using the same ungrouped RESTOptionsGetter as the kube apiserver, not SimpleRestOptionsFactory in aggregator.go
gvr ( "apiregistration.k8s.io" , "v1" , "apiservices" ) : {
Stub : ` { "metadata": { "name": "as2.foo.com"}, "spec": { "group": "foo.com", "version": "as2", "groupPriorityMinimum":100, "versionPriority":10}} ` ,
ExpectedEtcdPath : "/registry/apiregistration.k8s.io/apiservices/as2.foo.com" ,
} ,
// --
2019-06-29 14:42:21 -04:00
// k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
gvr ( "apiextensions.k8s.io" , "v1" , "customresourcedefinitions" ) : {
2019-08-08 21:46:12 -04:00
Stub : ` { "metadata": { "name": "openshiftwebconsoleconfigs.webconsole2.operator.openshift.io"},"spec": { ` +
` "scope": "Cluster","group": "webconsole2.operator.openshift.io", ` +
` "versions": [ { "name":"v1alpha1","storage":true,"served":true,"schema": { "openAPIV3Schema": { "type":"object"}}}], ` +
` "names": { "kind": "OpenShiftWebConsoleConfig","plural": "openshiftwebconsoleconfigs","singular": "openshiftwebconsoleconfig"}}} ` ,
2019-06-29 14:42:21 -04:00
ExpectedEtcdPath : "/registry/apiextensions.k8s.io/customresourcedefinitions/openshiftwebconsoleconfigs.webconsole2.operator.openshift.io" ,
ExpectedGVK : gvkP ( "apiextensions.k8s.io" , "v1beta1" , "CustomResourceDefinition" ) ,
} ,
2018-11-04 16:44:43 -05:00
gvr ( "cr.bar.com" , "v1" , "foos" ) : {
Stub : ` { "kind": "Foo", "apiVersion": "cr.bar.com/v1", "metadata": { "name": "cr1foo"}, "color": "blue"} ` , // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper
2019-04-19 23:16:10 -04:00
ExpectedEtcdPath : "/registry/cr.bar.com/foos/" + namespace + "/cr1foo" ,
2018-11-04 16:44:43 -05:00
} ,
gvr ( "custom.fancy.com" , "v2" , "pants" ) : {
Stub : ` { "kind": "Pant", "apiVersion": "custom.fancy.com/v2", "metadata": { "name": "cr2pant"}, "isFancy": true} ` , // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper
ExpectedEtcdPath : "/registry/custom.fancy.com/pants/cr2pant" ,
} ,
gvr ( "awesome.bears.com" , "v1" , "pandas" ) : {
2019-04-19 23:16:10 -04:00
Stub : ` { "kind": "Panda", "apiVersion": "awesome.bears.com/v1", "metadata": { "name": "cr3panda"}, "spec": { "replicas": 100}} ` , // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper
2018-11-04 16:44:43 -05:00
ExpectedEtcdPath : "/registry/awesome.bears.com/pandas/cr3panda" ,
} ,
gvr ( "awesome.bears.com" , "v3" , "pandas" ) : {
2019-04-19 23:16:10 -04:00
Stub : ` { "kind": "Panda", "apiVersion": "awesome.bears.com/v3", "metadata": { "name": "cr4panda"}, "spec": { "replicas": 300}} ` , // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper
2018-11-04 16:44:43 -05:00
ExpectedEtcdPath : "/registry/awesome.bears.com/pandas/cr4panda" ,
ExpectedGVK : gvkP ( "awesome.bears.com" , "v1" , "Panda" ) ,
} ,
2019-05-02 06:04:39 -04:00
gvr ( "random.numbers.com" , "v1" , "integers" ) : {
Stub : ` { "kind": "Integer", "apiVersion": "random.numbers.com/v1", "metadata": { "name": "fortytwo"}, "value": 42, "garbage": "oiujnasdf"} ` , // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper
ExpectedEtcdPath : "/registry/random.numbers.com/integers/fortytwo" ,
} ,
2018-10-18 15:47:51 -04:00
// --
2018-10-18 22:34:17 -04:00
2019-02-27 14:19:02 -05:00
// k8s.io/kubernetes/pkg/apis/node/v1alpha1
gvr ( "node.k8s.io" , "v1alpha1" , "runtimeclasses" ) : {
Stub : ` { "metadata": { "name": "rc1"}, "spec": { "runtimeHandler": "h1"}} ` ,
ExpectedEtcdPath : "/registry/runtimeclasses/rc1" ,
2021-02-15 15:29:47 -05:00
ExpectedGVK : gvkP ( "node.k8s.io" , "v1" , "RuntimeClass" ) ,
2019-02-27 14:19:02 -05:00
} ,
// --
// k8s.io/kubernetes/pkg/apis/node/v1beta1
gvr ( "node.k8s.io" , "v1beta1" , "runtimeclasses" ) : {
Stub : ` { "metadata": { "name": "rc2"}, "handler": "h2"} ` ,
ExpectedEtcdPath : "/registry/runtimeclasses/rc2" ,
2021-02-15 15:29:47 -05:00
ExpectedGVK : gvkP ( "node.k8s.io" , "v1" , "RuntimeClass" ) ,
2019-02-27 14:19:02 -05:00
} ,
// --
2020-02-24 18:28:51 -05:00
2020-11-11 14:22:32 -05:00
// k8s.io/kubernetes/pkg/apis/node/v1
gvr ( "node.k8s.io" , "v1" , "runtimeclasses" ) : {
Stub : ` { "metadata": { "name": "rc3"}, "handler": "h3"} ` ,
ExpectedEtcdPath : "/registry/runtimeclasses/rc3" ,
} ,
// --
2020-02-24 18:28:51 -05:00
// k8s.io/apiserver/pkg/apis/apiserverinternal/v1alpha1
gvr ( "internal.apiserver.k8s.io" , "v1alpha1" , "storageversions" ) : {
Stub : ` { "metadata": { "name":"sv1.test"},"spec": { }} ` ,
ExpectedEtcdPath : "/registry/storageversions/sv1.test" ,
} ,
// --
2018-10-18 15:47:51 -04:00
}
2019-02-08 11:06:07 -05:00
2020-11-13 07:45:33 -05:00
// add csinodes
// k8s.io/kubernetes/pkg/apis/storage/v1
etcdStorageData [ gvr ( "storage.k8s.io" , "v1" , "csinodes" ) ] = StorageData {
Stub : ` { "metadata": { "name": "csini2"}, "spec": { "drivers": [ { "name": "test-driver", "nodeID": "localhost", "topologyKeys": ["company.com/zone1", "company.com/zone2"]}]}} ` ,
ExpectedEtcdPath : "/registry/csinodes/csini2" ,
2019-02-08 11:06:07 -05:00
}
2020-02-28 17:13:11 -05:00
// add csidrivers
// k8s.io/kubernetes/pkg/apis/storage/v1
etcdStorageData [ gvr ( "storage.k8s.io" , "v1" , "csidrivers" ) ] = StorageData {
Stub : ` { "metadata": { "name": "csid2"}, "spec": { "attachRequired": true, "podInfoOnMount": true}} ` ,
ExpectedEtcdPath : "/registry/csidrivers/csid2" ,
2019-02-08 11:06:07 -05:00
}
return etcdStorageData
2018-10-18 15:47:51 -04:00
}
// StorageData contains information required to create an object and verify its storage in etcd
// It must be paired with a specific resource
type StorageData struct {
Stub string // Valid JSON stub to use during create
Prerequisites [ ] Prerequisite // Optional, ordered list of JSON objects to create before stub
ExpectedEtcdPath string // Expected location of object in etcd, do not use any variables, constants, etc to derive this value - always supply the full raw string
ExpectedGVK * schema . GroupVersionKind // The GVK that we expect this object to be stored as - leave this nil to use the default
}
// Prerequisite contains information required to create a resource (but not verify it)
type Prerequisite struct {
GvrData schema . GroupVersionResource
Stub string
}
2018-11-04 16:44:43 -05:00
// GetCustomResourceDefinitionData returns the resource definitions that back the custom resources
// included in GetEtcdStorageData. They should be created using CreateTestCRDs before running any tests.
2021-03-04 13:55:31 -05:00
// We can switch this to v1 CRDs based on transitive call site analysis.
// Call sites:
// 1. TestDedupOwnerReferences - beta doesn't matter
// 2. TestWebhookAdmissionWithWatchCache/TestWebhookAdmissionWithoutWatchCache - beta doesn't matter
// 3. TestApplyStatus - the version fields don't matter. Pruning isn't checked, just ownership.
// 4. TestDryRun - versions and pruning don't matter
// 5. TestStorageVersionBootstrap - versions and pruning don't matter.
// 6. TestEtcdStoragePath - beta doesn't matter
// 7. TestCrossGroupStorage - beta doesn't matter
// 8. TestOverlappingCustomResourceCustomResourceDefinition - beta doesn't matter
// 9. TestOverlappingCustomResourceAPIService - beta doesn't matter
func GetCustomResourceDefinitionData ( ) [ ] * apiextensionsv1 . CustomResourceDefinition {
return [ ] * apiextensionsv1 . CustomResourceDefinition {
// namespaced
2018-11-04 16:44:43 -05:00
{
ObjectMeta : metav1 . ObjectMeta {
Name : "foos.cr.bar.com" ,
} ,
2021-03-04 13:55:31 -05:00
Spec : apiextensionsv1 . CustomResourceDefinitionSpec {
Group : "cr.bar.com" ,
Scope : apiextensionsv1 . NamespaceScoped ,
Names : apiextensionsv1 . CustomResourceDefinitionNames {
2018-11-04 16:44:43 -05:00
Plural : "foos" ,
Kind : "Foo" ,
} ,
2021-03-04 13:55:31 -05:00
Versions : [ ] apiextensionsv1 . CustomResourceDefinitionVersion {
{
Name : "v1" ,
Served : true ,
Storage : true ,
Schema : fixtures . AllowAllSchema ( ) ,
} ,
} ,
2018-11-04 16:44:43 -05:00
} ,
} ,
2021-03-04 13:55:31 -05:00
// cluster scoped
2018-11-04 16:44:43 -05:00
{
ObjectMeta : metav1 . ObjectMeta {
Name : "pants.custom.fancy.com" ,
} ,
2021-03-04 13:55:31 -05:00
Spec : apiextensionsv1 . CustomResourceDefinitionSpec {
Group : "custom.fancy.com" ,
Scope : apiextensionsv1 . ClusterScoped ,
Names : apiextensionsv1 . CustomResourceDefinitionNames {
2018-11-04 16:44:43 -05:00
Plural : "pants" ,
Kind : "Pant" ,
} ,
2021-03-04 13:55:31 -05:00
Versions : [ ] apiextensionsv1 . CustomResourceDefinitionVersion {
{
Name : "v2" ,
Served : true ,
Storage : true ,
Schema : fixtures . AllowAllSchema ( ) ,
} ,
} ,
2018-11-04 16:44:43 -05:00
} ,
} ,
2019-05-02 06:04:39 -04:00
// cluster scoped with legacy version field and pruning.
{
ObjectMeta : metav1 . ObjectMeta {
Name : "integers.random.numbers.com" ,
} ,
2021-03-04 13:55:31 -05:00
Spec : apiextensionsv1 . CustomResourceDefinitionSpec {
Group : "random.numbers.com" ,
Scope : apiextensionsv1 . ClusterScoped ,
Names : apiextensionsv1 . CustomResourceDefinitionNames {
2019-05-02 06:04:39 -04:00
Plural : "integers" ,
Kind : "Integer" ,
} ,
2021-03-04 13:55:31 -05:00
Versions : [ ] apiextensionsv1 . CustomResourceDefinitionVersion {
{
Name : "v1" ,
Served : true ,
Storage : true ,
Schema : & apiextensionsv1 . CustomResourceValidation {
OpenAPIV3Schema : & apiextensionsv1 . JSONSchemaProps {
Type : "object" ,
Properties : map [ string ] apiextensionsv1 . JSONSchemaProps {
"value" : {
Type : "number" ,
} ,
} ,
} } ,
2019-05-02 06:04:39 -04:00
} ,
} ,
} ,
} ,
2018-11-04 16:44:43 -05:00
// cluster scoped with versions field
{
ObjectMeta : metav1 . ObjectMeta {
Name : "pandas.awesome.bears.com" ,
} ,
2021-03-04 13:55:31 -05:00
Spec : apiextensionsv1 . CustomResourceDefinitionSpec {
2018-11-04 16:44:43 -05:00
Group : "awesome.bears.com" ,
2021-03-04 13:55:31 -05:00
Versions : [ ] apiextensionsv1 . CustomResourceDefinitionVersion {
2018-11-04 16:44:43 -05:00
{
Name : "v1" ,
Served : true ,
Storage : true ,
2021-03-04 13:55:31 -05:00
Schema : fixtures . AllowAllSchema ( ) ,
Subresources : & apiextensionsv1 . CustomResourceSubresources {
Status : & apiextensionsv1 . CustomResourceSubresourceStatus { } ,
Scale : & apiextensionsv1 . CustomResourceSubresourceScale {
SpecReplicasPath : ".spec.replicas" ,
StatusReplicasPath : ".status.replicas" ,
LabelSelectorPath : func ( ) * string { path := ".status.selector" ; return & path } ( ) ,
} ,
} ,
2018-11-04 16:44:43 -05:00
} ,
{
Name : "v2" ,
Served : false ,
Storage : false ,
2021-03-04 13:55:31 -05:00
Schema : fixtures . AllowAllSchema ( ) ,
Subresources : & apiextensionsv1 . CustomResourceSubresources {
Status : & apiextensionsv1 . CustomResourceSubresourceStatus { } ,
Scale : & apiextensionsv1 . CustomResourceSubresourceScale {
SpecReplicasPath : ".spec.replicas" ,
StatusReplicasPath : ".status.replicas" ,
LabelSelectorPath : func ( ) * string { path := ".status.selector" ; return & path } ( ) ,
} ,
} ,
2018-11-04 16:44:43 -05:00
} ,
{
Name : "v3" ,
Served : true ,
Storage : false ,
2021-03-04 13:55:31 -05:00
Schema : fixtures . AllowAllSchema ( ) ,
Subresources : & apiextensionsv1 . CustomResourceSubresources {
Status : & apiextensionsv1 . CustomResourceSubresourceStatus { } ,
Scale : & apiextensionsv1 . CustomResourceSubresourceScale {
SpecReplicasPath : ".spec.replicas" ,
StatusReplicasPath : ".status.replicas" ,
LabelSelectorPath : func ( ) * string { path := ".status.selector" ; return & path } ( ) ,
} ,
} ,
2018-11-04 16:44:43 -05:00
} ,
} ,
2021-03-04 13:55:31 -05:00
Scope : apiextensionsv1 . ClusterScoped ,
Names : apiextensionsv1 . CustomResourceDefinitionNames {
2018-11-04 16:44:43 -05:00
Plural : "pandas" ,
Kind : "Panda" ,
} ,
} ,
} ,
}
}
2018-10-18 15:47:51 -04:00
func gvr ( g , v , r string ) schema . GroupVersionResource {
return schema . GroupVersionResource { Group : g , Version : v , Resource : r }
}
func gvkP ( g , v , k string ) * schema . GroupVersionKind {
return & schema . GroupVersionKind { Group : g , Version : v , Kind : k }
}
2021-03-05 17:52:22 -05:00
func gvk ( g , v , k string ) schema . GroupVersionKind {
return schema . GroupVersionKind { Group : g , Version : v , Kind : k }
}