From 085148bfc695d83dcb5220854ab845f5e24ca88a Mon Sep 17 00:00:00 2001 From: Mohamed Awnallah Date: Thu, 10 Oct 2024 07:42:45 +0300 Subject: [PATCH] operator/pkg/util/apiclient: unit test wait In this commit, we unit test the API client on waiting for API server, API service, all pods constraint, some pods constraint, and the exponential backoff utility. Signed-off-by: Mohamed Awnallah --- operator/pkg/util/apiclient/wait.go | 29 +- operator/pkg/util/apiclient/wait_test.go | 446 ++++++++++++++++++ .../clientset/fake/clientset_generated.go | 92 ++++ .../clientset_generated/clientset/fake/doc.go | 20 + .../clientset/fake/register.go | 58 +++ .../typed/apiregistration/v1/fake/doc.go | 20 + .../v1/fake/fake_apiregistration_client.go | 40 ++ .../v1/fake/fake_apiservice.go | 132 ++++++ .../typed/apiregistration/v1beta1/fake/doc.go | 20 + .../fake/fake_apiregistration_client.go | 40 ++ .../v1beta1/fake/fake_apiservice.go | 132 ++++++ vendor/modules.txt | 3 + 12 files changed, 1026 insertions(+), 6 deletions(-) create mode 100644 operator/pkg/util/apiclient/wait_test.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/clientset_generated.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/doc.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/register.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/doc.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiregistration_client.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiservice.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/doc.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiregistration_client.go create mode 100644 vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiservice.go diff --git a/operator/pkg/util/apiclient/wait.go b/operator/pkg/util/apiclient/wait.go index 92eddeb447f7..1c55cb79851d 100644 --- a/operator/pkg/util/apiclient/wait.go +++ b/operator/pkg/util/apiclient/wait.go @@ -36,6 +36,18 @@ const ( APICallRetryInterval = 500 * time.Millisecond ) +var ( + // initialBackoffDuration defines the initial duration for the backoff mechanism, + // set to 5 seconds. This value is used to determine the wait time before retrying + // a failed command. + initialBackoffDuration = 5 * time.Second + + // backoffTimeoutFactor is the factor by which the backoff duration is multiplied + // after each failure. In this case, it is set to 2, meaning the wait time will + // double with each consecutive failure. + backoffTimeoutFactor float64 = 2 +) + // Waiter is an interface for waiting for criteria in Karmada to happen type Waiter interface { // WaitForAPI waits for the API Server's /healthz endpoint to become "ok" @@ -79,9 +91,13 @@ func (w *KarmadaWaiter) WaitForAPI() error { }) } +var aggregateClientFromConfigBuilder = func(karmadaConfig *rest.Config) (aggregator.Interface, error) { + return aggregator.NewForConfig(karmadaConfig) +} + // WaitForAPIService waits for the APIService condition to become "true" func (w *KarmadaWaiter) WaitForAPIService(name string) error { - aggregateClient, err := aggregator.NewForConfig(w.karmadaConfig) + aggregateClient, err := aggregateClientFromConfigBuilder(w.karmadaConfig) if err != nil { return err } @@ -162,20 +178,21 @@ func (w *KarmadaWaiter) SetTimeout(timeout time.Duration) { w.timeout = timeout } -// TryRunCommand runs a function a maximum of failureThreshold times, and retries on error. If failureThreshold is hit; the last error is returned +// TryRunCommand runs a function a maximum of failureThreshold times, and +// retries on error. If failureThreshold is hit; the last error is returned. func TryRunCommand(f func() error, failureThreshold int) error { backoff := wait.Backoff{ - Duration: 5 * time.Second, - Factor: 2, // double the timeout for every failure + Duration: initialBackoffDuration, + Factor: backoffTimeoutFactor, Steps: failureThreshold, } return wait.ExponentialBackoff(backoff, func() (bool, error) { err := f() if err != nil { - // Retry until the timeout + // Retry until the timeout. return false, nil } - // The last f() call was a success, return cleanly + // The last f() call was a success, return cleanly. return true, nil }) } diff --git a/operator/pkg/util/apiclient/wait_test.go b/operator/pkg/util/apiclient/wait_test.go new file mode 100644 index 000000000000..c1d7a32cf565 --- /dev/null +++ b/operator/pkg/util/apiclient/wait_test.go @@ -0,0 +1,446 @@ +/* +Copyright 2024 The Karmada 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 apiclient + +import ( + "context" + "errors" + "fmt" + "net/http" + "testing" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + clientset "k8s.io/client-go/kubernetes" + fakeclientset "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/rest" + fakerest "k8s.io/client-go/rest/fake" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" + fakeAggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake" + + "github.com/karmada-io/karmada/operator/pkg/constants" +) + +func TestWaitForAPI(t *testing.T) { + tests := []struct { + name string + karmadaWriter *KarmadaWaiter + wantErr bool + }{ + { + name: "WaitForAPI_WaitingForAPIServerHealthyStatus_Timeout", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: &MockK8SRESTClient{ + RESTClientConnector: &fakerest.RESTClient{ + NegotiatedSerializer: runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{}), + Client: fakerest.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + return nil, fmt.Errorf("unexpected error, endpoint %s does not exist", req.URL.Path) + }), + }, + }, + timeout: time.Second, + }, + wantErr: true, + }, + { + name: "WaitForAPI_WaitingForAPIServerHealthyStatus_APIServerIsHealthy", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: &MockK8SRESTClient{ + RESTClientConnector: &fakerest.RESTClient{ + NegotiatedSerializer: runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{}), + Client: fakerest.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + if req.URL.Path == "/healthz" { + // Return a fake 200 OK response. + return &http.Response{ + StatusCode: http.StatusOK, + Body: http.NoBody, + }, nil + } + return nil, fmt.Errorf("unexpected error, endpoint %s does not exist", req.URL.Path) + }), + }, + }, + timeout: time.Millisecond, + }, + wantErr: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.karmadaWriter.WaitForAPI() + if err == nil && test.wantErr { + t.Errorf("expected an error, but got none") + } + if err != nil && !test.wantErr { + t.Errorf("unexpected error, got: %v", err) + } + }) + } +} + +func TestWaitForAPIService(t *testing.T) { + name := "karmada-demo-apiservice" + tests := []struct { + name string + karmadaWriter *KarmadaWaiter + apiService *apiregistrationv1.APIService + client aggregator.Interface + prep func(aggregator.Interface, *apiregistrationv1.APIService) error + wantErr bool + }{ + { + name: "WaitForAPIService_WaitingForKarmadaAPIServiceAvailableStatus_Timeout", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + timeout: time.Second, + }, + apiService: &apiregistrationv1.APIService{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: apiregistrationv1.APIServiceSpec{ + Service: &apiregistrationv1.ServiceReference{ + Name: "karmada-demo-service", + Namespace: "test", + }, + Version: "v1beta1", + }, + }, + client: fakeAggregator.NewSimpleClientset(), + prep: func(client aggregator.Interface, _ *apiregistrationv1.APIService) error { + aggregateClientFromConfigBuilder = func(*rest.Config) (aggregator.Interface, error) { + return client, nil + } + return nil + }, + wantErr: true, + }, + { + name: "WaitForAPIService_WaitingForKarmadaAPIServiceAvailableStatus_KarmadaAPIServiceIsAvailable", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + timeout: time.Millisecond, + }, + apiService: &apiregistrationv1.APIService{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: apiregistrationv1.APIServiceSpec{ + Service: &apiregistrationv1.ServiceReference{ + Name: "karmada-demo-service", + Namespace: "test", + }, + Version: "v1beta1", + }, + }, + client: fakeAggregator.NewSimpleClientset(), + prep: func(client aggregator.Interface, apiService *apiregistrationv1.APIService) error { + apiServiceCreated, err := client.ApiregistrationV1().APIServices().Create(context.TODO(), apiService, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("faield to create api service %s, got err: %v", apiService.Name, err) + } + apiServiceCreated.Status = apiregistrationv1.APIServiceStatus{ + Conditions: []apiregistrationv1.APIServiceCondition{ + { + Type: apiregistrationv1.Available, + Status: apiregistrationv1.ConditionTrue, + }, + }, + } + if _, err = client.ApiregistrationV1().APIServices().Update(context.TODO(), apiServiceCreated, metav1.UpdateOptions{}); err != nil { + return fmt.Errorf("failed to update api service with available status, got err: %v", err) + } + aggregateClientFromConfigBuilder = func(*rest.Config) (aggregator.Interface, error) { + return client, nil + } + return nil + }, + wantErr: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.prep(test.client, test.apiService); err != nil { + t.Errorf("failed to prep waiting for Karmada API Service, got err: %v", err) + } + err := test.karmadaWriter.WaitForAPIService(name) + if err == nil && test.wantErr { + t.Errorf("expected an error, but got none") + } + if err != nil && !test.wantErr { + t.Errorf("unexpected error, got: %v", err) + } + }) + } +} + +func TestWaitForPods(t *testing.T) { + name, namespace := "karmada-demo-apiserver", "test" + karmadaAPIServerLabels := labels.Set{"karmada-app": constants.KarmadaAPIServer} + var replicas int32 = 2 + tests := []struct { + name string + karmadaWriter *KarmadaWaiter + prep func(client clientset.Interface) error + wantErr bool + }{ + { + name: "WaitForPods_WaitingForAllKarmadaAPIServerPods_Timeout", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: fakeclientset.NewSimpleClientset(), + timeout: time.Second, + }, + prep: func(client clientset.Interface) error { + _, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false) + if err != nil { + return fmt.Errorf("failed to create pods, got err: %v", err) + } + return nil + }, + wantErr: true, + }, + { + name: "WaitForPods_WaitingForAllKarmadaAPIServerPods_AllAreUpAndRunning", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: fakeclientset.NewSimpleClientset(), + timeout: time.Second * 2, + }, + prep: func(client clientset.Interface) error { + pods, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false) + if err != nil { + return fmt.Errorf("failed to create pods, got err: %v", err) + } + time.AfterFunc(time.Second, func() { + for _, pod := range pods { + if err := UpdatePodStatus(client, pod); err != nil { + fmt.Printf("failed to update pod status, got err: %v", err) + return + } + } + }) + return nil + }, + wantErr: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.prep(test.karmadaWriter.client); err != nil { + t.Errorf("failed to prep before waiting for all Karmada APIServer pods , got err: %v", err) + } + err := test.karmadaWriter.WaitForPods(karmadaAPIServerLabels.String(), namespace) + if err == nil && test.wantErr { + t.Errorf("expected an error, but got none") + } + if err != nil && !test.wantErr { + t.Errorf("unexpected error, got: %v", err) + } + }) + } +} + +func TestWaitForSomePods(t *testing.T) { + name, namespace := "karmada-demo-apiserver", "test" + karmadaAPIServerLabels := labels.Set{"karmada-app": constants.KarmadaAPIServer} + var replicas int32 = 2 + tests := []struct { + name string + karmadaWriter *KarmadaWaiter + prep func(client clientset.Interface) error + wantErr bool + }{ + { + name: "WaitForSomePods_WaitingForSomeKarmadaAPIServerPods_Timeout", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: fakeclientset.NewSimpleClientset(), + timeout: time.Second, + }, + prep: func(client clientset.Interface) error { + _, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false) + if err != nil { + return fmt.Errorf("failed to create pods, got err: %v", err) + } + return nil + }, + wantErr: true, + }, + { + name: "WaitForSomePods_WaitingForSomeKarmadaAPIServerPods_SomeAreUpAndRunning", + karmadaWriter: &KarmadaWaiter{ + karmadaConfig: &rest.Config{}, + client: fakeclientset.NewSimpleClientset(), + timeout: time.Millisecond, + }, + prep: func(client clientset.Interface) error { + pods, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false) + if err != nil { + return fmt.Errorf("failed to create pods, got err: %v", err) + } + for _, pod := range pods[:1] { + if err := UpdatePodStatus(client, pod); err != nil { + return fmt.Errorf("failed to update pod status, got err: %v", err) + } + } + return nil + }, + wantErr: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.prep(test.karmadaWriter.client); err != nil { + t.Errorf("failed to prep before waiting for some Karmada APIServer pods , got err: %v", err) + } + err := test.karmadaWriter.WaitForSomePods(karmadaAPIServerLabels.String(), namespace, 1) + if err == nil && test.wantErr { + t.Errorf("expected an error, but got none") + } + if err != nil && !test.wantErr { + t.Errorf("unexpected error, got: %v", err) + } + }) + } +} + +func TestTryRunCommand(t *testing.T) { + tests := []struct { + name string + failureThreshold int + targetFunc func() error + prep func() error + wantErr bool + }{ + { + name: "TryRunCommand_HitTheFailureThreshold_CommandTimedOut", + failureThreshold: 2, + targetFunc: func() error { + return errors.New("unexpected error") + }, + prep: func() error { + initialBackoffDuration = time.Millisecond + return nil + }, + wantErr: true, + }, + { + name: "TryRunCommand_BelowFailureThreshold_CommandRunSuccessfully", + failureThreshold: 2, + targetFunc: func() error { return nil }, + prep: func() error { + initialBackoffDuration = time.Millisecond + return nil + }, + wantErr: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.prep(); err != nil { + t.Errorf("failed to prep before trying to running command, got err: %v", err) + } + err := TryRunCommand(test.targetFunc, test.failureThreshold) + if err == nil && test.wantErr { + t.Errorf("expected an error, but got none") + } + if err != nil && !test.wantErr { + t.Errorf("unexpected error, got: %v", err) + } + }) + } +} + +func TestIsPodRunning(t *testing.T) { + tests := []struct { + name string + pod *corev1.Pod + want bool + }{ + { + name: "IsPodRunning_PodInPendingState_PodIsNotRunningYet", + pod: &corev1.Pod{ + Status: corev1.PodStatus{ + Phase: corev1.PodPending, + }, + }, + want: false, + }, + { + name: "IsPodRunning_WithDeletionTimestamp_PodIsNotRunningYet", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &metav1.Time{Time: time.Now()}, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + }, + }, + want: false, + }, + { + name: "IsPodRunning_PodReadyConditionReadinessIsFalse_PodIsNotRunningYet", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: nil, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + Conditions: []corev1.PodCondition{ + { + Type: corev1.PodReady, + Status: corev1.ConditionFalse, + }, + }, + }, + }, + want: false, + }, + { + name: "IsPodRunning_PodSatisfyAllRunningConditions_PodIsAlreadyRunning", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: nil, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + Conditions: []corev1.PodCondition{ + { + Type: corev1.PodReady, + Status: corev1.ConditionTrue, + }, + }, + }, + }, + want: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := isPodRunning(*test.pod); got != test.want { + t.Errorf("expected pod running status %t, but got %t", test.want, got) + } + }) + } +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/clientset_generated.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/clientset_generated.go new file mode 100644 index 000000000000..e48af65d3fbb --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/clientset_generated.go @@ -0,0 +1,92 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" + clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" + fakeapiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake" + apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" + fakeapiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{tracker: o} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery + tracker testing.ObjectTracker +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +func (c *Clientset) Tracker() testing.ObjectTracker { + return c.tracker +} + +var ( + _ clientset.Interface = &Clientset{} + _ testing.FakeClient = &Clientset{} +) + +// ApiregistrationV1 retrieves the ApiregistrationV1Client +func (c *Clientset) ApiregistrationV1() apiregistrationv1.ApiregistrationV1Interface { + return &fakeapiregistrationv1.FakeApiregistrationV1{Fake: &c.Fake} +} + +// ApiregistrationV1beta1 retrieves the ApiregistrationV1beta1Client +func (c *Clientset) ApiregistrationV1beta1() apiregistrationv1beta1.ApiregistrationV1beta1Interface { + return &fakeapiregistrationv1beta1.FakeApiregistrationV1beta1{Fake: &c.Fake} +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/doc.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/doc.go new file mode 100644 index 000000000000..9b99e7167091 --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/register.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/register.go new file mode 100644 index 000000000000..880c67a3979a --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake/register.go @@ -0,0 +1,58 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) + +var localSchemeBuilder = runtime.SchemeBuilder{ + apiregistrationv1.AddToScheme, + apiregistrationv1beta1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/doc.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/doc.go new file mode 100644 index 000000000000..16f44399065e --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiregistration_client.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiregistration_client.go new file mode 100644 index 000000000000..3e563e6f07dd --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiregistration_client.go @@ -0,0 +1,40 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" +) + +type FakeApiregistrationV1 struct { + *testing.Fake +} + +func (c *FakeApiregistrationV1) APIServices() v1.APIServiceInterface { + return &FakeAPIServices{c} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeApiregistrationV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiservice.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiservice.go new file mode 100644 index 000000000000..88c87954a5fd --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiservice.go @@ -0,0 +1,132 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +// FakeAPIServices implements APIServiceInterface +type FakeAPIServices struct { + Fake *FakeApiregistrationV1 +} + +var apiservicesResource = v1.SchemeGroupVersion.WithResource("apiservices") + +var apiservicesKind = v1.SchemeGroupVersion.WithKind("APIService") + +// Get takes name of the aPIService, and returns the corresponding aPIService object, and an error if there is any. +func (c *FakeAPIServices) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(apiservicesResource, name), &v1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1.APIService), err +} + +// List takes label and field selectors, and returns the list of APIServices that match those selectors. +func (c *FakeAPIServices) List(ctx context.Context, opts metav1.ListOptions) (result *v1.APIServiceList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(apiservicesResource, apiservicesKind, opts), &v1.APIServiceList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.APIServiceList{ListMeta: obj.(*v1.APIServiceList).ListMeta} + for _, item := range obj.(*v1.APIServiceList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested aPIServices. +func (c *FakeAPIServices) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(apiservicesResource, opts)) +} + +// Create takes the representation of a aPIService and creates it. Returns the server's representation of the aPIService, and an error, if there is any. +func (c *FakeAPIServices) Create(ctx context.Context, aPIService *v1.APIService, opts metav1.CreateOptions) (result *v1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(apiservicesResource, aPIService), &v1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1.APIService), err +} + +// Update takes the representation of a aPIService and updates it. Returns the server's representation of the aPIService, and an error, if there is any. +func (c *FakeAPIServices) Update(ctx context.Context, aPIService *v1.APIService, opts metav1.UpdateOptions) (result *v1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(apiservicesResource, aPIService), &v1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1.APIService), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeAPIServices) UpdateStatus(ctx context.Context, aPIService *v1.APIService, opts metav1.UpdateOptions) (*v1.APIService, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(apiservicesResource, "status", aPIService), &v1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1.APIService), err +} + +// Delete takes name of the aPIService and deletes it. Returns an error if one occurs. +func (c *FakeAPIServices) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(apiservicesResource, name, opts), &v1.APIService{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAPIServices) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(apiservicesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.APIServiceList{}) + return err +} + +// Patch applies the patch and returns the patched aPIService. +func (c *FakeAPIServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(apiservicesResource, name, pt, data, subresources...), &v1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1.APIService), err +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/doc.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/doc.go new file mode 100644 index 000000000000..16f44399065e --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiregistration_client.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiregistration_client.go new file mode 100644 index 000000000000..9b32316af6ae --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiregistration_client.go @@ -0,0 +1,40 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" +) + +type FakeApiregistrationV1beta1 struct { + *testing.Fake +} + +func (c *FakeApiregistrationV1beta1) APIServices() v1beta1.APIServiceInterface { + return &FakeAPIServices{c} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeApiregistrationV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiservice.go b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiservice.go new file mode 100644 index 000000000000..4c5a1868a9bf --- /dev/null +++ b/vendor/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiservice.go @@ -0,0 +1,132 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" +) + +// FakeAPIServices implements APIServiceInterface +type FakeAPIServices struct { + Fake *FakeApiregistrationV1beta1 +} + +var apiservicesResource = v1beta1.SchemeGroupVersion.WithResource("apiservices") + +var apiservicesKind = v1beta1.SchemeGroupVersion.WithKind("APIService") + +// Get takes name of the aPIService, and returns the corresponding aPIService object, and an error if there is any. +func (c *FakeAPIServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(apiservicesResource, name), &v1beta1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.APIService), err +} + +// List takes label and field selectors, and returns the list of APIServices that match those selectors. +func (c *FakeAPIServices) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.APIServiceList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(apiservicesResource, apiservicesKind, opts), &v1beta1.APIServiceList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.APIServiceList{ListMeta: obj.(*v1beta1.APIServiceList).ListMeta} + for _, item := range obj.(*v1beta1.APIServiceList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested aPIServices. +func (c *FakeAPIServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(apiservicesResource, opts)) +} + +// Create takes the representation of a aPIService and creates it. Returns the server's representation of the aPIService, and an error, if there is any. +func (c *FakeAPIServices) Create(ctx context.Context, aPIService *v1beta1.APIService, opts v1.CreateOptions) (result *v1beta1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(apiservicesResource, aPIService), &v1beta1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.APIService), err +} + +// Update takes the representation of a aPIService and updates it. Returns the server's representation of the aPIService, and an error, if there is any. +func (c *FakeAPIServices) Update(ctx context.Context, aPIService *v1beta1.APIService, opts v1.UpdateOptions) (result *v1beta1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(apiservicesResource, aPIService), &v1beta1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.APIService), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeAPIServices) UpdateStatus(ctx context.Context, aPIService *v1beta1.APIService, opts v1.UpdateOptions) (*v1beta1.APIService, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(apiservicesResource, "status", aPIService), &v1beta1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.APIService), err +} + +// Delete takes name of the aPIService and deletes it. Returns an error if one occurs. +func (c *FakeAPIServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(apiservicesResource, name, opts), &v1beta1.APIService{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAPIServices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(apiservicesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.APIServiceList{}) + return err +} + +// Patch applies the patch and returns the patched aPIService. +func (c *FakeAPIServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.APIService, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(apiservicesResource, name, pt, data, subresources...), &v1beta1.APIService{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.APIService), err +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 99b354eacd4d..288c3285e18a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1629,9 +1629,12 @@ k8s.io/kube-aggregator/pkg/apis/apiregistration/validation k8s.io/kube-aggregator/pkg/apiserver k8s.io/kube-aggregator/pkg/apiserver/scheme k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset +k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1 +k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1 +k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake k8s.io/kube-aggregator/pkg/client/informers/externalversions k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1