diff --git a/cmd/command.go b/cmd/command.go index 0bd976e1..6ade8833 100644 --- a/cmd/command.go +++ b/cmd/command.go @@ -18,6 +18,7 @@ const ( defaultConcurrentReconciles = 1 defaultMetricsBindAddress = ":9643" defaultHealthBindAddress = ":9644" + defaultPprofBindAddress = ":8081" defaultLeaseDuration = 15 * time.Second defaultRenewDeadline = 10 * time.Second defaultRetryPeriod = 2 * time.Second @@ -57,6 +58,8 @@ type SharedOpts struct { MetricsBindAddress string // HealthBindAddress is the TCP address that the controller should bind to for serving health probes HealthBindAddress string + // PprofBindAddress is the TCP address that the controller should bind to for serving profiling endpoint. + PprofBindAddress string } // LeaderElectionOpts defines the configuration of leader election @@ -94,6 +97,7 @@ func SetSharedOpts(fs *flag.FlagSet, opts *SharedOpts) { fs.Float64Var(&opts.KubeApiQps, "kube-api-qps", float64(rest.DefaultQPS), "Maximum QPS (queries per second) allowed from the client to the API server") fs.StringVar(&opts.MetricsBindAddress, "metrics-bind-addr", defaultMetricsBindAddress, "The TCP address that the controller should bind to for serving prometheus metrics") fs.StringVar(&opts.HealthBindAddress, "health-bind-addr", defaultHealthBindAddress, "The TCP address that the controller should bind to for serving health probes") + fs.StringVar(&opts.PprofBindAddress, "pprof-bind-addr", defaultPprofBindAddress, "The TCP address that the controller should bind to for serving profiling endpoint") bindLeaderElectionFlags(fs, opts) } diff --git a/cmd/probercmd.go b/cmd/probercmd.go index 3c4bc85d..cc138c4a 100644 --- a/cmd/probercmd.go +++ b/cmd/probercmd.go @@ -7,6 +7,7 @@ package cmd import ( "flag" "fmt" + machinev1alpha1 "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/metrics/server" "github.com/gardener/dependency-watchdog/controllers/cluster" @@ -76,6 +77,7 @@ func init() { localSchemeBuilder := runtime.NewSchemeBuilder( clientgoscheme.AddToScheme, extensionsv1alpha1.AddToScheme, + machinev1alpha1.AddToScheme, ) utilruntime.Must(localSchemeBuilder.AddToScheme(scheme)) } @@ -107,6 +109,7 @@ func startClusterControllerMgr(logger logr.Logger) (manager.Manager, error) { LeaderElectionResourceLock: resourcelock.LeasesResourceLock, LeaderElectionID: proberLeaderElectionID, Logger: proberLogger, + PprofBindAddress: proberOpts.SharedOpts.PprofBindAddress, }) if err != nil { return nil, fmt.Errorf("failed to start the prober controller manager %w", err) diff --git a/cmd/weedercmd.go b/cmd/weedercmd.go index 2815c615..89290037 100644 --- a/cmd/weedercmd.go +++ b/cmd/weedercmd.go @@ -76,8 +76,8 @@ func startEndpointsControllerMgr(logger logr.Logger) (manager.Manager, error) { } restConf := ctrl.GetConfigOrDie() - restConf.QPS = float32(proberOpts.KubeApiQps) - restConf.Burst = proberOpts.KubeApiBurst + restConf.QPS = float32(weederOpts.KubeApiQps) + restConf.Burst = weederOpts.KubeApiBurst mgr, err := ctrl.NewManager(restConf, ctrl.Options{ Scheme: scheme, Metrics: server.Options{BindAddress: weederOpts.SharedOpts.MetricsBindAddress}, @@ -90,6 +90,7 @@ func startEndpointsControllerMgr(logger logr.Logger) (manager.Manager, error) { LeaderElectionResourceLock: resourcelock.LeasesResourceLock, LeaderElectionID: weederLeaderElectionID, Logger: weederLogger, + PprofBindAddress: weederOpts.SharedOpts.PprofBindAddress, }) if err != nil { return nil, fmt.Errorf("failed to start the weeder controller manager %w", err) diff --git a/controllers/cluster/cluster_controller.go b/controllers/cluster/cluster_controller.go index 3c20ac29..61dba7bf 100644 --- a/controllers/cluster/cluster_controller.go +++ b/controllers/cluster/cluster_controller.go @@ -8,8 +8,11 @@ import ( "context" "fmt" + "github.com/gardener/dependency-watchdog/internal/util" + papi "github.com/gardener/dependency-watchdog/api/prober" "github.com/gardener/dependency-watchdog/internal/prober/scaler" + shootclient "github.com/gardener/dependency-watchdog/internal/prober/shoot" "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -34,7 +37,7 @@ const controllerName = "cluster" // Reconciler reconciles a Cluster object type Reconciler struct { - client.Client + Client client.Client // Scheme is the controller-runtime scheme used to initialize the controller manager and to validate the probe config Scheme *runtime.Scheme // ProberMgr is interface to manage lifecycle of probers. @@ -73,51 +76,25 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu return ctrl.Result{}, fmt.Errorf("error extracting shoot from cluster: %w", err) } - // If shoot is marked for deletion then any existing probes will be unregistered - if shoot.DeletionTimestamp != nil { - if r.ProberMgr.Unregister(req.Name) { - log.Info("Cluster has been marked for deletion, existing prober has been removed") - } - return ctrl.Result{}, nil - } - - // if hibernation is enabled then we will remove any existing prober. Any resource scaling that is required in case of hibernation will now be handled as part of worker reconciliation in extension controllers. - if v1beta1helper.HibernationIsEnabled(shoot) { - if r.ProberMgr.Unregister(req.Name) { - log.Info("Cluster hibernation is enabled, existing prober has been removed") - } - return ctrl.Result{}, nil - } - - // if control plane migration has started for a shoot, then any existing probe should be removed as it is no longer needed. - if shoot.Status.LastOperation != nil && shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeMigrate { - if r.ProberMgr.Unregister(req.Name) { - log.Info("Cluster migration is enabled, existing prober has been removed") - } - return ctrl.Result{}, nil - } + shootControlNamespace := cluster.Name - // if a shoot is created without any workers (this can only happen for control-plane-as-a-service use case), then if there is a probe registered then - // unregister the probe and return early. If there is no existing probe registered then return early. - if len(shoot.Spec.Provider.Workers) == 0 { - if r.ProberMgr.Unregister(req.Name) { - log.Info("Cluster does not have any workers. An existing probe has been removed") - } else { - log.Info("Cluster does not have any workers. No probe will be created") + if shouldStopProber(shoot, log) { + if r.ProberMgr.Unregister(shootControlNamespace) { + log.Info("Existing prober has been removed") } return ctrl.Result{}, nil } - if canStartProber(shoot) { - r.startProber(ctx, shoot, log, req.Name) + if canStartProber(shoot, log) { + r.startProber(ctx, shootControlNamespace, shoot, log) } return ctrl.Result{}, nil } -// getCluster will retrieve the cluster object given the namespace and name Not found is not treated as an error and is handled differently in the caller +// getCluster will retrieve the cluster object given the namespace and name. Cluster not found is not treated as an error and is handled differently in the caller func (r *Reconciler) getCluster(ctx context.Context, namespace string, name string) (cluster *extensionsv1alpha1.Cluster, notFound bool, err error) { cluster = &extensionsv1alpha1.Cluster{} - if err := r.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, cluster); err != nil { + if err := r.Client.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, cluster); err != nil { if errors.IsNotFound(err) { return nil, true, nil } @@ -126,40 +103,32 @@ func (r *Reconciler) getCluster(ctx context.Context, namespace string, name stri return cluster, false, nil } -// canStartProber checks if a probe can be registered and started. -// shoot.Status.LastOperation.Type provides an insight into the current state of the cluster. It is important to identify the following cases: -// 1. Cluster has been created successfully => This will ensure that the current state of shoot Kube API Server can be acted upon to decide on scaling operations. If the cluster -// is in the process of creation, then it is possible that the control plane components have not completely come up. If the probe starts prematurely then it could start to scale down resources. -// 2. During control plane migration, the value of shoot.Status.LastOperation.Type will be "Restore" => During this time it is imperative that probe is started early to ensure -// that MCM is scaled down in case connectivity to the Kube API server of the shoot on the destination seed is broken, else it will try and recreate machines. -// If the shoot.Status.LastOperation.Type == "Reconcile" then it is assumed that the cluster has been successfully created at-least once, and it is safe to start the probe. -func canStartProber(shoot *v1beta1.Shoot) bool { - if shoot.Status.IsHibernated || shoot.Status.LastOperation == nil { - return false - } - if shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeReconcile || - (shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeRestore && shoot.Status.LastOperation.State == v1beta1.LastOperationStateSucceeded) || - (shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeCreate && shoot.Status.LastOperation.State == v1beta1.LastOperationStateSucceeded) { - return true - } - return false -} - // startProber sets up a new probe against a given key which uniquely identifies the probe. // Typically, the key in case of a shoot cluster is the shoot namespace -func (r *Reconciler) startProber(ctx context.Context, shoot *v1beta1.Shoot, logger logr.Logger, key string) { - _, ok := r.ProberMgr.GetProber(key) +func (r *Reconciler) startProber(ctx context.Context, shootControlNs string, shoot *v1beta1.Shoot, logger logr.Logger) { + workerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + existingProber, ok := r.ProberMgr.GetProber(shootControlNs) if !ok { - probeConfig := r.getEffectiveProbeConfig(shoot, logger) - deploymentScaler := scaler.NewScaler(key, probeConfig.DependentResourceInfos, r.Client, r.ScaleGetter, logger) - shootClientCreator := prober.NewShootClientCreator(r.Client) - p := prober.NewProber(ctx, key, probeConfig, deploymentScaler, shootClientCreator, logger) - r.ProberMgr.Register(*p) - logger.Info("Starting a new prober") - go p.Run() + r.createAndRunProber(ctx, shootControlNs, shoot, workerNodeConditions, logger) + } else { + if existingProber.AreWorkerNodeConditionsStale(workerNodeConditions) { + logger.Info("Restarting prober due to change in node conditions for workers") + _ = r.ProberMgr.Unregister(shootControlNs) + r.createAndRunProber(ctx, shootControlNs, shoot, workerNodeConditions, logger) + } } } +func (r *Reconciler) createAndRunProber(ctx context.Context, shootNamespace string, shoot *v1beta1.Shoot, workerNodeConditions map[string][]string, logger logr.Logger) { + probeConfig := r.getEffectiveProbeConfig(shoot, logger) + deploymentScaler := scaler.NewScaler(shootNamespace, probeConfig.DependentResourceInfos, r.Client, r.ScaleGetter, logger) + shootClientCreator := shootclient.NewClientCreator(shootNamespace, probeConfig.KubeConfigSecretName, r.Client) + p := prober.NewProber(ctx, r.Client, shootNamespace, probeConfig, workerNodeConditions, deploymentScaler, shootClientCreator, logger) + r.ProberMgr.Register(*p) + logger.Info("Starting a new prober") + go p.Run() +} + // SetupWithManager sets up the controller with the Manager. func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error { c, err := controller.New( @@ -186,3 +155,55 @@ func (r *Reconciler) getEffectiveProbeConfig(shoot *v1beta1.Shoot, logger logr.L } return &probeConfig } + +func shouldStopProber(shoot *v1beta1.Shoot, logger logr.Logger) bool { + // If shoot is marked for deletion then any existing probes will be unregistered + if shoot.DeletionTimestamp != nil { + logger.Info("Cluster has been marked for deletion, existing prober if any will be removed") + return true + } + + // if hibernation is enabled then we will remove any existing prober. Any resource scaling that is required in case of hibernation will now be handled as part of worker reconciliation in extension controllers. + if v1beta1helper.HibernationIsEnabled(shoot) { + logger.Info("Cluster hibernation is enabled, existing prober if any will be removed") + return true + } + + // if control plane migration has started for a shoot, then any existing probe should be removed as it is no longer needed. + if shoot.Status.LastOperation != nil && shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeMigrate { + logger.Info("Cluster migration is enabled, existing prober if any will be removed") + return true + } + + // if a shoot is created without any workers (this can only happen for control-plane-as-a-service use case), then any existing probe should be removed as it is no longer needed. + if len(shoot.Spec.Provider.Workers) == 0 { + logger.Info("Cluster does not have any workers, existing prober if any will be removed") + return true + } + return false +} + +// canStartProber checks if a probe can be registered and started. +// shoot.Status.LastOperation.Type provides an insight into the current state of the cluster. It is important to identify the following cases: +// 1. Cluster has been created successfully => This will ensure that the current state of shoot Kube API Server can be acted upon to decide on scaling operations. If the cluster +// is in the process of creation, then it is possible that the control plane components have not completely come up. If the probe starts prematurely then it could start to scale down resources. +// 2. During control plane migration, the value of shoot.Status.LastOperation.Type will be "Restore" => During this time it is imperative that probe is started early to ensure +// that MCM is scaled down in case connectivity to the Kube API server of the shoot on the destination seed is broken, else it will try and recreate machines. +// If the shoot.Status.LastOperation.Type == "Reconcile" then it is assumed that the cluster has been successfully created at-least once, and it is safe to start the probe. +func canStartProber(shoot *v1beta1.Shoot, logger logr.Logger) bool { + if !v1beta1helper.HibernationIsEnabled(shoot) && shoot.Status.IsHibernated { + logger.Info("Cannot start probe. Cluster is waking up from hibernation") + return false + } + if shoot.Status.LastOperation == nil { + logger.Info("Cannot start probe. Cluster is creation phase") + return false + } + if shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeReconcile || + (shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeRestore && shoot.Status.LastOperation.State == v1beta1.LastOperationStateSucceeded) || + (shoot.Status.LastOperation.Type == v1beta1.LastOperationTypeCreate && shoot.Status.LastOperation.State == v1beta1.LastOperationStateSucceeded) { + return true + } + logger.Info("Cannot start probe. Cluster is either in migration/restore or in creation phase") + return false +} diff --git a/controllers/cluster/cluster_controller_test.go b/controllers/cluster/cluster_controller_test.go index 5600fa65..45bfe555 100644 --- a/controllers/cluster/cluster_controller_test.go +++ b/controllers/cluster/cluster_controller_test.go @@ -12,6 +12,7 @@ import ( "log" "os" "path/filepath" + "reflect" "testing" "time" @@ -137,7 +138,7 @@ func testProberDedicatedEnvTest(t *testing.T) { func testReconciliationAfterAPIServerIsDown(ctx context.Context, t *testing.T, testEnv *envtest.Environment, _ client.Client, reconciler *Reconciler, _ manager.Manager, cancelFn context.CancelFunc) { var err error g := NewWithT(t) - cluster, _, err := testutil.CreateClusterResource(1, nil, false) + cluster, _, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) cancelFn() err = testEnv.ControlPlane.APIServer.Stop() @@ -169,6 +170,7 @@ func testProberSharedEnvTest(t *testing.T) { {"start prober if last operation is restore and successfully", testLastOperationIsRestoreAndSuccessful}, {"start prober if last operation is reconciliation of shoot", testLastOperationIsShootReconciliation}, {"no prober if shoot has no workers", testShootHasNoWorkers}, + {"prober should start with correct worker node conditions mapping", testShootWorkerNodeConditions}, } for _, test := range tests { @@ -179,6 +181,25 @@ func testProberSharedEnvTest(t *testing.T) { } } +func testShootWorkerNodeConditions(g *WithT, crClient client.Client, reconciler *Reconciler) { + workerNodeConditions := [][]string{{testutil.NodeConditionDiskPressure, testutil.NodeConditionMemoryPressure}} + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).WithWorkerNodeConditions(workerNodeConditions).Build() + g.Expect(err).ToNot(HaveOccurred()) + createCluster(g, crClient, cluster) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) + // update the workers + updatedWorkerNodeConditions := []string{testutil.NodeConditionPIDPressure, testutil.NodeConditionNetworkReady} + shoot.Spec.Provider.Workers[0].MachineControllerManagerSettings.NodeConditions = updatedWorkerNodeConditions + cluster.Spec.Shoot = runtime.RawExtension{ + Object: shoot, + } + updateCluster(g, crClient, cluster) + expectedWorkerNodeConditions = util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) + deleteClusterAndCheckIfProberRemoved(g, crClient, reconciler, cluster) +} + func deleteAllClusters(g *WithT, crClient client.Client) { err := crClient.DeleteAllOf(context.Background(), &gardenerv1alpha1.Cluster{}) g.Expect(err).ToNot(HaveOccurred()) @@ -211,10 +232,11 @@ func updateShootHibernationSpec(g *WithT, crClient client.Client, cluster *garde } func testShootHibernation(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) createCluster(g, crClient, cluster) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) // update spec to indicate start of hibernation updateShootHibernationSpec(g, crClient, cluster, shoot, pointer.Bool(true)) proberShouldNotBePresent(g, reconciler, cluster) @@ -225,7 +247,7 @@ func testShootHibernation(g *WithT, crClient client.Client, reconciler *Reconcil proberShouldNotBePresent(g, reconciler, cluster) // update status to indicate cluster has successfully woken up updateShootHibernationStatus(g, crClient, cluster, shoot, false) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) deleteClusterAndCheckIfProberRemoved(g, crClient, reconciler, cluster) } @@ -238,7 +260,7 @@ func updateShootHibernationStatus(g *WithT, crClient client.Client, cluster *gar } func testInvalidShootInClusterSpec(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, _, err := testutil.CreateClusterResource(1, nil, false) + cluster, _, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) cluster.Spec.Shoot.Object = nil cluster.Spec.Shoot.Raw = []byte(`{"apiVersion": 8}`) @@ -260,10 +282,11 @@ func updateShootDeletionTimeStamp(g *WithT, crClient client.Client, cluster *gar } func testProberShouldBeRemovedIfDeletionTimeStampIsSet(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) createCluster(g, crClient, cluster) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) updateShootDeletionTimeStamp(g, crClient, cluster, shoot) proberShouldNotBePresent(g, reconciler, cluster) deleteClusterAndCheckIfProberRemoved(g, crClient, reconciler, cluster) @@ -292,12 +315,13 @@ func testShootCreationNotComplete(g *WithT, crClient client.Client, reconciler * } for _, testCase := range testCases { - cluster, shoot, err := testutil.CreateClusterResource(1, shootKCMNodeMonitorGracePeriod, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).WithNodeMonitorGracePeriod(shootKCMNodeMonitorGracePeriod).Build() g.Expect(err).ToNot(HaveOccurred()) setShootLastOperationStatus(cluster, shoot, gardencorev1beta1.LastOperationTypeCreate, testCase.lastOpState) createCluster(g, crClient, cluster) if testCase.shouldCreateProber { - proberShouldBePresent(g, reconciler, cluster, *shootKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, *shootKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) } else { proberShouldNotBePresent(g, reconciler, cluster) } @@ -306,7 +330,7 @@ func testShootCreationNotComplete(g *WithT, crClient client.Client, reconciler * } func testShootIsMigrating(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) createCluster(g, crClient, cluster) setShootLastOperationStatus(cluster, shoot, gardencorev1beta1.LastOperationTypeMigrate, "") @@ -316,10 +340,11 @@ func testShootIsMigrating(g *WithT, crClient client.Client, reconciler *Reconcil } func testShootRestoringIsNotComplete(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) createCluster(g, crClient, cluster) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) // cluster migration starts setShootLastOperationStatus(cluster, shoot, gardencorev1beta1.LastOperationTypeMigrate, "") updateCluster(g, crClient, cluster) @@ -332,36 +357,37 @@ func testShootRestoringIsNotComplete(g *WithT, crClient client.Client, reconcile } func testLastOperationIsRestoreAndSuccessful(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) setShootLastOperationStatus(cluster, shoot, gardencorev1beta1.LastOperationTypeRestore, gardencorev1beta1.LastOperationStateSucceeded) createCluster(g, crClient, cluster) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) deleteClusterAndCheckIfProberRemoved(g, crClient, reconciler, cluster) } func testLastOperationIsShootReconciliation(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, shoot, err := testutil.CreateClusterResource(1, nil, false) + cluster, shoot, err := testutil.NewClusterBuilder().WithWorkerCount(1).Build() g.Expect(err).ToNot(HaveOccurred()) setShootLastOperationStatus(cluster, shoot, gardencorev1beta1.LastOperationTypeReconcile, "") createCluster(g, crClient, cluster) - proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod) + expectedWorkerNodeConditions := util.GetEffectiveNodeConditionsForWorkers(shoot) + proberShouldBePresent(g, reconciler, cluster, defaultKCMNodeMonitorGracePeriod, expectedWorkerNodeConditions) deleteClusterAndCheckIfProberRemoved(g, crClient, reconciler, cluster) } func testShootHasNoWorkers(g *WithT, crClient client.Client, reconciler *Reconciler) { - cluster, _, err := testutil.CreateClusterResource(0, nil, false) + cluster, _, err := testutil.NewClusterBuilder().Build() g.Expect(err).ToNot(HaveOccurred()) createCluster(g, crClient, cluster) proberShouldNotBePresent(g, reconciler, cluster) } -func proberShouldBePresent(g *WithT, reconciler *Reconciler, cluster *gardenerv1alpha1.Cluster, expectedKCMNodeMonitorGraceDuration metav1.Duration) { - g.Eventually(func() int { return len(reconciler.ProberMgr.GetAllProbers()) }, 10*time.Second, 1*time.Second).Should(Equal(1)) - prober, ok := reconciler.ProberMgr.GetProber(cluster.ObjectMeta.Name) - g.Expect(ok).To(BeTrue()) - g.Expect(*prober.GetConfig().KCMNodeMonitorGraceDuration).To(Equal(expectedKCMNodeMonitorGraceDuration)) - g.Expect(prober.IsClosed()).To(BeFalse()) +func proberShouldBePresent(g *WithT, reconciler *Reconciler, cluster *gardenerv1alpha1.Cluster, expectedKCMNodeMonitorGraceDuration metav1.Duration, expectedWorkerNodeConditions map[string][]string) { + g.Eventually(func() bool { + prober, ok := reconciler.ProberMgr.GetProber(cluster.ObjectMeta.Name) + return ok && reflect.DeepEqual(*prober.GetConfig().KCMNodeMonitorGraceDuration, expectedKCMNodeMonitorGraceDuration) && !prober.AreWorkerNodeConditionsStale(expectedWorkerNodeConditions) && !prober.IsClosed() + }, 10*time.Second, 1*time.Second).Should(BeTrue()) } func proberShouldNotBePresent(g *WithT, reconciler *Reconciler, cluster *gardenerv1alpha1.Cluster) { diff --git a/controllers/cluster/clusterpredicate_test.go b/controllers/cluster/clusterpredicate_test.go index 39ce6539..801ca1ab 100644 --- a/controllers/cluster/clusterpredicate_test.go +++ b/controllers/cluster/clusterpredicate_test.go @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: Apache-2.0 +//go:build !kind_tests + package cluster import ( @@ -30,25 +32,25 @@ func TestCreateAndDeletePredicateFunc(t *testing.T) { {"test: delete predicate func for cluster having no workers", testDeletePredicateFunc, 0, false}, } - for _, test := range tests { - t.Run(test.title, func(t *testing.T) { + for _, entry := range tests { + t.Run(entry.title, func(t *testing.T) { g := NewWithT(t) - predicateResult := test.run(g, test.numWorkers) - g.Expect(predicateResult).To(Equal(test.expectedResult)) + predicateResult := entry.run(g, entry.numWorkers) + g.Expect(predicateResult).To(Equal(entry.expectedResult)) }) } } -func testCreatePredicateFunc(g *WithT, numWorkers int) bool { - cluster, _, err := test.CreateClusterResource(numWorkers, nil, true) +func testCreatePredicateFunc(g *WithT, workerCount int) bool { + cluster, _, err := test.NewClusterBuilder().WithWorkerCount(workerCount).WithRawShoot(true).Build() g.Expect(err).ToNot(HaveOccurred()) e := event.CreateEvent{Object: cluster} predicateFuncs := workerLessShoot(logr.Discard()) return predicateFuncs.Create(e) } -func testDeletePredicateFunc(g *WithT, numWorkers int) bool { - cluster, _, err := test.CreateClusterResource(numWorkers, nil, true) +func testDeletePredicateFunc(g *WithT, workerCount int) bool { + cluster, _, err := test.NewClusterBuilder().WithWorkerCount(workerCount).WithRawShoot(true).Build() g.Expect(err).ToNot(HaveOccurred()) e := event.DeleteEvent{Object: cluster} predicateFuncs := workerLessShoot(logr.Discard()) @@ -69,19 +71,19 @@ func TestUpdatePredicateFunc(t *testing.T) { {"test: both old and new cluster have workers and are different in number", 1, 2, true}, } - for _, test := range tests { - t.Run(test.title, func(t *testing.T) { + for _, entry := range tests { + t.Run(entry.title, func(t *testing.T) { g := NewWithT(t) - predicateResult := testUpdatePredicateFunc(g, test.oldNumWorkers, test.newNumWorkers) - g.Expect(predicateResult).To(Equal(test.expectedResult)) + predicateResult := testUpdatePredicateFunc(g, entry.oldNumWorkers, entry.newNumWorkers) + g.Expect(predicateResult).To(Equal(entry.expectedResult)) }) } } -func testUpdatePredicateFunc(g *WithT, oldNumWorker, newNumWorkers int) bool { - oldCluster, _, err := test.CreateClusterResource(oldNumWorker, nil, true) +func testUpdatePredicateFunc(g *WithT, oldNumWorkers, newNumWorkers int) bool { + oldCluster, _, err := test.NewClusterBuilder().WithWorkerCount(oldNumWorkers).WithRawShoot(true).Build() g.Expect(err).ToNot(HaveOccurred()) - newCluster, _, err := test.CreateClusterResource(newNumWorkers, nil, true) + newCluster, _, err := test.NewClusterBuilder().WithWorkerCount(newNumWorkers).WithRawShoot(true).Build() g.Expect(err).ToNot(HaveOccurred()) e := event.UpdateEvent{ ObjectOld: oldCluster, @@ -111,7 +113,7 @@ func TestShootHasWorkersForNonShootResource(t *testing.T) { func TestShootHasWorkersForInvalidShootResource(t *testing.T) { g := NewWithT(t) - cluster, _, err := test.CreateClusterResource(0, nil, false) + cluster, _, err := test.NewClusterBuilder().WithRawShoot(true).Build() g.Expect(err).ToNot(HaveOccurred()) seed := gardencorev1beta1.Seed{ ObjectMeta: metav1.ObjectMeta{ diff --git a/controllers/endpoint/endpoints_controller_test.go b/controllers/endpoint/endpoints_controller_test.go index 561c0607..e8350f7b 100644 --- a/controllers/endpoint/endpoints_controller_test.go +++ b/controllers/endpoint/endpoints_controller_test.go @@ -9,10 +9,11 @@ package endpoint import ( "context" "path/filepath" - "strings" "testing" "time" + "k8s.io/apimachinery/pkg/util/rand" + testutil "github.com/gardener/dependency-watchdog/internal/test" "k8s.io/client-go/kubernetes/scheme" @@ -127,9 +128,10 @@ func testWeederSharedEnvTest(t *testing.T) { for _, test := range tests { childCtx, chileCancelFn := context.WithCancel(ctx) - ns := testutil.CreateTestNamespace(childCtx, g, reconciler.Client, strings.ToLower(test.name)) + testNs := rand.String(4) + testutil.CreateTestNamespace(childCtx, g, reconciler.Client, testNs) t.Run(test.description, func(t *testing.T) { - test.run(childCtx, chileCancelFn, g, reconciler, ns) + test.run(childCtx, chileCancelFn, g, reconciler, testNs) }) deleteAllPods(childCtx, g, reconciler.Client) deleteAllEp(childCtx, g, reconciler.Client) @@ -150,9 +152,10 @@ func testWeederDedicatedEnvTest(t *testing.T) { for _, test := range tests { ctx, cancelFn := context.WithCancel(context.Background()) testEnv, reconciler := setupWeederEnv(ctx, t, test.apiServerFlags) - ns := testutil.CreateTestNamespace(ctx, g, reconciler.Client, strings.ToLower(test.name)) + testNs := rand.String(4) + testutil.CreateTestNamespace(ctx, g, reconciler.Client, testNs) t.Run(test.description, func(t *testing.T) { - test.run(ctx, cancelFn, g, reconciler, ns) + test.run(ctx, cancelFn, g, reconciler, testNs) }) testutil.TeardownEnv(g, testEnv, cancelFn) } diff --git a/go.mod b/go.mod index 695232ff..8a868f00 100644 --- a/go.mod +++ b/go.mod @@ -1,69 +1,68 @@ module github.com/gardener/dependency-watchdog -go 1.22 +go 1.22.0 require ( - github.com/gardener/gardener v1.86.0 - github.com/go-logr/logr v1.3.0 - github.com/golang/mock v1.6.0 - github.com/google/gnostic-models v0.6.8 + github.com/gardener/gardener v1.99.1 + github.com/gardener/machine-controller-manager v0.53.0 + github.com/go-logr/logr v1.4.1 github.com/hashicorp/go-multierror v1.1.1 - github.com/onsi/gomega v1.29.0 - go.uber.org/zap v1.26.0 - k8s.io/api v0.29.4 - k8s.io/apimachinery v0.29.4 - k8s.io/client-go v0.29.4 - k8s.io/code-generator v0.29.4 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.16.3 + github.com/onsi/gomega v1.33.1 + go.uber.org/zap v1.27.0 + k8s.io/api v0.29.6 + k8s.io/apimachinery v0.29.6 + k8s.io/client-go v0.29.6 + k8s.io/code-generator v0.29.6 + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 + sigs.k8s.io/controller-runtime v0.17.5 sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231015215740-bf15e44028f9 - sigs.k8s.io/kind v0.17.0 - sigs.k8s.io/yaml v1.3.0 + sigs.k8s.io/kind v0.20.0 + sigs.k8s.io/yaml v1.4.0 ) require ( - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.3 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fluent/fluent-operator/v2 v2.2.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gardener/etcd-druid v0.21.0 // indirect - github.com/gardener/hvpa-controller/api v0.5.0 // indirect - github.com/gardener/machine-controller-manager v0.50.0 // indirect - github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-logr/zapr v1.2.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect + github.com/fluent/fluent-operator/v2 v2.9.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gardener/cert-management v0.15.0 // indirect + github.com/gardener/etcd-druid v0.22.1 // indirect + github.com/gardener/hvpa-controller/api v0.15.0 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/go-openapi/errors v0.20.4 // indirect + github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/huandu/xstrings v1.3.2 // indirect - github.com/imdario/mergo v0.3.12 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/spdystream v0.2.0 // indirect @@ -73,44 +72,49 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cobra v1.7.0 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/protobuf v1.34.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - istio.io/api v1.19.2-0.20231011000955-f3015ebb5bd4 // indirect - istio.io/client-go v1.19.3 // indirect - k8s.io/apiextensions-apiserver v0.28.3 // indirect - k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 // indirect - k8s.io/component-base v0.28.3 // indirect + helm.sh/helm/v3 v3.14.4 // indirect + istio.io/api v1.22.2 // indirect + istio.io/client-go v1.22.0 // indirect + k8s.io/apiextensions-apiserver v0.29.6 // indirect + k8s.io/autoscaler/vertical-pod-autoscaler v1.1.2 // indirect + k8s.io/component-base v0.29.6 // indirect k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect - k8s.io/helm v2.17.0+incompatible // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-aggregator v0.28.3 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-aggregator v0.29.6 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/kubelet v0.28.3 // indirect - k8s.io/metrics v0.28.3 // indirect + k8s.io/kubelet v0.29.6 // indirect + k8s.io/metrics v0.29.6 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index d0855731..3c8c7d69 100644 --- a/go.sum +++ b/go.sum @@ -3,39 +3,13 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= @@ -50,35 +24,29 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= -github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -88,17 +56,15 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -107,55 +73,48 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fluent/fluent-operator/v2 v2.2.0 h1:97CiP6WKOHRM7zY/zCynX187Rg+T8hgx2JzD2iuJof8= -github.com/fluent/fluent-operator/v2 v2.2.0/go.mod h1:v/q0zLEOWP6MKHP7xvrhtASZTwlrk4LcCne/kgPQ7J0= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fluent/fluent-operator/v2 v2.9.0 h1:VFGgRPOI+yxnOrTIAL6sgFCtc+quDda12iyVL1lRQag= +github.com/fluent/fluent-operator/v2 v2.9.0/go.mod h1:Hthhi/3oO26udvro6t5foUx20PZAMn7WGUhSnEWUV9U= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gardener/etcd-druid v0.21.0 h1:kgr3KR+lVL4+k2WD+9PMrTY1eePkQ7CZHSCB5A+Q9TQ= -github.com/gardener/etcd-druid v0.21.0/go.mod h1:1tAeHycB0Vb2GfCX6sUCc6V6frGrCQI//quVg4K3GNA= -github.com/gardener/gardener v1.86.0 h1:r0DjNZbUc2F/feWDrySZ/AU/5LAr0LoKXdraFtPb6NQ= -github.com/gardener/gardener v1.86.0/go.mod h1:8eHlXs2EkaghrgQwK8qEiVw3dZGpNJaq+I9IkPpReA4= -github.com/gardener/hvpa-controller/api v0.5.0 h1:f4F3O7YUrenwh4S3TgPREPiB287JjjUiUL18OqPLyAA= -github.com/gardener/hvpa-controller/api v0.5.0/go.mod h1:QQl3ELkCaki+8RhXl0FZMfvnm0WCGwGJlGmrxJj6lvM= -github.com/gardener/machine-controller-manager v0.50.0 h1:3dcQjzueFU1TGgprV00adjb3OCR99myTBx8DQGxywks= -github.com/gardener/machine-controller-manager v0.50.0/go.mod h1:RySZ40AgbNV/wMq60G/w49kb+okbj5Xs1A6usz5Pm/I= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gardener/cert-management v0.15.0 h1:ohm1eWae2rQSkwFGWXTt+lBv4rLBhtJsJgqvaXJBs6o= +github.com/gardener/cert-management v0.15.0/go.mod h1:3BK2VEtGwv2ijf3bSziTLMCUvYnPzIQrQ/uPeZzL4m0= +github.com/gardener/etcd-druid v0.22.1 h1:g5NN/4aqKKX40ehupeYYyYoZ/b85sffSANcs0vzNatk= +github.com/gardener/etcd-druid v0.22.1/go.mod h1:FROhfVKyWBo4krlPe3R6FIhJRmOmijEWBdEeUP0CJjE= +github.com/gardener/gardener v1.99.1 h1:c/wVXYgt4j7eHCMwxpQPPpaLXt1BY/IPYStfCtNsR8Q= +github.com/gardener/gardener v1.99.1/go.mod h1:XboPwJptOg9ZfXTjuohGk7X8kxnF0o88gJnz6Ed7Vqc= +github.com/gardener/hvpa-controller/api v0.15.0 h1:igsalL5Z6kFMn1+Kv1Eq0cRjYW+4oBA1aEY/yDO2QtI= +github.com/gardener/hvpa-controller/api v0.15.0/go.mod h1:fqb4wNrQLESDKpm7ppXyCM2Gvx96wRlLL35aH0ge07U= +github.com/gardener/machine-controller-manager v0.53.0 h1:g2O0F7nEYZ9LjyPY6Gew8+q0n+rU88deexNq5k8CKks= +github.com/gardener/machine-controller-manager v0.53.0/go.mod h1:XWXHaTy32TU0qmLjWqOgtw8NncdB0HfFzXhUUrcpr7Y= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -166,40 +125,29 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -207,7 +155,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -218,11 +165,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -231,34 +173,20 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI= github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -271,13 +199,14 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -285,19 +214,14 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -317,13 +241,14 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= @@ -338,7 +263,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -346,57 +270,53 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 h1:AHzMWDxNiAVscJL6+4wkvFRTpMnJqiaZFEKA/osaBXE= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0/go.mod h1:wAR5JopumPtAZnu0Cjv2PSqV4p4QB09LMhc6fZZTXuA= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -405,62 +325,50 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= -go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -469,29 +377,20 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -501,61 +400,36 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -564,63 +438,40 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -638,48 +489,17 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -690,29 +510,12 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -721,54 +524,16 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 h1:9NWlQfY2ePejTmfwUH1OWwmznFa+0kKcHGPDvcPza9M= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -778,10 +543,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= +google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -803,92 +566,69 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +helm.sh/helm/v3 v3.14.4 h1:6FSpEfqyDalHq3kUr4gOMThhgY55kXUEjdQoyODYnrM= +helm.sh/helm/v3 v3.14.4/go.mod h1:Tje7LL4gprZpuBNTbG34d1Xn5NmRT3OWfBRwpOSer9I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -istio.io/api v1.19.2-0.20231011000955-f3015ebb5bd4 h1:NoiArVONh9DPs/DovhCCl771BUeEkKp+/GhsRB1YbOk= -istio.io/api v1.19.2-0.20231011000955-f3015ebb5bd4/go.mod h1:KstZe4bKbXouALUJ5PqpjNEhu5nj90HrDFitZfpNhlU= -istio.io/client-go v1.19.3 h1:nxNcBhtpJJmSoiTbCzO4Ay4Y1qve4Uct6oiqPSJVNMg= -istio.io/client-go v1.19.3/go.mod h1:ra3fVlXcquh7EuQnNssuLxfp6lFv/nx5314PvNEzOUs= -k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= -k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= +istio.io/api v1.22.2 h1:b02rTNfbnsEK2HMH/kfuXHTzovSmqcL5cAj2TSklPcQ= +istio.io/api v1.22.2/go.mod h1:S3l8LWqNYS9yT+d4bH+jqzH2lMencPkW7SKM1Cu9EyM= +istio.io/client-go v1.22.0 h1:TQ+Y7hqZVQHvaJXF99Q1jBqnVG7gYAHR9IvCK2nlwfE= +istio.io/client-go v1.22.0/go.mod h1:1lAPr0DOVBbnRQqLAQKxWbEaxFk6b1CJTm+ypnP7sMo= k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= -k8s.io/api v0.29.4 h1:WEnF/XdxuCxdG3ayHNRR8yH3cI1B/llkWBma6bq4R3w= -k8s.io/api v0.29.4/go.mod h1:DetSv0t4FBTcEpfA84NJV3g9a7+rSzlUHk5ADAYHUv0= -k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= -k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= -k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= -k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/api v0.29.6 h1:eDxIl8+PeEpwbe2YyS5RXJ9vdn4hnKWMBf4WUJP9DQM= +k8s.io/api v0.29.6/go.mod h1:ZuUPMhJV74DJXapldbg6upaHfiOjrBb+0ffUbBi1jaw= +k8s.io/apiextensions-apiserver v0.29.6 h1:tUu1N6Zt9GT8KVcPF5aGDqfISz1mveM4yFh7eL5bxmE= +k8s.io/apiextensions-apiserver v0.29.6/go.mod h1:iw1EbwZat08I219qrQKoFMHGo7J9KxPqMpVKxCbNbCs= k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= -k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q= -k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= -k8s.io/apiserver v0.28.3 h1:8Ov47O1cMyeDzTXz0rwcfIIGAP/dP7L8rWbEljRcg5w= -k8s.io/apiserver v0.28.3/go.mod h1:YIpM+9wngNAv8Ctt0rHG4vQuX/I5rvkEMtZtsxW2rNM= -k8s.io/autoscaler/vertical-pod-autoscaler v0.9.0/go.mod h1:PwWTGRRCxefhAezrDbG/tRYSAW7etHjjMPAr8fXKVAA= -k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0 h1:y0TgWoHaeYEv3L1MfLC+D2WVxyN1fGr6axURHXq+wHE= -k8s.io/autoscaler/vertical-pod-autoscaler v1.0.0/go.mod h1:w6/LjLR3DPQd57vlgvgbpzpuJKsCiily0+OzQI+nyfI= -k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/apimachinery v0.29.6 h1:CLjJ5b0hWW7531n/njRE3rnusw3rhVGCFftPfnG54CI= +k8s.io/apimachinery v0.29.6/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/autoscaler/vertical-pod-autoscaler v1.1.2 h1:ENxmnVXLt8+iXhDA0PNFhXb1sgvbvnAc66sC34UGrTw= +k8s.io/autoscaler/vertical-pod-autoscaler v1.1.2/go.mod h1:J2cNKnieE7r4bInjpQDBq93D50aD/CmspSi6xRUfKk4= k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU= -k8s.io/client-go v0.29.4 h1:79ytIedxVfyXV8rpH3jCBW0u+un0fxHDwX5F9K8dPR8= -k8s.io/client-go v0.29.4/go.mod h1:kC1thZQ4zQWYwldsfI088BbK6RkxK+aF5ebV8y9Q4tk= -k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/client-go v0.29.6 h1:5E2ebuB/p0F0THuQatyvhDvPL2SIeqwTPrtnrwKob/8= +k8s.io/client-go v0.29.6/go.mod h1:jHZcrQqDplyv20v7eu+iFM4gTpglZSZoMVcKrh8sRGg= k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= -k8s.io/code-generator v0.29.4 h1:8ESudFNbY5/9BzB8KOEFG2uV9Q0AQxkc4mrQESr30Ks= -k8s.io/code-generator v0.29.4/go.mod h1:7TYnI0dYItL2cKuhhgPSuF3WED9uMdELgbVXFfn/joE= -k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k= -k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= -k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/code-generator v0.29.6 h1:Z8T9VMR0mr7V5GG66c6GVAZrIiEy2uFoQwbeVeWLqPA= +k8s.io/code-generator v0.29.6/go.mod h1:7TYnI0dYItL2cKuhhgPSuF3WED9uMdELgbVXFfn/joE= +k8s.io/component-base v0.29.6 h1:XkVJI67FvBgNb/3kKqvaGKokxUrIR0RrksCPNI+JYCs= +k8s.io/component-base v0.29.6/go.mod h1:kIahZm8aw9lV8Vw17LF89REmeBrv5+QEl3v7HsrmITY= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao= -k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-aggregator v0.28.3 h1:CVbj3+cpshSHR5dWPzLYx3sVpIDEPLlzMSxY/lAc9cM= -k8s.io/kube-aggregator v0.28.3/go.mod h1:5DyLevbRTcWnT1f9b+lB3BfbXC1w7gDa/OtB6kKInCw= -k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-aggregator v0.29.6 h1:jZJjYF58F6kVuGC/kqLfuu7qGHqc2hoVKsDnRj26QRs= +k8s.io/kube-aggregator v0.29.6/go.mod h1:a6z0yORlXVXtGfsVB5PCjh2Soq1S7Wc6fApU6/T2eCE= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubelet v0.28.3 h1:bp/uIf1R5F61BlFvFtzc4PDEiK7TtFcw3wFJlc0V0LM= -k8s.io/kubelet v0.28.3/go.mod h1:E3NHYbp/v45Ao6AD0EOZnqO3L0R6Haks6Nm0+bnFwtU= -k8s.io/metrics v0.18.3/go.mod h1:TkuJE3ezDZ1ym8pYkZoEzJB7HDiFE7qxl+EmExEBoPA= -k8s.io/metrics v0.28.3 h1:w2s3kVi7HulXqCVDFkF4hN/OsL1tXTTb4Biif995h/g= -k8s.io/metrics v0.28.3/go.mod h1:OZZ23AHFojPzU6r3xoHGRUcV3I9pauLua+07sAUbwLc= -k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/kubelet v0.29.6 h1:jXnnBNHK/KNNEJesmlIZmCvlYC3a5/e04BIS9VPM49M= +k8s.io/kubelet v0.29.6/go.mod h1:kGEUqodVM120YTTQLSCTXzZP4XMFDp7qLf7iU3hrRE4= +k8s.io/metrics v0.29.6 h1:kjMGPYxtCi4OO0fUar76y0CiUoeGYDNmUV0LXJIis4Q= +k8s.io/metrics v0.29.6/go.mod h1:vqGzOaYGuNSSAI7GM1+v6L5z8aAUSzui1W0eQB3wVJY= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= +sigs.k8s.io/controller-runtime v0.17.5 h1:1FI9Lm7NiOOmBsgTV36/s2XrEFXnO2C4sbg/Zme72Rw= +sigs.k8s.io/controller-runtime v0.17.5/go.mod h1:N0jpP5Lo7lMTF9aL56Z/B2oWBJjey6StQM0jRbKQXtY= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231015215740-bf15e44028f9 h1:O27fSMHw4u0h+Rj8bNzcZk5jY0iZCO0J8/mCpigpnbw= sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20231015215740-bf15e44028f9/go.mod h1:TF/lVLWS+JNNaVqJuDDictY2hZSXSsIHCx4FClMvqFg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kind v0.17.0 h1:CScmGz/wX66puA06Gj8OZb76Wmk7JIjgWf5JDvY7msM= -sigs.k8s.io/kind v0.17.0/go.mod h1:Qqp8AiwOlMZmJWs37Hgs31xcbiYXjtXlRBSftcnZXQk= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/kind v0.20.0 h1:f0sc3v9mQbGnjBUaqSFST1dwIuiikKVGgoTwpoP33a8= +sigs.k8s.io/kind v0.20.0/go.mod h1:aBlbxg08cauDgZ612shr017/rZwqd7AS563FvpWKPVs= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hack/test.sh b/hack/test.sh index a53d9887..c362a077 100755 --- a/hack/test.sh +++ b/hack/test.sh @@ -16,4 +16,4 @@ export KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT=true # see https://github.com/kubernetes-sigs/controller-runtime/issues/1363 which remains unresolved. go test -json -cover ./controllers/cluster | gotestfmt -hide empty-packages go test -json -cover ./controllers/endpoint | gotestfmt -hide empty-packages -go test -json -cover `go list ./internal/... | grep -v mock | grep -v test` | gotestfmt -hide empty-packages +go test -json -cover `go list ./internal/... | grep -v fakes | grep -v test` | gotestfmt -hide empty-packages diff --git a/hack/tools.go b/hack/tools.go index 7f4de9d0..61e14f95 100644 --- a/hack/tools.go +++ b/hack/tools.go @@ -9,7 +9,6 @@ package tools import ( - _ "github.com/golang/mock/mockgen/model" _ "k8s.io/code-generator/cmd/import-boss" _ "sigs.k8s.io/controller-runtime/tools/setup-envtest" ) diff --git a/internal/docs/e2e-tests.md b/internal/docs/e2e-tests.md index 94cc231b..63292668 100644 --- a/internal/docs/e2e-tests.md +++ b/internal/docs/e2e-tests.md @@ -1,52 +1,85 @@ # End to End tests ## Table Of Contents - - [DWD prober](#dwd-prober) + +- [DWD prober](#dwd-prober) - [Setup](#setup) - - [Shooted-Seed](#shooted-seed) - - [Secret changes](#secret-changes) - - [Prober Config](#prober-config) + - [Shooted-Seed](#shooted-seed) + - [Secret changes](#secret-changes) + - [Prober Config](#prober-config) - [End-To-End Tests](#end-to-end-tests) - - [Weeder e2e tests](#weeder-e2e-tests) - +- [Weeder e2e tests](#weeder-e2e-tests) ## DWD prober -### Setup +### Setup To run these tests against a DEV cluster the following setup is required. #### Shooted-Seed -* Create a `shooted seed` setup by following running the script at [Gardener-Extensions-Setup](https://github.tools.sap/kubernetes/onboarding/blob/master/setup/localsetup/hacks/local-setup-extensions.sh) and deploy a local shoot in the shooted seed.(Use latest gardener version if possible) -* After the shoot is deployed, `annotate` the `managed resource` for DWD prober present in the `garden` namespace of the seed worker plane with the following: + +* Create a `shooted seed` setup by following running the script + at [Gardener-Extensions-Setup](https://github.tools.sap/kubernetes/onboarding/blob/master/setup/localsetup/hacks/local-setup-extensions.sh) + and deploy a local shoot in the shooted seed.(Use latest gardener version if possible) +* After the shoot is deployed, `annotate` the `managed resource` for DWD prober present in the `garden` namespace of the + seed worker plane with the following: + ```bash # This is required to ensure that `Dependency watchdog prober pods` are not scaled up during reconciliation of the shooted seed. kubectl -n garden annotate managedresource dependency-watchdog-probe resources.gardener.cloud/ignore=true --overwrite ``` -* Check the role/clusterrole for dependency-watchdog-prober in the `garden` namespace of the seed worker plane and add a `patch` verb for deployment/scale resource if not present. -* Check the role/rolebinding in the shoot for the dependency-watchdog-probe related service account in the `kube-system` namespace. Add rules for listing leases in the `kube-node-lease` namespace. -* Scale down the DWD prober deployment in the garden namespace (in the shooted-seed) and start a local DWD process by providing the prober config and the kubeconfig of the shooted seed as command line flags - ```bash go run ./dwd.go prober --config-file= --kubeconfig=```. To change the log level one can additionally pass `--zap-log-level=` command line flag which will be picked up zap logger at the time of initialization of DWD prober. -* Another way of running DWD is to change the image of the DWD deployment at `imagevector/images.yaml` in the cloned gardener repo used for the setup. (This needs to be done after the script checks out the desired gardener version and before `make gardener-extensions-up` is run) + +* Check the role/clusterrole for dependency-watchdog-prober in the `garden` namespace of the seed worker plane and add a + `patch` verb for deployment/scale resource if not present. +* Check the role/rolebinding in the shoot for the dependency-watchdog-probe related service account in the `kube-system` + namespace. Add rules for listing leases in the `kube-node-lease` namespace. +* Scale down the DWD prober deployment in the garden namespace (in the shooted-seed) and start a local DWD process by + providing the prober config and the kubeconfig of the shooted seed as command line flags - + ```bash go run ./dwd.go prober --config-file= --kubeconfig=```. + To change the log level one can additionally pass `--zap-log-level=` command line flag which will be picked + up zap logger at the time of initialization of DWD prober. +* Another way of running DWD is to change the image of the DWD deployment at `imagevector/images.yaml` in the cloned + gardener repo used for the setup. (This needs to be done after the script checks out the desired gardener version and + before `make gardener-extensions-up` is run) #### Secret changes -DWD API server probe leverages an `apiserver-probe-endpoint`(name might vary) to connect to the shoot Kube API server. API server probe DNS record points to an `in-cluster` endpoint which is only reachable from within the cluster. For tests that are run locally by starting a DWD prober process, the api server probe endpoint will have to be changed. This can be done in the following way: -> **NOTE:**
Create a new apiserver probe endpoint which is then reachable from the locally running DWD prober process. To do that you will have to the following: -> * Create a new `DNSRecord` containing the new shoot Kube API server endpoint. This will create a provider specific route (e.g. In case of AWS it will create a AWS-Route53 endpoint) -> * To ensure that a call to this endpoint is routed to the Kube API server of the shoot do the following: - > * Update Istio `Gateway` resource in the shoot namespace (E.g `kubectl get gateway -n kube-apiserver -oyaml`). Add the new endpoint to `spec.servers.hosts`. -> * Update Istio `VirtualService` resource in the shoot namespace (`k get virtualservice -n kube-apiserver -oyaml`). Add the new endpoints to `spec.hosts`, `spec.tls.match.sniHosts` +DWD API server probe leverages an `apiserver-probe-endpoint`(name might vary) to connect to the shoot Kube API server. +API server probe DNS record points to an `in-cluster` endpoint which is only reachable from within the cluster. For +tests that are run locally by starting a DWD prober process, the api server probe endpoint will have to be changed. This +can be done in the following way: +> **NOTE:**
Create a new apiserver probe endpoint which is then reachable from the locally running DWD prober +> process. To do that you will have to the following: +> * Create a new `DNSRecord` containing the new shoot Kube API server endpoint. This will create a provider specific + route (e.g. In case of AWS it will create a AWS-Route53 endpoint) +> * To ensure that a call to this endpoint is routed to the Kube API server of the shoot do the following: + > * Update Istio `Gateway` resource in the shoot namespace (E.g + `kubectl get gateway -n kube-apiserver -oyaml`). Add the new endpoint to `spec.servers.hosts`. + > + +* Update Istio `VirtualService` resource in the shoot namespace ( + `k get virtualservice -n kube-apiserver -oyaml`). Add the new endpoints to `spec.hosts`, + `spec.tls.match.sniHosts` + +* Modify the existing secret `shoot-access-dependency-watchdog-apiserver-probe`(name might vary) present in the + `shoot namespace` of the `shooted seed` cluster to use the new endpoint. + > NOTE: If you intend to modify the existing secret, it will be restored back to its original state after every shoot + reconciliation. The duration is set to 1 hour. You need to then re-apply your changes. +* Create a new secret with the changed endpoint and ensure that the prober configuration that you supply to the locally + running DWD prober process points to the new secret. + > NOTE: If you intend to use a new secret, ensure that the name should not end with + `dependency-watchdog-internal-probe` or `dependency-watchdog-external-probe` to prevent its automatic removal during + reconciliation of the shoot. + +For these tests, the API server probe uses the target url mentioned in the dns record `$SHOOTNAME-apiserver`(name might +vary). -* Modify the existing secret `shoot-access-dependency-watchdog-apiserver-probe`(name might vary) present in the `shoot namespace` of the `shooted seed` cluster to use the new endpoint. - > NOTE: If you intend to modify the existing secret, it will be restored back to its original state after every shoot reconciliation. The duration is set to 1 hour. You need to then re-apply your changes. -* Create a new secret with the changed endpoint and ensure that the prober configuration that you supply to the locally running DWD prober process points to the new secret. - > NOTE: If you intend to use a new secret, ensure that the name should not end with `dependency-watchdog-internal-probe` or `dependency-watchdog-external-probe` to prevent its automatic removal during reconciliation of the shoot. +#### Prober Config -For these tests, the API server probe uses the target url mentioned in the dns record `$SHOOTNAME-apiserver`(name might vary). +You can customize different configuration values by defining your own config file. Prober config used for these tests is +as follows (you can also use it as a template): -#### Prober Config -You can customize different configuration values by defining your own config file. Prober config used for these tests is as follows (you can also use it as a template): ```yaml kubeConfigSecretName: "shoot-access-dependency-watchdog-api-server-probe" # name of the secret can vary kcmNodeMonitorGraceDuration: 120s @@ -83,12 +116,17 @@ dependentResourceInfos: ### End-To-End Tests -End to End tests and their results are using the prober config as mentioned above. The order of scale up and scale down operations is controlled by the `level` defined for each resource under `scaleUp` and `scaleDown` configuration elements. -> NOTE: If you choose to have a different order of scale up/down then evaluate the test results according to the configured order. Below results as assuming the configuration defined above and should not be used as expectations start orders different from the one defined above. +End to End tests and their results are using the prober config as mentioned above. The order of scale up and scale down +operations is controlled by the `level` defined for each resource under `scaleUp` and `scaleDown` configuration +elements. +> NOTE: If you choose to have a different order of scale up/down then evaluate the test results according to the +> configured order. Below results as assuming the configuration defined above and should not be used as expectations +> start +> orders different from the one defined above. As per the above configuration scaling orders are as follows: -**Scale Up Order**: +**Scale Up Order**: `KCM` -> `MCM` -> `CA` **Scale Down Order**: @@ -96,35 +134,31 @@ As per the above configuration scaling orders are as follows: There are two types of end to end tests that were done: -1. Tests that can be automated as Integration tests -2. Tests that cannot be automated as Integration tests - -| # | Test | Result | -|:----|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 1 | scale down kcm and mcm | both probes pass and are healthy, scaling up operation starts, `CA` is skipped , `MCM` and `KCM` are scaled as per the order in the config. | -| 2 | update the API server probe secret by changing the server url so that it fails | API server probe fails, lease probe is skipped and any scaling of dependent resources is not done | -| 3 | API server probe is failing, change the secret back so that it succeeds | both the probes pass and scaling up happens according to the flow (skipped if replicas have min target replicas). | -| 4 | hibernate the shoot cluster after scale down operation has happened. | the prober is removed when hibernation is enabled, scaling up of any of the needed resources is done by the hibernation logic in gardener/gardener and it successfully hibernates the shoot | -| 5 | wake up the cluster from hibernation | new prober is added for the cluster only after the wake up process is successfully complete | -| 6 | shut down the kubelet of some nodes to cause the lease probe to fail | Lease probe fails, starts scaling down of resources. | -| 7 | Lease probe is failing, replace machines in `Unknown` state(or restart their kubelet) so that it succeeds | Both the probes pass, scaling up happens successfully. | -| 8 | Lease probe is failing, replace machines in `Unknown` state(or restart their kubelet) so that it succeeds and change the API server probe secret to use the wrong server url | API server probe fails, Lease probe is skipped and no scaling of dependent resources is done | -| 9 | set annotation `dependency-watchdog.gardener.cloud/ignore-scaling: true` one by one on `CA`, `KCM`, and `MCM` deployment. Do this for both the cases - Lease probe success and failure | In both the cases, the expected scaling operation is performed and the resources for which annotation is set to true, are not scaled. The other deployments are scaled as expected | -| 10 | Scale down the api-server deployment | API server probe fails, Lease probe is skipped and no scaling of dependent resources is done | -| 11 | Remove `KCM` deployment(mandatory resource) before any scale up/down is attempted. | The scale up/down flow fails to find `KCM` deployment and all retry attempts exhaust resulting in all downstream scale operations to not occur. | -| 12 | Change the `token` in the API server probe kubeconfig secret to get an error from API server probe. | API server probe fails, Lease probe is skipped and no scaling of dependent resources is done. | -| 13 | Remove the API server probe kubeconfig secret | API server probe is skipped as client could not be created, Lease probe is skipped and no scaling is done. | -| 14 | Delete the shoot from the local garden cluster | The prober is removed when the `DeletionTimestamp` is set. | -| 15 | Create a new shoot in the local garden cluster | The prober is added only after creation of shoot is successful. | -| 16 | Migrate shoot from one seed to another | prober is removed from the source seed as soon as migration starts. A new prober is started in the destination seed after restore is successful. | -| 17 | Start with 2 replicas for `KCM` deployment, scale it to 1 after scale down happens successfully, and then cause a scale up | Scale up of `KCM` will be skipped. | - -The above tests were done with replica count in some deployments as 2 to check that the replica count after scale up is as expected or not. +The below tests were done with replica count in MCM deployment as 2 to check that the replica count after scale up is as +expected or not. + +| # | Test | Result | +|----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | Create a new workerless shoot in the local garden cluster. | The prober is not added for the workeless shoot. | +| 2 | Create a cluster with min=max=1 for the worker. | The prober is added after shoot creation is successful. | +| 3 | Cluster is created successfully and in a healthy state (min=max=1). Delete the node lease in kube-node-lease ns | Scale out is done as no candidate leases are present. | +| 4 | Cluster is successfully created and in a healthy state (min=max=3). Scale down kcm and mcm deployments | `MCM` and `KCM` are scaled up as per the order in the config. | +| 5 | Cluster is successfully created and in a healthy state (min=max=3). Scale down the api-server deployment. | API server probe fails, Lease probe is skipped and no scaling of dependent resources is done. | +| 6 | Cluster is successfully created and in a healthy state (min=max=3). Update the API server probe secret by changing the server url so that it fails. Once the probe fails, update the secret back to its original state | API server probe fails, lease probe is skipped and scaling of dependent resources is not done. Once the secret is reverted, API server probe will succeed. | +| 7 | Cluster is successfully created and in a healthy state (min=max=3). Set annotation `dependency-watchdog.gardener.cloud/ignore-scaling: true` on `MCM` deployment. | The expected scaling operation is performed and the resources for which annotation is set to true, are not scaled. The other deployments are scaled as expected | +| 8 | Cluster is successfully created and in a healthy state (min=max=3). Block outbound traffic from shoot. This will cause leases to not be renewed. Later unblock the outbound traffic from the shoot. | Lease probe fails, dependent resources are scaled down. Once outbound traffic is unblocked Lease probe succeeds and scales up dependent resources. | +| 9 | Cluster is successfully created and in a healthy state (min=max=3). Annotate two nodes with `node.machine.sapcloud.io/not-managed-by-mcm: true`. | No scaling is done as there is only one candidate lease present (unmanaged nodes are ignored by DWD). | +| 10 | Cluster is successfully created and in a healthy state (min=max=3). Delete 2 machines. This will result in the cluster having `2 machines in `Terminating` State, 2 in `Pending` state and `1` in Running state. | The prober will ignore `Terminating` machines and not perform any scaling operation as there is only 1 candidate lease in the cluster. (`Pending` machines have no registered nodes yet.) | +| 11 | Cluster is successfully created and in a healthy state (min=max=3). Hibernate the shoot cluster. Wake up the cluster after hibernation is successful. | The prober is removed when hibernation is enabled, scaling up of any of the needed resources is done by the hibernation logic in gardener/gardener and it successfully hibernates the shoot. New prober will be added only after cluster successfully wakes up. | +| 12 | Cluster is successfully created and in a healthy state (min=max=3). Define `MemoryPressure` nodeCondition in `machineControllerSettings` for the worker. Cause `MemoryPressure` on 2 nodes. | The prober will ignore nodes with `MemoryPressure` and not perform any scaling operation as there is only 1 candidate lease in the cluster. | +| 13 | Migrate shoot from one seed to another | The prober is removed from the source seed as soon as migration starts. A new prober is started in the destination seed after restore is successful. | +| 14 | Delete the shoot from the local garden cluster | The prober is removed when the `DeletionTimestamp` is set. | ## Weeder e2e tests -| # | Test | Result | -|:----|:--------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 1 | scale down api server | weeder is not started as no endpoint subset would be ready | -| 2 | scaled up api server after scale down | dependent pods like KCM , kube-scheduler which go in `CrashLoopBackOff` are restarted | -| 3 | scale down etcd | weeder is not started as no endpoint subset would be ready | -| 4 | scale up etcd after scale down | weeder for `etcd` endpoint started which restarted `kube-apiserver` and then weeder started for `kube-apiserver` which restarted its dependent `CrashloopBackoff` pods | + +| # | Test | Result | +|:--|:--------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | scale down api server | weeder is not started as no endpoint subset would be ready | +| 2 | scaled up api server after scale down | dependent pods like KCM , kube-scheduler which go in `CrashLoopBackOff` are restarted | +| 3 | scale down etcd | weeder is not started as no endpoint subset would be ready | +| 4 | scale up etcd after scale down | weeder for `etcd` endpoint started which restarted `kube-apiserver` and then weeder started for `kube-apiserver` which restarted its dependent `CrashloopBackoff` pods | diff --git a/internal/mock/client-go/discovery/doc.go b/internal/mock/client-go/discovery/doc.go deleted file mode 100644 index 809139be..00000000 --- a/internal/mock/client-go/discovery/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package discovery -destination=mocks.go k8s.io/client-go/discovery DiscoveryInterface -package discovery diff --git a/internal/mock/client-go/discovery/mocks.go b/internal/mock/client-go/discovery/mocks.go deleted file mode 100644 index 587bbfe4..00000000 --- a/internal/mock/client-go/discovery/mocks.go +++ /dev/null @@ -1,188 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: k8s.io/client-go/discovery (interfaces: DiscoveryInterface) - -// Package discovery is a generated GoMock package. -package discovery - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - openapi_v2 "github.com/google/gnostic-models/openapiv2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - version "k8s.io/apimachinery/pkg/version" - discovery "k8s.io/client-go/discovery" - openapi "k8s.io/client-go/openapi" - rest "k8s.io/client-go/rest" -) - -// MockDiscoveryInterface is a mock of DiscoveryInterface interface. -type MockDiscoveryInterface struct { - ctrl *gomock.Controller - recorder *MockDiscoveryInterfaceMockRecorder -} - -// MockDiscoveryInterfaceMockRecorder is the mock recorder for MockDiscoveryInterface. -type MockDiscoveryInterfaceMockRecorder struct { - mock *MockDiscoveryInterface -} - -// NewMockDiscoveryInterface creates a new mock instance. -func NewMockDiscoveryInterface(ctrl *gomock.Controller) *MockDiscoveryInterface { - mock := &MockDiscoveryInterface{ctrl: ctrl} - mock.recorder = &MockDiscoveryInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDiscoveryInterface) EXPECT() *MockDiscoveryInterfaceMockRecorder { - return m.recorder -} - -// OpenAPISchema mocks base method. -func (m *MockDiscoveryInterface) OpenAPISchema() (*openapi_v2.Document, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OpenAPISchema") - ret0, _ := ret[0].(*openapi_v2.Document) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// OpenAPISchema indicates an expected call of OpenAPISchema. -func (mr *MockDiscoveryInterfaceMockRecorder) OpenAPISchema() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenAPISchema", reflect.TypeOf((*MockDiscoveryInterface)(nil).OpenAPISchema)) -} - -// OpenAPIV3 mocks base method. -func (m *MockDiscoveryInterface) OpenAPIV3() openapi.Client { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OpenAPIV3") - ret0, _ := ret[0].(openapi.Client) - return ret0 -} - -// OpenAPIV3 indicates an expected call of OpenAPIV3. -func (mr *MockDiscoveryInterfaceMockRecorder) OpenAPIV3() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenAPIV3", reflect.TypeOf((*MockDiscoveryInterface)(nil).OpenAPIV3)) -} - -// RESTClient mocks base method. -func (m *MockDiscoveryInterface) RESTClient() rest.Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RESTClient") - ret0, _ := ret[0].(rest.Interface) - return ret0 -} - -// RESTClient indicates an expected call of RESTClient. -func (mr *MockDiscoveryInterfaceMockRecorder) RESTClient() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTClient", reflect.TypeOf((*MockDiscoveryInterface)(nil).RESTClient)) -} - -// ServerGroups mocks base method. -func (m *MockDiscoveryInterface) ServerGroups() (*v1.APIGroupList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerGroups") - ret0, _ := ret[0].(*v1.APIGroupList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerGroups indicates an expected call of ServerGroups. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerGroups() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerGroups", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerGroups)) -} - -// ServerGroupsAndResources mocks base method. -func (m *MockDiscoveryInterface) ServerGroupsAndResources() ([]*v1.APIGroup, []*v1.APIResourceList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerGroupsAndResources") - ret0, _ := ret[0].([]*v1.APIGroup) - ret1, _ := ret[1].([]*v1.APIResourceList) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// ServerGroupsAndResources indicates an expected call of ServerGroupsAndResources. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerGroupsAndResources() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerGroupsAndResources", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerGroupsAndResources)) -} - -// ServerPreferredNamespacedResources mocks base method. -func (m *MockDiscoveryInterface) ServerPreferredNamespacedResources() ([]*v1.APIResourceList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerPreferredNamespacedResources") - ret0, _ := ret[0].([]*v1.APIResourceList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerPreferredNamespacedResources indicates an expected call of ServerPreferredNamespacedResources. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerPreferredNamespacedResources() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerPreferredNamespacedResources", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerPreferredNamespacedResources)) -} - -// ServerPreferredResources mocks base method. -func (m *MockDiscoveryInterface) ServerPreferredResources() ([]*v1.APIResourceList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerPreferredResources") - ret0, _ := ret[0].([]*v1.APIResourceList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerPreferredResources indicates an expected call of ServerPreferredResources. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerPreferredResources() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerPreferredResources", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerPreferredResources)) -} - -// ServerResourcesForGroupVersion mocks base method. -func (m *MockDiscoveryInterface) ServerResourcesForGroupVersion(arg0 string) (*v1.APIResourceList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerResourcesForGroupVersion", arg0) - ret0, _ := ret[0].(*v1.APIResourceList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerResourcesForGroupVersion indicates an expected call of ServerResourcesForGroupVersion. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerResourcesForGroupVersion(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerResourcesForGroupVersion", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerResourcesForGroupVersion), arg0) -} - -// ServerVersion mocks base method. -func (m *MockDiscoveryInterface) ServerVersion() (*version.Info, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServerVersion") - ret0, _ := ret[0].(*version.Info) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ServerVersion indicates an expected call of ServerVersion. -func (mr *MockDiscoveryInterfaceMockRecorder) ServerVersion() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerVersion", reflect.TypeOf((*MockDiscoveryInterface)(nil).ServerVersion)) -} - -// WithLegacy mocks base method. -func (m *MockDiscoveryInterface) WithLegacy() discovery.DiscoveryInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WithLegacy") - ret0, _ := ret[0].(discovery.DiscoveryInterface) - return ret0 -} - -// WithLegacy indicates an expected call of WithLegacy. -func (mr *MockDiscoveryInterfaceMockRecorder) WithLegacy() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithLegacy", reflect.TypeOf((*MockDiscoveryInterface)(nil).WithLegacy)) -} diff --git a/internal/mock/client-go/kubernetes/coordinationv1/doc.go b/internal/mock/client-go/kubernetes/coordinationv1/doc.go deleted file mode 100644 index d4d9343f..00000000 --- a/internal/mock/client-go/kubernetes/coordinationv1/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package coordinationv1 -destination=mocks.go k8s.io/client-go/kubernetes/typed/coordination/v1 CoordinationV1Interface,LeaseInterface -package coordinationv1 diff --git a/internal/mock/client-go/kubernetes/coordinationv1/mocks.go b/internal/mock/client-go/kubernetes/coordinationv1/mocks.go deleted file mode 100644 index 3170d961..00000000 --- a/internal/mock/client-go/kubernetes/coordinationv1/mocks.go +++ /dev/null @@ -1,231 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: k8s.io/client-go/kubernetes/typed/coordination/v1 (interfaces: CoordinationV1Interface,LeaseInterface) - -// Package coordinationv1 is a generated GoMock package. -package coordinationv1 - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - v1 "k8s.io/api/coordination/v1" - v10 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - v11 "k8s.io/client-go/applyconfigurations/coordination/v1" - v12 "k8s.io/client-go/kubernetes/typed/coordination/v1" - rest "k8s.io/client-go/rest" -) - -// MockCoordinationV1Interface is a mock of CoordinationV1Interface interface. -type MockCoordinationV1Interface struct { - ctrl *gomock.Controller - recorder *MockCoordinationV1InterfaceMockRecorder -} - -// MockCoordinationV1InterfaceMockRecorder is the mock recorder for MockCoordinationV1Interface. -type MockCoordinationV1InterfaceMockRecorder struct { - mock *MockCoordinationV1Interface -} - -// NewMockCoordinationV1Interface creates a new mock instance. -func NewMockCoordinationV1Interface(ctrl *gomock.Controller) *MockCoordinationV1Interface { - mock := &MockCoordinationV1Interface{ctrl: ctrl} - mock.recorder = &MockCoordinationV1InterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockCoordinationV1Interface) EXPECT() *MockCoordinationV1InterfaceMockRecorder { - return m.recorder -} - -// Leases mocks base method. -func (m *MockCoordinationV1Interface) Leases(arg0 string) v12.LeaseInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Leases", arg0) - ret0, _ := ret[0].(v12.LeaseInterface) - return ret0 -} - -// Leases indicates an expected call of Leases. -func (mr *MockCoordinationV1InterfaceMockRecorder) Leases(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Leases", reflect.TypeOf((*MockCoordinationV1Interface)(nil).Leases), arg0) -} - -// RESTClient mocks base method. -func (m *MockCoordinationV1Interface) RESTClient() rest.Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RESTClient") - ret0, _ := ret[0].(rest.Interface) - return ret0 -} - -// RESTClient indicates an expected call of RESTClient. -func (mr *MockCoordinationV1InterfaceMockRecorder) RESTClient() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTClient", reflect.TypeOf((*MockCoordinationV1Interface)(nil).RESTClient)) -} - -// MockLeaseInterface is a mock of LeaseInterface interface. -type MockLeaseInterface struct { - ctrl *gomock.Controller - recorder *MockLeaseInterfaceMockRecorder -} - -// MockLeaseInterfaceMockRecorder is the mock recorder for MockLeaseInterface. -type MockLeaseInterfaceMockRecorder struct { - mock *MockLeaseInterface -} - -// NewMockLeaseInterface creates a new mock instance. -func NewMockLeaseInterface(ctrl *gomock.Controller) *MockLeaseInterface { - mock := &MockLeaseInterface{ctrl: ctrl} - mock.recorder = &MockLeaseInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockLeaseInterface) EXPECT() *MockLeaseInterfaceMockRecorder { - return m.recorder -} - -// Apply mocks base method. -func (m *MockLeaseInterface) Apply(arg0 context.Context, arg1 *v11.LeaseApplyConfiguration, arg2 v10.ApplyOptions) (*v1.Lease, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Lease) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Apply indicates an expected call of Apply. -func (mr *MockLeaseInterfaceMockRecorder) Apply(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockLeaseInterface)(nil).Apply), arg0, arg1, arg2) -} - -// Create mocks base method. -func (m *MockLeaseInterface) Create(arg0 context.Context, arg1 *v1.Lease, arg2 v10.CreateOptions) (*v1.Lease, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Lease) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Create indicates an expected call of Create. -func (mr *MockLeaseInterfaceMockRecorder) Create(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockLeaseInterface)(nil).Create), arg0, arg1, arg2) -} - -// Delete mocks base method. -func (m *MockLeaseInterface) Delete(arg0 context.Context, arg1 string, arg2 v10.DeleteOptions) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// Delete indicates an expected call of Delete. -func (mr *MockLeaseInterfaceMockRecorder) Delete(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockLeaseInterface)(nil).Delete), arg0, arg1, arg2) -} - -// DeleteCollection mocks base method. -func (m *MockLeaseInterface) DeleteCollection(arg0 context.Context, arg1 v10.DeleteOptions, arg2 v10.ListOptions) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteCollection", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteCollection indicates an expected call of DeleteCollection. -func (mr *MockLeaseInterfaceMockRecorder) DeleteCollection(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCollection", reflect.TypeOf((*MockLeaseInterface)(nil).DeleteCollection), arg0, arg1, arg2) -} - -// Get mocks base method. -func (m *MockLeaseInterface) Get(arg0 context.Context, arg1 string, arg2 v10.GetOptions) (*v1.Lease, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Lease) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get. -func (mr *MockLeaseInterfaceMockRecorder) Get(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockLeaseInterface)(nil).Get), arg0, arg1, arg2) -} - -// List mocks base method. -func (m *MockLeaseInterface) List(arg0 context.Context, arg1 v10.ListOptions) (*v1.LeaseList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", arg0, arg1) - ret0, _ := ret[0].(*v1.LeaseList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// List indicates an expected call of List. -func (mr *MockLeaseInterfaceMockRecorder) List(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockLeaseInterface)(nil).List), arg0, arg1) -} - -// Patch mocks base method. -func (m *MockLeaseInterface) Patch(arg0 context.Context, arg1 string, arg2 types.PatchType, arg3 []byte, arg4 v10.PatchOptions, arg5 ...string) (*v1.Lease, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3, arg4} - for _, a := range arg5 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Patch", varargs...) - ret0, _ := ret[0].(*v1.Lease) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Patch indicates an expected call of Patch. -func (mr *MockLeaseInterfaceMockRecorder) Patch(arg0, arg1, arg2, arg3, arg4 interface{}, arg5 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4}, arg5...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Patch", reflect.TypeOf((*MockLeaseInterface)(nil).Patch), varargs...) -} - -// Update mocks base method. -func (m *MockLeaseInterface) Update(arg0 context.Context, arg1 *v1.Lease, arg2 v10.UpdateOptions) (*v1.Lease, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Lease) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Update indicates an expected call of Update. -func (mr *MockLeaseInterfaceMockRecorder) Update(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockLeaseInterface)(nil).Update), arg0, arg1, arg2) -} - -// Watch mocks base method. -func (m *MockLeaseInterface) Watch(arg0 context.Context, arg1 v10.ListOptions) (watch.Interface, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Watch", arg0, arg1) - ret0, _ := ret[0].(watch.Interface) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Watch indicates an expected call of Watch. -func (mr *MockLeaseInterfaceMockRecorder) Watch(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockLeaseInterface)(nil).Watch), arg0, arg1) -} diff --git a/internal/mock/client-go/kubernetes/corev1/doc.go b/internal/mock/client-go/kubernetes/corev1/doc.go deleted file mode 100644 index 5878e94d..00000000 --- a/internal/mock/client-go/kubernetes/corev1/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package corev1 -destination=mocks.go k8s.io/client-go/kubernetes/typed/core/v1 CoreV1Interface,NodeInterface -package corev1 diff --git a/internal/mock/client-go/kubernetes/corev1/mocks.go b/internal/mock/client-go/kubernetes/corev1/mocks.go deleted file mode 100644 index 4d485415..00000000 --- a/internal/mock/client-go/kubernetes/corev1/mocks.go +++ /dev/null @@ -1,486 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: k8s.io/client-go/kubernetes/typed/core/v1 (interfaces: CoreV1Interface,NodeInterface) - -// Package corev1 is a generated GoMock package. -package corev1 - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - v1 "k8s.io/api/core/v1" - v10 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - v11 "k8s.io/client-go/applyconfigurations/core/v1" - v12 "k8s.io/client-go/kubernetes/typed/core/v1" - rest "k8s.io/client-go/rest" -) - -// MockCoreV1Interface is a mock of CoreV1Interface interface. -type MockCoreV1Interface struct { - ctrl *gomock.Controller - recorder *MockCoreV1InterfaceMockRecorder -} - -// MockCoreV1InterfaceMockRecorder is the mock recorder for MockCoreV1Interface. -type MockCoreV1InterfaceMockRecorder struct { - mock *MockCoreV1Interface -} - -// NewMockCoreV1Interface creates a new mock instance. -func NewMockCoreV1Interface(ctrl *gomock.Controller) *MockCoreV1Interface { - mock := &MockCoreV1Interface{ctrl: ctrl} - mock.recorder = &MockCoreV1InterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockCoreV1Interface) EXPECT() *MockCoreV1InterfaceMockRecorder { - return m.recorder -} - -// ComponentStatuses mocks base method. -func (m *MockCoreV1Interface) ComponentStatuses() v12.ComponentStatusInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ComponentStatuses") - ret0, _ := ret[0].(v12.ComponentStatusInterface) - return ret0 -} - -// ComponentStatuses indicates an expected call of ComponentStatuses. -func (mr *MockCoreV1InterfaceMockRecorder) ComponentStatuses() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ComponentStatuses", reflect.TypeOf((*MockCoreV1Interface)(nil).ComponentStatuses)) -} - -// ConfigMaps mocks base method. -func (m *MockCoreV1Interface) ConfigMaps(arg0 string) v12.ConfigMapInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ConfigMaps", arg0) - ret0, _ := ret[0].(v12.ConfigMapInterface) - return ret0 -} - -// ConfigMaps indicates an expected call of ConfigMaps. -func (mr *MockCoreV1InterfaceMockRecorder) ConfigMaps(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigMaps", reflect.TypeOf((*MockCoreV1Interface)(nil).ConfigMaps), arg0) -} - -// Endpoints mocks base method. -func (m *MockCoreV1Interface) Endpoints(arg0 string) v12.EndpointsInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Endpoints", arg0) - ret0, _ := ret[0].(v12.EndpointsInterface) - return ret0 -} - -// Endpoints indicates an expected call of Endpoints. -func (mr *MockCoreV1InterfaceMockRecorder) Endpoints(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Endpoints", reflect.TypeOf((*MockCoreV1Interface)(nil).Endpoints), arg0) -} - -// Events mocks base method. -func (m *MockCoreV1Interface) Events(arg0 string) v12.EventInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Events", arg0) - ret0, _ := ret[0].(v12.EventInterface) - return ret0 -} - -// Events indicates an expected call of Events. -func (mr *MockCoreV1InterfaceMockRecorder) Events(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Events", reflect.TypeOf((*MockCoreV1Interface)(nil).Events), arg0) -} - -// LimitRanges mocks base method. -func (m *MockCoreV1Interface) LimitRanges(arg0 string) v12.LimitRangeInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LimitRanges", arg0) - ret0, _ := ret[0].(v12.LimitRangeInterface) - return ret0 -} - -// LimitRanges indicates an expected call of LimitRanges. -func (mr *MockCoreV1InterfaceMockRecorder) LimitRanges(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LimitRanges", reflect.TypeOf((*MockCoreV1Interface)(nil).LimitRanges), arg0) -} - -// Namespaces mocks base method. -func (m *MockCoreV1Interface) Namespaces() v12.NamespaceInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Namespaces") - ret0, _ := ret[0].(v12.NamespaceInterface) - return ret0 -} - -// Namespaces indicates an expected call of Namespaces. -func (mr *MockCoreV1InterfaceMockRecorder) Namespaces() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Namespaces", reflect.TypeOf((*MockCoreV1Interface)(nil).Namespaces)) -} - -// Nodes mocks base method. -func (m *MockCoreV1Interface) Nodes() v12.NodeInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Nodes") - ret0, _ := ret[0].(v12.NodeInterface) - return ret0 -} - -// Nodes indicates an expected call of Nodes. -func (mr *MockCoreV1InterfaceMockRecorder) Nodes() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Nodes", reflect.TypeOf((*MockCoreV1Interface)(nil).Nodes)) -} - -// PersistentVolumeClaims mocks base method. -func (m *MockCoreV1Interface) PersistentVolumeClaims(arg0 string) v12.PersistentVolumeClaimInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PersistentVolumeClaims", arg0) - ret0, _ := ret[0].(v12.PersistentVolumeClaimInterface) - return ret0 -} - -// PersistentVolumeClaims indicates an expected call of PersistentVolumeClaims. -func (mr *MockCoreV1InterfaceMockRecorder) PersistentVolumeClaims(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistentVolumeClaims", reflect.TypeOf((*MockCoreV1Interface)(nil).PersistentVolumeClaims), arg0) -} - -// PersistentVolumes mocks base method. -func (m *MockCoreV1Interface) PersistentVolumes() v12.PersistentVolumeInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PersistentVolumes") - ret0, _ := ret[0].(v12.PersistentVolumeInterface) - return ret0 -} - -// PersistentVolumes indicates an expected call of PersistentVolumes. -func (mr *MockCoreV1InterfaceMockRecorder) PersistentVolumes() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistentVolumes", reflect.TypeOf((*MockCoreV1Interface)(nil).PersistentVolumes)) -} - -// PodTemplates mocks base method. -func (m *MockCoreV1Interface) PodTemplates(arg0 string) v12.PodTemplateInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PodTemplates", arg0) - ret0, _ := ret[0].(v12.PodTemplateInterface) - return ret0 -} - -// PodTemplates indicates an expected call of PodTemplates. -func (mr *MockCoreV1InterfaceMockRecorder) PodTemplates(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PodTemplates", reflect.TypeOf((*MockCoreV1Interface)(nil).PodTemplates), arg0) -} - -// Pods mocks base method. -func (m *MockCoreV1Interface) Pods(arg0 string) v12.PodInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Pods", arg0) - ret0, _ := ret[0].(v12.PodInterface) - return ret0 -} - -// Pods indicates an expected call of Pods. -func (mr *MockCoreV1InterfaceMockRecorder) Pods(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pods", reflect.TypeOf((*MockCoreV1Interface)(nil).Pods), arg0) -} - -// RESTClient mocks base method. -func (m *MockCoreV1Interface) RESTClient() rest.Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RESTClient") - ret0, _ := ret[0].(rest.Interface) - return ret0 -} - -// RESTClient indicates an expected call of RESTClient. -func (mr *MockCoreV1InterfaceMockRecorder) RESTClient() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTClient", reflect.TypeOf((*MockCoreV1Interface)(nil).RESTClient)) -} - -// ReplicationControllers mocks base method. -func (m *MockCoreV1Interface) ReplicationControllers(arg0 string) v12.ReplicationControllerInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReplicationControllers", arg0) - ret0, _ := ret[0].(v12.ReplicationControllerInterface) - return ret0 -} - -// ReplicationControllers indicates an expected call of ReplicationControllers. -func (mr *MockCoreV1InterfaceMockRecorder) ReplicationControllers(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicationControllers", reflect.TypeOf((*MockCoreV1Interface)(nil).ReplicationControllers), arg0) -} - -// ResourceQuotas mocks base method. -func (m *MockCoreV1Interface) ResourceQuotas(arg0 string) v12.ResourceQuotaInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResourceQuotas", arg0) - ret0, _ := ret[0].(v12.ResourceQuotaInterface) - return ret0 -} - -// ResourceQuotas indicates an expected call of ResourceQuotas. -func (mr *MockCoreV1InterfaceMockRecorder) ResourceQuotas(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResourceQuotas", reflect.TypeOf((*MockCoreV1Interface)(nil).ResourceQuotas), arg0) -} - -// Secrets mocks base method. -func (m *MockCoreV1Interface) Secrets(arg0 string) v12.SecretInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Secrets", arg0) - ret0, _ := ret[0].(v12.SecretInterface) - return ret0 -} - -// Secrets indicates an expected call of Secrets. -func (mr *MockCoreV1InterfaceMockRecorder) Secrets(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Secrets", reflect.TypeOf((*MockCoreV1Interface)(nil).Secrets), arg0) -} - -// ServiceAccounts mocks base method. -func (m *MockCoreV1Interface) ServiceAccounts(arg0 string) v12.ServiceAccountInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ServiceAccounts", arg0) - ret0, _ := ret[0].(v12.ServiceAccountInterface) - return ret0 -} - -// ServiceAccounts indicates an expected call of ServiceAccounts. -func (mr *MockCoreV1InterfaceMockRecorder) ServiceAccounts(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceAccounts", reflect.TypeOf((*MockCoreV1Interface)(nil).ServiceAccounts), arg0) -} - -// Services mocks base method. -func (m *MockCoreV1Interface) Services(arg0 string) v12.ServiceInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Services", arg0) - ret0, _ := ret[0].(v12.ServiceInterface) - return ret0 -} - -// Services indicates an expected call of Services. -func (mr *MockCoreV1InterfaceMockRecorder) Services(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Services", reflect.TypeOf((*MockCoreV1Interface)(nil).Services), arg0) -} - -// MockNodeInterface is a mock of NodeInterface interface. -type MockNodeInterface struct { - ctrl *gomock.Controller - recorder *MockNodeInterfaceMockRecorder -} - -// MockNodeInterfaceMockRecorder is the mock recorder for MockNodeInterface. -type MockNodeInterfaceMockRecorder struct { - mock *MockNodeInterface -} - -// NewMockNodeInterface creates a new mock instance. -func NewMockNodeInterface(ctrl *gomock.Controller) *MockNodeInterface { - mock := &MockNodeInterface{ctrl: ctrl} - mock.recorder = &MockNodeInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockNodeInterface) EXPECT() *MockNodeInterfaceMockRecorder { - return m.recorder -} - -// Apply mocks base method. -func (m *MockNodeInterface) Apply(arg0 context.Context, arg1 *v11.NodeApplyConfiguration, arg2 v10.ApplyOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Apply indicates an expected call of Apply. -func (mr *MockNodeInterfaceMockRecorder) Apply(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockNodeInterface)(nil).Apply), arg0, arg1, arg2) -} - -// ApplyStatus mocks base method. -func (m *MockNodeInterface) ApplyStatus(arg0 context.Context, arg1 *v11.NodeApplyConfiguration, arg2 v10.ApplyOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyStatus", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ApplyStatus indicates an expected call of ApplyStatus. -func (mr *MockNodeInterfaceMockRecorder) ApplyStatus(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyStatus", reflect.TypeOf((*MockNodeInterface)(nil).ApplyStatus), arg0, arg1, arg2) -} - -// Create mocks base method. -func (m *MockNodeInterface) Create(arg0 context.Context, arg1 *v1.Node, arg2 v10.CreateOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Create indicates an expected call of Create. -func (mr *MockNodeInterfaceMockRecorder) Create(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockNodeInterface)(nil).Create), arg0, arg1, arg2) -} - -// Delete mocks base method. -func (m *MockNodeInterface) Delete(arg0 context.Context, arg1 string, arg2 v10.DeleteOptions) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// Delete indicates an expected call of Delete. -func (mr *MockNodeInterfaceMockRecorder) Delete(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockNodeInterface)(nil).Delete), arg0, arg1, arg2) -} - -// DeleteCollection mocks base method. -func (m *MockNodeInterface) DeleteCollection(arg0 context.Context, arg1 v10.DeleteOptions, arg2 v10.ListOptions) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteCollection", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteCollection indicates an expected call of DeleteCollection. -func (mr *MockNodeInterfaceMockRecorder) DeleteCollection(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCollection", reflect.TypeOf((*MockNodeInterface)(nil).DeleteCollection), arg0, arg1, arg2) -} - -// Get mocks base method. -func (m *MockNodeInterface) Get(arg0 context.Context, arg1 string, arg2 v10.GetOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get. -func (mr *MockNodeInterfaceMockRecorder) Get(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockNodeInterface)(nil).Get), arg0, arg1, arg2) -} - -// List mocks base method. -func (m *MockNodeInterface) List(arg0 context.Context, arg1 v10.ListOptions) (*v1.NodeList, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", arg0, arg1) - ret0, _ := ret[0].(*v1.NodeList) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// List indicates an expected call of List. -func (mr *MockNodeInterfaceMockRecorder) List(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockNodeInterface)(nil).List), arg0, arg1) -} - -// Patch mocks base method. -func (m *MockNodeInterface) Patch(arg0 context.Context, arg1 string, arg2 types.PatchType, arg3 []byte, arg4 v10.PatchOptions, arg5 ...string) (*v1.Node, error) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2, arg3, arg4} - for _, a := range arg5 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Patch", varargs...) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Patch indicates an expected call of Patch. -func (mr *MockNodeInterfaceMockRecorder) Patch(arg0, arg1, arg2, arg3, arg4 interface{}, arg5 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2, arg3, arg4}, arg5...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Patch", reflect.TypeOf((*MockNodeInterface)(nil).Patch), varargs...) -} - -// PatchStatus mocks base method. -func (m *MockNodeInterface) PatchStatus(arg0 context.Context, arg1 string, arg2 []byte) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PatchStatus", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PatchStatus indicates an expected call of PatchStatus. -func (mr *MockNodeInterfaceMockRecorder) PatchStatus(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchStatus", reflect.TypeOf((*MockNodeInterface)(nil).PatchStatus), arg0, arg1, arg2) -} - -// Update mocks base method. -func (m *MockNodeInterface) Update(arg0 context.Context, arg1 *v1.Node, arg2 v10.UpdateOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Update indicates an expected call of Update. -func (mr *MockNodeInterfaceMockRecorder) Update(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockNodeInterface)(nil).Update), arg0, arg1, arg2) -} - -// UpdateStatus mocks base method. -func (m *MockNodeInterface) UpdateStatus(arg0 context.Context, arg1 *v1.Node, arg2 v10.UpdateOptions) (*v1.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateStatus", arg0, arg1, arg2) - ret0, _ := ret[0].(*v1.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UpdateStatus indicates an expected call of UpdateStatus. -func (mr *MockNodeInterfaceMockRecorder) UpdateStatus(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStatus", reflect.TypeOf((*MockNodeInterface)(nil).UpdateStatus), arg0, arg1, arg2) -} - -// Watch mocks base method. -func (m *MockNodeInterface) Watch(arg0 context.Context, arg1 v10.ListOptions) (watch.Interface, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Watch", arg0, arg1) - ret0, _ := ret[0].(watch.Interface) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Watch indicates an expected call of Watch. -func (mr *MockNodeInterfaceMockRecorder) Watch(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockNodeInterface)(nil).Watch), arg0, arg1) -} diff --git a/internal/mock/client-go/kubernetes/doc.go b/internal/mock/client-go/kubernetes/doc.go deleted file mode 100644 index 1646c9a1..00000000 --- a/internal/mock/client-go/kubernetes/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package kubernetes -destination=mocks.go k8s.io/client-go/kubernetes Interface -package kubernetes diff --git a/internal/mock/client-go/kubernetes/mocks.go b/internal/mock/client-go/kubernetes/mocks.go deleted file mode 100644 index 3d46e296..00000000 --- a/internal/mock/client-go/kubernetes/mocks.go +++ /dev/null @@ -1,814 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: k8s.io/client-go/kubernetes (interfaces: Interface) - -// Package kubernetes is a generated GoMock package. -package kubernetes - -import ( - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - discovery "k8s.io/client-go/discovery" - v1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" - v1alpha1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1" - v1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1" - v1alpha10 "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1" - v10 "k8s.io/client-go/kubernetes/typed/apps/v1" - v1beta10 "k8s.io/client-go/kubernetes/typed/apps/v1beta1" - v1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" - v11 "k8s.io/client-go/kubernetes/typed/authentication/v1" - v1alpha11 "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1" - v1beta11 "k8s.io/client-go/kubernetes/typed/authentication/v1beta1" - v12 "k8s.io/client-go/kubernetes/typed/authorization/v1" - v1beta12 "k8s.io/client-go/kubernetes/typed/authorization/v1beta1" - v13 "k8s.io/client-go/kubernetes/typed/autoscaling/v1" - v2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2" - v2beta1 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1" - v2beta2 "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2" - v14 "k8s.io/client-go/kubernetes/typed/batch/v1" - v1beta13 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" - v15 "k8s.io/client-go/kubernetes/typed/certificates/v1" - v1alpha12 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" - v1beta14 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" - v16 "k8s.io/client-go/kubernetes/typed/coordination/v1" - v1beta15 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" - v17 "k8s.io/client-go/kubernetes/typed/core/v1" - v18 "k8s.io/client-go/kubernetes/typed/discovery/v1" - v1beta16 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1" - v19 "k8s.io/client-go/kubernetes/typed/events/v1" - v1beta17 "k8s.io/client-go/kubernetes/typed/events/v1beta1" - v1beta18 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1" - v110 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1" - v1beta19 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1" - v1beta20 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2" - v1beta3 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" - v111 "k8s.io/client-go/kubernetes/typed/networking/v1" - v1alpha13 "k8s.io/client-go/kubernetes/typed/networking/v1alpha1" - v1beta110 "k8s.io/client-go/kubernetes/typed/networking/v1beta1" - v112 "k8s.io/client-go/kubernetes/typed/node/v1" - v1alpha14 "k8s.io/client-go/kubernetes/typed/node/v1alpha1" - v1beta111 "k8s.io/client-go/kubernetes/typed/node/v1beta1" - v113 "k8s.io/client-go/kubernetes/typed/policy/v1" - v1beta112 "k8s.io/client-go/kubernetes/typed/policy/v1beta1" - v114 "k8s.io/client-go/kubernetes/typed/rbac/v1" - v1alpha15 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" - v1beta113 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" - v1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" - v115 "k8s.io/client-go/kubernetes/typed/scheduling/v1" - v1alpha16 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" - v1beta114 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" - v116 "k8s.io/client-go/kubernetes/typed/storage/v1" - v1alpha17 "k8s.io/client-go/kubernetes/typed/storage/v1alpha1" - v1beta115 "k8s.io/client-go/kubernetes/typed/storage/v1beta1" -) - -// MockInterface is a mock of Interface interface. -type MockInterface struct { - ctrl *gomock.Controller - recorder *MockInterfaceMockRecorder -} - -// MockInterfaceMockRecorder is the mock recorder for MockInterface. -type MockInterfaceMockRecorder struct { - mock *MockInterface -} - -// NewMockInterface creates a new mock instance. -func NewMockInterface(ctrl *gomock.Controller) *MockInterface { - mock := &MockInterface{ctrl: ctrl} - mock.recorder = &MockInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder { - return m.recorder -} - -// AdmissionregistrationV1 mocks base method. -func (m *MockInterface) AdmissionregistrationV1() v1.AdmissionregistrationV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AdmissionregistrationV1") - ret0, _ := ret[0].(v1.AdmissionregistrationV1Interface) - return ret0 -} - -// AdmissionregistrationV1 indicates an expected call of AdmissionregistrationV1. -func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1)) -} - -// AdmissionregistrationV1alpha1 mocks base method. -func (m *MockInterface) AdmissionregistrationV1alpha1() v1alpha1.AdmissionregistrationV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AdmissionregistrationV1alpha1") - ret0, _ := ret[0].(v1alpha1.AdmissionregistrationV1alpha1Interface) - return ret0 -} - -// AdmissionregistrationV1alpha1 indicates an expected call of AdmissionregistrationV1alpha1. -func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1alpha1)) -} - -// AdmissionregistrationV1beta1 mocks base method. -func (m *MockInterface) AdmissionregistrationV1beta1() v1beta1.AdmissionregistrationV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AdmissionregistrationV1beta1") - ret0, _ := ret[0].(v1beta1.AdmissionregistrationV1beta1Interface) - return ret0 -} - -// AdmissionregistrationV1beta1 indicates an expected call of AdmissionregistrationV1beta1. -func (mr *MockInterfaceMockRecorder) AdmissionregistrationV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdmissionregistrationV1beta1", reflect.TypeOf((*MockInterface)(nil).AdmissionregistrationV1beta1)) -} - -// AppsV1 mocks base method. -func (m *MockInterface) AppsV1() v10.AppsV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppsV1") - ret0, _ := ret[0].(v10.AppsV1Interface) - return ret0 -} - -// AppsV1 indicates an expected call of AppsV1. -func (mr *MockInterfaceMockRecorder) AppsV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1", reflect.TypeOf((*MockInterface)(nil).AppsV1)) -} - -// AppsV1beta1 mocks base method. -func (m *MockInterface) AppsV1beta1() v1beta10.AppsV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppsV1beta1") - ret0, _ := ret[0].(v1beta10.AppsV1beta1Interface) - return ret0 -} - -// AppsV1beta1 indicates an expected call of AppsV1beta1. -func (mr *MockInterfaceMockRecorder) AppsV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1beta1", reflect.TypeOf((*MockInterface)(nil).AppsV1beta1)) -} - -// AppsV1beta2 mocks base method. -func (m *MockInterface) AppsV1beta2() v1beta2.AppsV1beta2Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppsV1beta2") - ret0, _ := ret[0].(v1beta2.AppsV1beta2Interface) - return ret0 -} - -// AppsV1beta2 indicates an expected call of AppsV1beta2. -func (mr *MockInterfaceMockRecorder) AppsV1beta2() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppsV1beta2", reflect.TypeOf((*MockInterface)(nil).AppsV1beta2)) -} - -// AuthenticationV1 mocks base method. -func (m *MockInterface) AuthenticationV1() v11.AuthenticationV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthenticationV1") - ret0, _ := ret[0].(v11.AuthenticationV1Interface) - return ret0 -} - -// AuthenticationV1 indicates an expected call of AuthenticationV1. -func (mr *MockInterfaceMockRecorder) AuthenticationV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1)) -} - -// AuthenticationV1alpha1 mocks base method. -func (m *MockInterface) AuthenticationV1alpha1() v1alpha11.AuthenticationV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthenticationV1alpha1") - ret0, _ := ret[0].(v1alpha11.AuthenticationV1alpha1Interface) - return ret0 -} - -// AuthenticationV1alpha1 indicates an expected call of AuthenticationV1alpha1. -func (mr *MockInterfaceMockRecorder) AuthenticationV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1alpha1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1alpha1)) -} - -// AuthenticationV1beta1 mocks base method. -func (m *MockInterface) AuthenticationV1beta1() v1beta11.AuthenticationV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthenticationV1beta1") - ret0, _ := ret[0].(v1beta11.AuthenticationV1beta1Interface) - return ret0 -} - -// AuthenticationV1beta1 indicates an expected call of AuthenticationV1beta1. -func (mr *MockInterfaceMockRecorder) AuthenticationV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticationV1beta1", reflect.TypeOf((*MockInterface)(nil).AuthenticationV1beta1)) -} - -// AuthorizationV1 mocks base method. -func (m *MockInterface) AuthorizationV1() v12.AuthorizationV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthorizationV1") - ret0, _ := ret[0].(v12.AuthorizationV1Interface) - return ret0 -} - -// AuthorizationV1 indicates an expected call of AuthorizationV1. -func (mr *MockInterfaceMockRecorder) AuthorizationV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationV1", reflect.TypeOf((*MockInterface)(nil).AuthorizationV1)) -} - -// AuthorizationV1beta1 mocks base method. -func (m *MockInterface) AuthorizationV1beta1() v1beta12.AuthorizationV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthorizationV1beta1") - ret0, _ := ret[0].(v1beta12.AuthorizationV1beta1Interface) - return ret0 -} - -// AuthorizationV1beta1 indicates an expected call of AuthorizationV1beta1. -func (mr *MockInterfaceMockRecorder) AuthorizationV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationV1beta1", reflect.TypeOf((*MockInterface)(nil).AuthorizationV1beta1)) -} - -// AutoscalingV1 mocks base method. -func (m *MockInterface) AutoscalingV1() v13.AutoscalingV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AutoscalingV1") - ret0, _ := ret[0].(v13.AutoscalingV1Interface) - return ret0 -} - -// AutoscalingV1 indicates an expected call of AutoscalingV1. -func (mr *MockInterfaceMockRecorder) AutoscalingV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV1", reflect.TypeOf((*MockInterface)(nil).AutoscalingV1)) -} - -// AutoscalingV2 mocks base method. -func (m *MockInterface) AutoscalingV2() v2.AutoscalingV2Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AutoscalingV2") - ret0, _ := ret[0].(v2.AutoscalingV2Interface) - return ret0 -} - -// AutoscalingV2 indicates an expected call of AutoscalingV2. -func (mr *MockInterfaceMockRecorder) AutoscalingV2() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2)) -} - -// AutoscalingV2beta1 mocks base method. -func (m *MockInterface) AutoscalingV2beta1() v2beta1.AutoscalingV2beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AutoscalingV2beta1") - ret0, _ := ret[0].(v2beta1.AutoscalingV2beta1Interface) - return ret0 -} - -// AutoscalingV2beta1 indicates an expected call of AutoscalingV2beta1. -func (mr *MockInterfaceMockRecorder) AutoscalingV2beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2beta1", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2beta1)) -} - -// AutoscalingV2beta2 mocks base method. -func (m *MockInterface) AutoscalingV2beta2() v2beta2.AutoscalingV2beta2Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AutoscalingV2beta2") - ret0, _ := ret[0].(v2beta2.AutoscalingV2beta2Interface) - return ret0 -} - -// AutoscalingV2beta2 indicates an expected call of AutoscalingV2beta2. -func (mr *MockInterfaceMockRecorder) AutoscalingV2beta2() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AutoscalingV2beta2", reflect.TypeOf((*MockInterface)(nil).AutoscalingV2beta2)) -} - -// BatchV1 mocks base method. -func (m *MockInterface) BatchV1() v14.BatchV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BatchV1") - ret0, _ := ret[0].(v14.BatchV1Interface) - return ret0 -} - -// BatchV1 indicates an expected call of BatchV1. -func (mr *MockInterfaceMockRecorder) BatchV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchV1", reflect.TypeOf((*MockInterface)(nil).BatchV1)) -} - -// BatchV1beta1 mocks base method. -func (m *MockInterface) BatchV1beta1() v1beta13.BatchV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BatchV1beta1") - ret0, _ := ret[0].(v1beta13.BatchV1beta1Interface) - return ret0 -} - -// BatchV1beta1 indicates an expected call of BatchV1beta1. -func (mr *MockInterfaceMockRecorder) BatchV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchV1beta1", reflect.TypeOf((*MockInterface)(nil).BatchV1beta1)) -} - -// CertificatesV1 mocks base method. -func (m *MockInterface) CertificatesV1() v15.CertificatesV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CertificatesV1") - ret0, _ := ret[0].(v15.CertificatesV1Interface) - return ret0 -} - -// CertificatesV1 indicates an expected call of CertificatesV1. -func (mr *MockInterfaceMockRecorder) CertificatesV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1)) -} - -// CertificatesV1alpha1 mocks base method. -func (m *MockInterface) CertificatesV1alpha1() v1alpha12.CertificatesV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CertificatesV1alpha1") - ret0, _ := ret[0].(v1alpha12.CertificatesV1alpha1Interface) - return ret0 -} - -// CertificatesV1alpha1 indicates an expected call of CertificatesV1alpha1. -func (mr *MockInterfaceMockRecorder) CertificatesV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1alpha1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1alpha1)) -} - -// CertificatesV1beta1 mocks base method. -func (m *MockInterface) CertificatesV1beta1() v1beta14.CertificatesV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CertificatesV1beta1") - ret0, _ := ret[0].(v1beta14.CertificatesV1beta1Interface) - return ret0 -} - -// CertificatesV1beta1 indicates an expected call of CertificatesV1beta1. -func (mr *MockInterfaceMockRecorder) CertificatesV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CertificatesV1beta1", reflect.TypeOf((*MockInterface)(nil).CertificatesV1beta1)) -} - -// CoordinationV1 mocks base method. -func (m *MockInterface) CoordinationV1() v16.CoordinationV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CoordinationV1") - ret0, _ := ret[0].(v16.CoordinationV1Interface) - return ret0 -} - -// CoordinationV1 indicates an expected call of CoordinationV1. -func (mr *MockInterfaceMockRecorder) CoordinationV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoordinationV1", reflect.TypeOf((*MockInterface)(nil).CoordinationV1)) -} - -// CoordinationV1beta1 mocks base method. -func (m *MockInterface) CoordinationV1beta1() v1beta15.CoordinationV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CoordinationV1beta1") - ret0, _ := ret[0].(v1beta15.CoordinationV1beta1Interface) - return ret0 -} - -// CoordinationV1beta1 indicates an expected call of CoordinationV1beta1. -func (mr *MockInterfaceMockRecorder) CoordinationV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoordinationV1beta1", reflect.TypeOf((*MockInterface)(nil).CoordinationV1beta1)) -} - -// CoreV1 mocks base method. -func (m *MockInterface) CoreV1() v17.CoreV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CoreV1") - ret0, _ := ret[0].(v17.CoreV1Interface) - return ret0 -} - -// CoreV1 indicates an expected call of CoreV1. -func (mr *MockInterfaceMockRecorder) CoreV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CoreV1", reflect.TypeOf((*MockInterface)(nil).CoreV1)) -} - -// Discovery mocks base method. -func (m *MockInterface) Discovery() discovery.DiscoveryInterface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Discovery") - ret0, _ := ret[0].(discovery.DiscoveryInterface) - return ret0 -} - -// Discovery indicates an expected call of Discovery. -func (mr *MockInterfaceMockRecorder) Discovery() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discovery", reflect.TypeOf((*MockInterface)(nil).Discovery)) -} - -// DiscoveryV1 mocks base method. -func (m *MockInterface) DiscoveryV1() v18.DiscoveryV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DiscoveryV1") - ret0, _ := ret[0].(v18.DiscoveryV1Interface) - return ret0 -} - -// DiscoveryV1 indicates an expected call of DiscoveryV1. -func (mr *MockInterfaceMockRecorder) DiscoveryV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscoveryV1", reflect.TypeOf((*MockInterface)(nil).DiscoveryV1)) -} - -// DiscoveryV1beta1 mocks base method. -func (m *MockInterface) DiscoveryV1beta1() v1beta16.DiscoveryV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DiscoveryV1beta1") - ret0, _ := ret[0].(v1beta16.DiscoveryV1beta1Interface) - return ret0 -} - -// DiscoveryV1beta1 indicates an expected call of DiscoveryV1beta1. -func (mr *MockInterfaceMockRecorder) DiscoveryV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiscoveryV1beta1", reflect.TypeOf((*MockInterface)(nil).DiscoveryV1beta1)) -} - -// EventsV1 mocks base method. -func (m *MockInterface) EventsV1() v19.EventsV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EventsV1") - ret0, _ := ret[0].(v19.EventsV1Interface) - return ret0 -} - -// EventsV1 indicates an expected call of EventsV1. -func (mr *MockInterfaceMockRecorder) EventsV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsV1", reflect.TypeOf((*MockInterface)(nil).EventsV1)) -} - -// EventsV1beta1 mocks base method. -func (m *MockInterface) EventsV1beta1() v1beta17.EventsV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EventsV1beta1") - ret0, _ := ret[0].(v1beta17.EventsV1beta1Interface) - return ret0 -} - -// EventsV1beta1 indicates an expected call of EventsV1beta1. -func (mr *MockInterfaceMockRecorder) EventsV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsV1beta1", reflect.TypeOf((*MockInterface)(nil).EventsV1beta1)) -} - -// ExtensionsV1beta1 mocks base method. -func (m *MockInterface) ExtensionsV1beta1() v1beta18.ExtensionsV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ExtensionsV1beta1") - ret0, _ := ret[0].(v1beta18.ExtensionsV1beta1Interface) - return ret0 -} - -// ExtensionsV1beta1 indicates an expected call of ExtensionsV1beta1. -func (mr *MockInterfaceMockRecorder) ExtensionsV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExtensionsV1beta1", reflect.TypeOf((*MockInterface)(nil).ExtensionsV1beta1)) -} - -// FlowcontrolV1 mocks base method. -func (m *MockInterface) FlowcontrolV1() v110.FlowcontrolV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlowcontrolV1") - ret0, _ := ret[0].(v110.FlowcontrolV1Interface) - return ret0 -} - -// FlowcontrolV1 indicates an expected call of FlowcontrolV1. -func (mr *MockInterfaceMockRecorder) FlowcontrolV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1)) -} - -// FlowcontrolV1beta1 mocks base method. -func (m *MockInterface) FlowcontrolV1beta1() v1beta19.FlowcontrolV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlowcontrolV1beta1") - ret0, _ := ret[0].(v1beta19.FlowcontrolV1beta1Interface) - return ret0 -} - -// FlowcontrolV1beta1 indicates an expected call of FlowcontrolV1beta1. -func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta1", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta1)) -} - -// FlowcontrolV1beta2 mocks base method. -func (m *MockInterface) FlowcontrolV1beta2() v1beta20.FlowcontrolV1beta2Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlowcontrolV1beta2") - ret0, _ := ret[0].(v1beta20.FlowcontrolV1beta2Interface) - return ret0 -} - -// FlowcontrolV1beta2 indicates an expected call of FlowcontrolV1beta2. -func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta2() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta2", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta2)) -} - -// FlowcontrolV1beta3 mocks base method. -func (m *MockInterface) FlowcontrolV1beta3() v1beta3.FlowcontrolV1beta3Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlowcontrolV1beta3") - ret0, _ := ret[0].(v1beta3.FlowcontrolV1beta3Interface) - return ret0 -} - -// FlowcontrolV1beta3 indicates an expected call of FlowcontrolV1beta3. -func (mr *MockInterfaceMockRecorder) FlowcontrolV1beta3() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlowcontrolV1beta3", reflect.TypeOf((*MockInterface)(nil).FlowcontrolV1beta3)) -} - -// InternalV1alpha1 mocks base method. -func (m *MockInterface) InternalV1alpha1() v1alpha10.InternalV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InternalV1alpha1") - ret0, _ := ret[0].(v1alpha10.InternalV1alpha1Interface) - return ret0 -} - -// InternalV1alpha1 indicates an expected call of InternalV1alpha1. -func (mr *MockInterfaceMockRecorder) InternalV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InternalV1alpha1", reflect.TypeOf((*MockInterface)(nil).InternalV1alpha1)) -} - -// NetworkingV1 mocks base method. -func (m *MockInterface) NetworkingV1() v111.NetworkingV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NetworkingV1") - ret0, _ := ret[0].(v111.NetworkingV1Interface) - return ret0 -} - -// NetworkingV1 indicates an expected call of NetworkingV1. -func (mr *MockInterfaceMockRecorder) NetworkingV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1)) -} - -// NetworkingV1alpha1 mocks base method. -func (m *MockInterface) NetworkingV1alpha1() v1alpha13.NetworkingV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NetworkingV1alpha1") - ret0, _ := ret[0].(v1alpha13.NetworkingV1alpha1Interface) - return ret0 -} - -// NetworkingV1alpha1 indicates an expected call of NetworkingV1alpha1. -func (mr *MockInterfaceMockRecorder) NetworkingV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1alpha1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1alpha1)) -} - -// NetworkingV1beta1 mocks base method. -func (m *MockInterface) NetworkingV1beta1() v1beta110.NetworkingV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NetworkingV1beta1") - ret0, _ := ret[0].(v1beta110.NetworkingV1beta1Interface) - return ret0 -} - -// NetworkingV1beta1 indicates an expected call of NetworkingV1beta1. -func (mr *MockInterfaceMockRecorder) NetworkingV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkingV1beta1", reflect.TypeOf((*MockInterface)(nil).NetworkingV1beta1)) -} - -// NodeV1 mocks base method. -func (m *MockInterface) NodeV1() v112.NodeV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NodeV1") - ret0, _ := ret[0].(v112.NodeV1Interface) - return ret0 -} - -// NodeV1 indicates an expected call of NodeV1. -func (mr *MockInterfaceMockRecorder) NodeV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1", reflect.TypeOf((*MockInterface)(nil).NodeV1)) -} - -// NodeV1alpha1 mocks base method. -func (m *MockInterface) NodeV1alpha1() v1alpha14.NodeV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NodeV1alpha1") - ret0, _ := ret[0].(v1alpha14.NodeV1alpha1Interface) - return ret0 -} - -// NodeV1alpha1 indicates an expected call of NodeV1alpha1. -func (mr *MockInterfaceMockRecorder) NodeV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1alpha1", reflect.TypeOf((*MockInterface)(nil).NodeV1alpha1)) -} - -// NodeV1beta1 mocks base method. -func (m *MockInterface) NodeV1beta1() v1beta111.NodeV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NodeV1beta1") - ret0, _ := ret[0].(v1beta111.NodeV1beta1Interface) - return ret0 -} - -// NodeV1beta1 indicates an expected call of NodeV1beta1. -func (mr *MockInterfaceMockRecorder) NodeV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeV1beta1", reflect.TypeOf((*MockInterface)(nil).NodeV1beta1)) -} - -// PolicyV1 mocks base method. -func (m *MockInterface) PolicyV1() v113.PolicyV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PolicyV1") - ret0, _ := ret[0].(v113.PolicyV1Interface) - return ret0 -} - -// PolicyV1 indicates an expected call of PolicyV1. -func (mr *MockInterfaceMockRecorder) PolicyV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PolicyV1", reflect.TypeOf((*MockInterface)(nil).PolicyV1)) -} - -// PolicyV1beta1 mocks base method. -func (m *MockInterface) PolicyV1beta1() v1beta112.PolicyV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PolicyV1beta1") - ret0, _ := ret[0].(v1beta112.PolicyV1beta1Interface) - return ret0 -} - -// PolicyV1beta1 indicates an expected call of PolicyV1beta1. -func (mr *MockInterfaceMockRecorder) PolicyV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PolicyV1beta1", reflect.TypeOf((*MockInterface)(nil).PolicyV1beta1)) -} - -// RbacV1 mocks base method. -func (m *MockInterface) RbacV1() v114.RbacV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RbacV1") - ret0, _ := ret[0].(v114.RbacV1Interface) - return ret0 -} - -// RbacV1 indicates an expected call of RbacV1. -func (mr *MockInterfaceMockRecorder) RbacV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1", reflect.TypeOf((*MockInterface)(nil).RbacV1)) -} - -// RbacV1alpha1 mocks base method. -func (m *MockInterface) RbacV1alpha1() v1alpha15.RbacV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RbacV1alpha1") - ret0, _ := ret[0].(v1alpha15.RbacV1alpha1Interface) - return ret0 -} - -// RbacV1alpha1 indicates an expected call of RbacV1alpha1. -func (mr *MockInterfaceMockRecorder) RbacV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1alpha1", reflect.TypeOf((*MockInterface)(nil).RbacV1alpha1)) -} - -// RbacV1beta1 mocks base method. -func (m *MockInterface) RbacV1beta1() v1beta113.RbacV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RbacV1beta1") - ret0, _ := ret[0].(v1beta113.RbacV1beta1Interface) - return ret0 -} - -// RbacV1beta1 indicates an expected call of RbacV1beta1. -func (mr *MockInterfaceMockRecorder) RbacV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RbacV1beta1", reflect.TypeOf((*MockInterface)(nil).RbacV1beta1)) -} - -// ResourceV1alpha2 mocks base method. -func (m *MockInterface) ResourceV1alpha2() v1alpha2.ResourceV1alpha2Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResourceV1alpha2") - ret0, _ := ret[0].(v1alpha2.ResourceV1alpha2Interface) - return ret0 -} - -// ResourceV1alpha2 indicates an expected call of ResourceV1alpha2. -func (mr *MockInterfaceMockRecorder) ResourceV1alpha2() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResourceV1alpha2", reflect.TypeOf((*MockInterface)(nil).ResourceV1alpha2)) -} - -// SchedulingV1 mocks base method. -func (m *MockInterface) SchedulingV1() v115.SchedulingV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SchedulingV1") - ret0, _ := ret[0].(v115.SchedulingV1Interface) - return ret0 -} - -// SchedulingV1 indicates an expected call of SchedulingV1. -func (mr *MockInterfaceMockRecorder) SchedulingV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1)) -} - -// SchedulingV1alpha1 mocks base method. -func (m *MockInterface) SchedulingV1alpha1() v1alpha16.SchedulingV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SchedulingV1alpha1") - ret0, _ := ret[0].(v1alpha16.SchedulingV1alpha1Interface) - return ret0 -} - -// SchedulingV1alpha1 indicates an expected call of SchedulingV1alpha1. -func (mr *MockInterfaceMockRecorder) SchedulingV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1alpha1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1alpha1)) -} - -// SchedulingV1beta1 mocks base method. -func (m *MockInterface) SchedulingV1beta1() v1beta114.SchedulingV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SchedulingV1beta1") - ret0, _ := ret[0].(v1beta114.SchedulingV1beta1Interface) - return ret0 -} - -// SchedulingV1beta1 indicates an expected call of SchedulingV1beta1. -func (mr *MockInterfaceMockRecorder) SchedulingV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SchedulingV1beta1", reflect.TypeOf((*MockInterface)(nil).SchedulingV1beta1)) -} - -// StorageV1 mocks base method. -func (m *MockInterface) StorageV1() v116.StorageV1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StorageV1") - ret0, _ := ret[0].(v116.StorageV1Interface) - return ret0 -} - -// StorageV1 indicates an expected call of StorageV1. -func (mr *MockInterfaceMockRecorder) StorageV1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1", reflect.TypeOf((*MockInterface)(nil).StorageV1)) -} - -// StorageV1alpha1 mocks base method. -func (m *MockInterface) StorageV1alpha1() v1alpha17.StorageV1alpha1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StorageV1alpha1") - ret0, _ := ret[0].(v1alpha17.StorageV1alpha1Interface) - return ret0 -} - -// StorageV1alpha1 indicates an expected call of StorageV1alpha1. -func (mr *MockInterfaceMockRecorder) StorageV1alpha1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1alpha1", reflect.TypeOf((*MockInterface)(nil).StorageV1alpha1)) -} - -// StorageV1beta1 mocks base method. -func (m *MockInterface) StorageV1beta1() v1beta115.StorageV1beta1Interface { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StorageV1beta1") - ret0, _ := ret[0].(v1beta115.StorageV1beta1Interface) - return ret0 -} - -// StorageV1beta1 indicates an expected call of StorageV1beta1. -func (mr *MockInterfaceMockRecorder) StorageV1beta1() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageV1beta1", reflect.TypeOf((*MockInterface)(nil).StorageV1beta1)) -} diff --git a/internal/mock/client-go/scale/doc.go b/internal/mock/client-go/scale/doc.go deleted file mode 100644 index a93b49ba..00000000 --- a/internal/mock/client-go/scale/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package scale -destination=mocks.go k8s.io/client-go/scale ScaleInterface -package scale diff --git a/internal/mock/client-go/scale/mocks.go b/internal/mock/client-go/scale/mocks.go deleted file mode 100644 index e91ab398..00000000 --- a/internal/mock/client-go/scale/mocks.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: k8s.io/client-go/scale (interfaces: ScaleInterface) - -// Package scale is a generated GoMock package. -package scale - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - v1 "k8s.io/api/autoscaling/v1" - v10 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" -) - -// MockScaleInterface is a mock of ScaleInterface interface. -type MockScaleInterface struct { - ctrl *gomock.Controller - recorder *MockScaleInterfaceMockRecorder -} - -// MockScaleInterfaceMockRecorder is the mock recorder for MockScaleInterface. -type MockScaleInterfaceMockRecorder struct { - mock *MockScaleInterface -} - -// NewMockScaleInterface creates a new mock instance. -func NewMockScaleInterface(ctrl *gomock.Controller) *MockScaleInterface { - mock := &MockScaleInterface{ctrl: ctrl} - mock.recorder = &MockScaleInterfaceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockScaleInterface) EXPECT() *MockScaleInterfaceMockRecorder { - return m.recorder -} - -// Get mocks base method. -func (m *MockScaleInterface) Get(arg0 context.Context, arg1 schema.GroupResource, arg2 string, arg3 v10.GetOptions) (*v1.Scale, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*v1.Scale) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get. -func (mr *MockScaleInterfaceMockRecorder) Get(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockScaleInterface)(nil).Get), arg0, arg1, arg2, arg3) -} - -// Patch mocks base method. -func (m *MockScaleInterface) Patch(arg0 context.Context, arg1 schema.GroupVersionResource, arg2 string, arg3 types.PatchType, arg4 []byte, arg5 v10.PatchOptions) (*v1.Scale, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Patch", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(*v1.Scale) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Patch indicates an expected call of Patch. -func (mr *MockScaleInterfaceMockRecorder) Patch(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Patch", reflect.TypeOf((*MockScaleInterface)(nil).Patch), arg0, arg1, arg2, arg3, arg4, arg5) -} - -// Update mocks base method. -func (m *MockScaleInterface) Update(arg0 context.Context, arg1 schema.GroupResource, arg2 *v1.Scale, arg3 v10.UpdateOptions) (*v1.Scale, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*v1.Scale) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Update indicates an expected call of Update. -func (mr *MockScaleInterfaceMockRecorder) Update(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockScaleInterface)(nil).Update), arg0, arg1, arg2, arg3) -} diff --git a/internal/mock/controller-runtime/client/doc.go b/internal/mock/controller-runtime/client/doc.go deleted file mode 100644 index 930c556c..00000000 --- a/internal/mock/controller-runtime/client/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package client -destination=mocks.go sigs.k8s.io/controller-runtime/pkg/client Client -package client diff --git a/internal/mock/controller-runtime/client/mocks.go b/internal/mock/controller-runtime/client/mocks.go deleted file mode 100644 index 1e80ef5f..00000000 --- a/internal/mock/controller-runtime/client/mocks.go +++ /dev/null @@ -1,259 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: sigs.k8s.io/controller-runtime/pkg/client (interfaces: Client) - -// Package client is a generated GoMock package. -package client - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" - meta "k8s.io/apimachinery/pkg/api/meta" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - client "sigs.k8s.io/controller-runtime/pkg/client" -) - -// MockClient is a mock of Client interface. -type MockClient struct { - ctrl *gomock.Controller - recorder *MockClientMockRecorder -} - -// MockClientMockRecorder is the mock recorder for MockClient. -type MockClientMockRecorder struct { - mock *MockClient -} - -// NewMockClient creates a new mock instance. -func NewMockClient(ctrl *gomock.Controller) *MockClient { - mock := &MockClient{ctrl: ctrl} - mock.recorder = &MockClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockClient) EXPECT() *MockClientMockRecorder { - return m.recorder -} - -// Create mocks base method. -func (m *MockClient) Create(arg0 context.Context, arg1 client.Object, arg2 ...client.CreateOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Create", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Create indicates an expected call of Create. -func (mr *MockClientMockRecorder) Create(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClient)(nil).Create), varargs...) -} - -// Delete mocks base method. -func (m *MockClient) Delete(arg0 context.Context, arg1 client.Object, arg2 ...client.DeleteOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Delete", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Delete indicates an expected call of Delete. -func (mr *MockClientMockRecorder) Delete(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), varargs...) -} - -// DeleteAllOf mocks base method. -func (m *MockClient) DeleteAllOf(arg0 context.Context, arg1 client.Object, arg2 ...client.DeleteAllOfOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteAllOf", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteAllOf indicates an expected call of DeleteAllOf. -func (mr *MockClientMockRecorder) DeleteAllOf(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllOf", reflect.TypeOf((*MockClient)(nil).DeleteAllOf), varargs...) -} - -// Get mocks base method. -func (m *MockClient) Get(arg0 context.Context, arg1 types.NamespacedName, arg2 client.Object, arg3 ...client.GetOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2} - for _, a := range arg3 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Get", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Get indicates an expected call of Get. -func (mr *MockClientMockRecorder) Get(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), varargs...) -} - -// GroupVersionKindFor mocks base method. -func (m *MockClient) GroupVersionKindFor(arg0 runtime.Object) (schema.GroupVersionKind, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GroupVersionKindFor", arg0) - ret0, _ := ret[0].(schema.GroupVersionKind) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GroupVersionKindFor indicates an expected call of GroupVersionKindFor. -func (mr *MockClientMockRecorder) GroupVersionKindFor(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GroupVersionKindFor", reflect.TypeOf((*MockClient)(nil).GroupVersionKindFor), arg0) -} - -// IsObjectNamespaced mocks base method. -func (m *MockClient) IsObjectNamespaced(arg0 runtime.Object) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsObjectNamespaced", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsObjectNamespaced indicates an expected call of IsObjectNamespaced. -func (mr *MockClientMockRecorder) IsObjectNamespaced(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsObjectNamespaced", reflect.TypeOf((*MockClient)(nil).IsObjectNamespaced), arg0) -} - -// List mocks base method. -func (m *MockClient) List(arg0 context.Context, arg1 client.ObjectList, arg2 ...client.ListOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "List", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// List indicates an expected call of List. -func (mr *MockClientMockRecorder) List(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClient)(nil).List), varargs...) -} - -// Patch mocks base method. -func (m *MockClient) Patch(arg0 context.Context, arg1 client.Object, arg2 client.Patch, arg3 ...client.PatchOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1, arg2} - for _, a := range arg3 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Patch", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Patch indicates an expected call of Patch. -func (mr *MockClientMockRecorder) Patch(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Patch", reflect.TypeOf((*MockClient)(nil).Patch), varargs...) -} - -// RESTMapper mocks base method. -func (m *MockClient) RESTMapper() meta.RESTMapper { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RESTMapper") - ret0, _ := ret[0].(meta.RESTMapper) - return ret0 -} - -// RESTMapper indicates an expected call of RESTMapper. -func (mr *MockClientMockRecorder) RESTMapper() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTMapper", reflect.TypeOf((*MockClient)(nil).RESTMapper)) -} - -// Scheme mocks base method. -func (m *MockClient) Scheme() *runtime.Scheme { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Scheme") - ret0, _ := ret[0].(*runtime.Scheme) - return ret0 -} - -// Scheme indicates an expected call of Scheme. -func (mr *MockClientMockRecorder) Scheme() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scheme", reflect.TypeOf((*MockClient)(nil).Scheme)) -} - -// Status mocks base method. -func (m *MockClient) Status() client.SubResourceWriter { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Status") - ret0, _ := ret[0].(client.SubResourceWriter) - return ret0 -} - -// Status indicates an expected call of Status. -func (mr *MockClientMockRecorder) Status() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockClient)(nil).Status)) -} - -// SubResource mocks base method. -func (m *MockClient) SubResource(arg0 string) client.SubResourceClient { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubResource", arg0) - ret0, _ := ret[0].(client.SubResourceClient) - return ret0 -} - -// SubResource indicates an expected call of SubResource. -func (mr *MockClientMockRecorder) SubResource(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubResource", reflect.TypeOf((*MockClient)(nil).SubResource), arg0) -} - -// Update mocks base method. -func (m *MockClient) Update(arg0 context.Context, arg1 client.Object, arg2 ...client.UpdateOption) error { - m.ctrl.T.Helper() - varargs := []interface{}{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "Update", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// Update indicates an expected call of Update. -func (mr *MockClientMockRecorder) Update(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockClient)(nil).Update), varargs...) -} diff --git a/internal/mock/prober/doc.go b/internal/mock/prober/doc.go deleted file mode 100644 index 22f4a84e..00000000 --- a/internal/mock/prober/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package prober -destination=mocks.go github.com/gardener/dependency-watchdog/internal/prober ShootClientCreator -package prober diff --git a/internal/mock/prober/mocks.go b/internal/mock/prober/mocks.go deleted file mode 100644 index 2a334bb6..00000000 --- a/internal/mock/prober/mocks.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/gardener/dependency-watchdog/internal/prober (interfaces: ShootClientCreator) - -// Package prober is a generated GoMock package. -package prober - -import ( - context "context" - reflect "reflect" - time "time" - - logr "github.com/go-logr/logr" - gomock "github.com/golang/mock/gomock" - kubernetes "k8s.io/client-go/kubernetes" -) - -// MockShootClientCreator is a mock of ShootClientCreator interface. -type MockShootClientCreator struct { - ctrl *gomock.Controller - recorder *MockShootClientCreatorMockRecorder -} - -// MockShootClientCreatorMockRecorder is the mock recorder for MockShootClientCreator. -type MockShootClientCreatorMockRecorder struct { - mock *MockShootClientCreator -} - -// NewMockShootClientCreator creates a new mock instance. -func NewMockShootClientCreator(ctrl *gomock.Controller) *MockShootClientCreator { - mock := &MockShootClientCreator{ctrl: ctrl} - mock.recorder = &MockShootClientCreatorMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockShootClientCreator) EXPECT() *MockShootClientCreatorMockRecorder { - return m.recorder -} - -// CreateClient mocks base method. -func (m *MockShootClientCreator) CreateClient(arg0 context.Context, arg1 logr.Logger, arg2, arg3 string, arg4 time.Duration) (kubernetes.Interface, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateClient", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(kubernetes.Interface) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateClient indicates an expected call of CreateClient. -func (mr *MockShootClientCreatorMockRecorder) CreateClient(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClient", reflect.TypeOf((*MockShootClientCreator)(nil).CreateClient), arg0, arg1, arg2, arg3, arg4) -} diff --git a/internal/mock/prober/scaler/doc.go b/internal/mock/prober/scaler/doc.go deleted file mode 100644 index 660ce622..00000000 --- a/internal/mock/prober/scaler/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:generate mockgen -package scaler -destination=mocks.go github.com/gardener/dependency-watchdog/internal/prober/scaler Scaler -package scaler diff --git a/internal/mock/prober/scaler/mocks.go b/internal/mock/prober/scaler/mocks.go deleted file mode 100644 index 777e6d51..00000000 --- a/internal/mock/prober/scaler/mocks.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/gardener/dependency-watchdog/internal/prober/scaler (interfaces: Scaler) - -// Package scaler is a generated GoMock package. -package scaler - -import ( - context "context" - reflect "reflect" - - gomock "github.com/golang/mock/gomock" -) - -// MockScaler is a mock of Scaler interface. -type MockScaler struct { - ctrl *gomock.Controller - recorder *MockScalerMockRecorder -} - -// MockScalerMockRecorder is the mock recorder for MockScaler. -type MockScalerMockRecorder struct { - mock *MockScaler -} - -// NewMockScaler creates a new mock instance. -func NewMockScaler(ctrl *gomock.Controller) *MockScaler { - mock := &MockScaler{ctrl: ctrl} - mock.recorder = &MockScalerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockScaler) EXPECT() *MockScalerMockRecorder { - return m.recorder -} - -// ScaleDown mocks base method. -func (m *MockScaler) ScaleDown(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScaleDown", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// ScaleDown indicates an expected call of ScaleDown. -func (mr *MockScalerMockRecorder) ScaleDown(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScaleDown", reflect.TypeOf((*MockScaler)(nil).ScaleDown), arg0) -} - -// ScaleUp mocks base method. -func (m *MockScaler) ScaleUp(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScaleUp", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// ScaleUp indicates an expected call of ScaleUp. -func (mr *MockScalerMockRecorder) ScaleUp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScaleUp", reflect.TypeOf((*MockScaler)(nil).ScaleUp), arg0) -} diff --git a/internal/prober/.import-restrictions b/internal/prober/.import-restrictions index 6beca05b..caa6a7c0 100644 --- a/internal/prober/.import-restrictions +++ b/internal/prober/.import-restrictions @@ -8,6 +8,6 @@ rules: - github.com/gardener/dependency-watchdog/api - github.com/gardener/dependency-watchdog/internal/util - github.com/gardener/dependency-watchdog/internal/test - - github.com/gardener/dependency-watchdog/internal/mock + - github.com/gardener/dependency-watchdog/internal/fakes - github.com/gardener/dependency-watchdog/internal/prober - github.com/gardener/dependency-watchdog/internal/prober/scaler diff --git a/internal/prober/errors/errors.go b/internal/prober/errors/errors.go new file mode 100644 index 00000000..ab3ca57b --- /dev/null +++ b/internal/prober/errors/errors.go @@ -0,0 +1,50 @@ +package errors + +import "fmt" + +// ErrorCode is the type for error codes. +type ErrorCode string + +const ( + // ErrProbeAPIServer is the error code for errors in the API server probe. + ErrProbeAPIServer = "ERR_PROBE_API_SERVER" + // ErrSetupProbeClient is the error code for errors in setting up the probe client. + ErrSetupProbeClient = "ERR_SETUP_PROBE_CLIENT" + // ErrProbeNodeLease is the error code for errors in the node lease probe. + ErrProbeNodeLease = "ERR_PROBE_NODE_LEASE" + // ErrScaleUp is the error code for errors in scaling up the dependent resources + ErrScaleUp = "ERR_SCALE_UP" + // ErrScaleDown is the error code for errors in scaling down the dependent resources + ErrScaleDown = "ERR_SCALE_DOWN" +) + +// ProbeError is the error type for probe errors. It contains the error code, the cause of the error, and the error message. +// It is used by prober to record its last error and is currently only used for unit tests. +type ProbeError struct { + // Code is the error code that is returned by the probe. + Code ErrorCode + // Cause is the error that happened during the probe. + Cause error + // Message is used for mentioning additional details describing the error. + Message string +} + +// Error is the error interface implementation for ProbeError. +func (e *ProbeError) Error() string { + if e.Cause != nil { + return fmt.Sprintf("Code: %s, Message: %s, Cause: %s", e.Code, e.Message, e.Cause.Error()) + } + return fmt.Sprintf("Code: %s, Message: %s", e.Code, e.Message) +} + +// WrapError wraps an error with an error code and a message. +func WrapError(err error, code ErrorCode, message string) error { + if err == nil { + return nil + } + return &ProbeError{ + Code: code, + Cause: err, + Message: message, + } +} diff --git a/internal/prober/fakes/k8s/client.go b/internal/prober/fakes/k8s/client.go new file mode 100644 index 00000000..e6fd4c76 --- /dev/null +++ b/internal/prober/fakes/k8s/client.go @@ -0,0 +1,127 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 + +package k8s + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + +// ClientMethod is a name of the method on client.Client for which an error is recorded. +type ClientMethod string + +const ( + // ClientMethodList is the name of the List method on client.Client. + ClientMethodList ClientMethod = "List" +) + +// errorRecord contains the recorded error for a specific client.Client method and identifiers such as name, namespace and matching labels. +type errorRecord struct { + method ClientMethod + resourceName string + resourceNamespace string + labels labels.Set + resourceGVK schema.GroupVersionKind + err error +} + +// ErrorsForGVK contains the recorded errors for a specific GroupVersionKind. +type ErrorsForGVK struct { + GVK schema.GroupVersionKind + DeleteAllErr *apierrors.StatusError + ListErr *apierrors.StatusError +} + +// FakeClientBuilder builds a client.Client which will also react to the configured errors. +type FakeClientBuilder struct { + errorRecords []errorRecord + existingObjects []client.Object + scheme *runtime.Scheme +} + +// NewFakeClientBuilder creates a new instance of FakeClientBuilder. +func NewFakeClientBuilder(existingObjects ...client.Object) *FakeClientBuilder { + return &FakeClientBuilder{ + existingObjects: existingObjects, + } +} + +// RecordErrorForObjectsWithGVK records an error for a specific client.Client method and objects in a given namespace of a given GroupVersionKind. +func (b *FakeClientBuilder) RecordErrorForObjectsWithGVK(method ClientMethod, namespace string, gvk schema.GroupVersionKind, err *apierrors.StatusError) *FakeClientBuilder { + // this method records error, so if nil error is passed then there is no need to create any error record. + if err == nil { + return b + } + b.errorRecords = append(b.errorRecords, errorRecord{ + method: method, + resourceGVK: gvk, + resourceNamespace: namespace, + err: err, + }) + return b +} + +// WithScheme sets the scheme for the client. +func (b *FakeClientBuilder) WithScheme(scheme *runtime.Scheme) *FakeClientBuilder { + b.scheme = scheme + return b +} + +// Build creates a new instance of client.Client which will react to the configured errors. +func (b *FakeClientBuilder) Build() client.Client { + if b.scheme == nil { + b.scheme = scheme.Scheme + } + return &fakeClient{ + Client: fake.NewClientBuilder().WithObjects(b.existingObjects...).WithScheme(b.scheme).Build(), + errorRecords: b.errorRecords, + } +} + +// fakeClient is a client.Client implementation which reacts to the configured errors. +type fakeClient struct { + client.Client + errorRecords []errorRecord +} + +// ---------------------------------- Implementation of client.Client ---------------------------------- + +func (c *fakeClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + listOpts := client.ListOptions{} + listOpts.ApplyOptions(opts) + + gvk, err := apiutil.GVKForObject(list, c.Scheme()) + if err != nil { + return err + } + + if err := c.getRecordedObjectCollectionError(ClientMethodList, listOpts.Namespace, listOpts.LabelSelector, gvk); err != nil { + return err + } + return c.Client.List(ctx, list, opts...) +} + +// ---------------------------------- Helper methods ---------------------------------- + +func (c *fakeClient) getRecordedObjectCollectionError(method ClientMethod, namespace string, labelSelector labels.Selector, objGVK schema.GroupVersionKind) error { + for _, errRecord := range c.errorRecords { + if errRecord.method == method && errRecord.resourceNamespace == namespace && + (errRecord.resourceGVK == objGVK || // if the GVK is set, we need to match it + (labelSelector == nil && errRecord.labels == nil) || // if there is no label selector and no labels in the error record + labelSelector.Matches(errRecord.labels)) { // if there is a label selector, and it matches the labels in the error record + return errRecord.err + } + } + return nil +} diff --git a/internal/prober/fakes/k8s/discoveryclient.go b/internal/prober/fakes/k8s/discoveryclient.go new file mode 100644 index 00000000..74c7e235 --- /dev/null +++ b/internal/prober/fakes/k8s/discoveryclient.go @@ -0,0 +1,29 @@ +package k8s + +import ( + "k8s.io/apimachinery/pkg/version" + "k8s.io/client-go/discovery" + "k8s.io/client-go/kubernetes/fake" +) + +// discoveryClient is a test implementation of DiscoveryInterface. +type discoveryClient struct { + discovery.DiscoveryInterface + err error +} + +// ServerVersion is the implementation of the DiscoveryInterface method for discoveryClient +func (t *discoveryClient) ServerVersion() (*version.Info, error) { + if t.err != nil { + return nil, t.err + } + return t.DiscoveryInterface.ServerVersion() +} + +// NewFakeDiscoveryClient creates a new DiscoveryClient. +func NewFakeDiscoveryClient(err error) discovery.DiscoveryInterface { + return &discoveryClient{ + DiscoveryInterface: fake.NewSimpleClientset().Discovery(), + err: err, + } +} diff --git a/internal/prober/fakes/scale/scale.go b/internal/prober/fakes/scale/scale.go new file mode 100644 index 00000000..12c777c8 --- /dev/null +++ b/internal/prober/fakes/scale/scale.go @@ -0,0 +1,80 @@ +package scale + +import ( + "context" + + "github.com/gardener/dependency-watchdog/internal/prober/scaler" + "github.com/gardener/dependency-watchdog/internal/test" + appsv1 "k8s.io/api/apps/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var defaultScalingTargetNames = []string{test.MCMDeploymentName, test.KCMDeploymentName, test.CADeploymentName} + +type fakeScaler struct { + scaler.Scaler + client client.Client + scalingTargetRefs []client.ObjectKey + scaleUpErr error + scaleDownErr error +} + +// NewFakeScaler creates a new instance of fakeScaler. +func NewFakeScaler(client client.Client, namespace string, scaleUpErr, scaleDownErr error) scaler.Scaler { + return &fakeScaler{ + client: client, + scalingTargetRefs: createScalingTargetRefs(namespace), + scaleUpErr: scaleUpErr, + scaleDownErr: scaleDownErr, + } +} + +func createScalingTargetRefs(namespace string) []client.ObjectKey { + var scalingTargetRefs []client.ObjectKey + for _, scalingTargetName := range defaultScalingTargetNames { + scalingTargetRefs = append(scalingTargetRefs, client.ObjectKey{ + Namespace: namespace, + Name: scalingTargetName, + }) + } + return scalingTargetRefs +} + +//---------------------------------- Implementation of scaler.Scaler ---------------------------------- + +func (f *fakeScaler) ScaleUp(ctx context.Context) error { + if f.scaleUpErr != nil { + return f.scaleUpErr + } + for _, scalingTargetRef := range f.scalingTargetRefs { + if err := f.doScale(ctx, scalingTargetRef, 1); err != nil { + return err + } + } + return nil +} + +func (f *fakeScaler) ScaleDown(ctx context.Context) error { + if f.scaleDownErr != nil { + return f.scaleDownErr + } + for _, scalingTargetRef := range f.scalingTargetRefs { + if err := f.doScale(ctx, scalingTargetRef, 0); err != nil { + return err + } + } + return nil +} + +func (f *fakeScaler) doScale(ctx context.Context, ref client.ObjectKey, replicas int32) error { + deploy := &appsv1.Deployment{} + if err := f.client.Get(ctx, ref, deploy); err != nil { + return err + } + clone := deploy.DeepCopy() + clone.Spec.Replicas = &replicas + if err := f.client.Update(ctx, clone); err != nil { + return err + } + return nil +} diff --git a/internal/prober/fakes/shoot/clientcreator.go b/internal/prober/fakes/shoot/clientcreator.go new file mode 100644 index 00000000..27581db1 --- /dev/null +++ b/internal/prober/fakes/shoot/clientcreator.go @@ -0,0 +1,65 @@ +package shoot + +import ( + "context" + "time" + + "github.com/gardener/dependency-watchdog/internal/prober/shoot" + "github.com/go-logr/logr" + "k8s.io/client-go/discovery" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type shootClientCreator struct { + discoveryClient discovery.DiscoveryInterface + client client.Client + discoveryClientCreationError error + clientCreationError error +} + +type shootClientBuilder struct { + shootClientCreator shootClientCreator +} + +// NewFakeShootClientBuilder creates a new instance of shootClientBuilder. +func NewFakeShootClientBuilder(discoveryClient discovery.DiscoveryInterface, client client.Client) *shootClientBuilder { + return &shootClientBuilder{ + shootClientCreator: shootClientCreator{ + discoveryClient: discoveryClient, + client: client, + }, + } +} + +// WithDiscoveryClientCreationError sets the error to be returned when creating a discovery client. +func (s *shootClientBuilder) WithDiscoveryClientCreationError(err error) *shootClientBuilder { + s.shootClientCreator.discoveryClientCreationError = err + return s +} + +// WithClientCreationError sets the error to be returned when creating a client. +func (s *shootClientBuilder) WithClientCreationError(err error) *shootClientBuilder { + s.shootClientCreator.clientCreationError = err + return s +} + +// Build returns a shootClientCreator. +func (s *shootClientBuilder) Build() shoot.ClientCreator { + return &s.shootClientCreator +} + +//--------------------------- Implementation of ShootClientCreator interface --------------------------- + +func (s *shootClientCreator) CreateClient(_ context.Context, _ logr.Logger, _ time.Duration) (client.Client, error) { + if s.clientCreationError != nil { + return nil, s.clientCreationError + } + return s.client, nil +} + +func (s *shootClientCreator) CreateDiscoveryClient(_ context.Context, _ logr.Logger, _ time.Duration) (discovery.DiscoveryInterface, error) { + if s.discoveryClientCreationError != nil { + return nil, s.discoveryClientCreationError + } + return s.discoveryClient, nil +} diff --git a/internal/prober/prober.go b/internal/prober/prober.go index cd618234..db132f7e 100644 --- a/internal/prober/prober.go +++ b/internal/prober/prober.go @@ -6,26 +6,28 @@ package prober import ( "context" + "reflect" + "slices" "time" - coordinationv1 "k8s.io/api/coordination/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/sets" + "github.com/gardener/dependency-watchdog/internal/prober/errors" + "github.com/gardener/dependency-watchdog/internal/prober/shoot" + "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" papi "github.com/gardener/dependency-watchdog/api/prober" dwdScaler "github.com/gardener/dependency-watchdog/internal/prober/scaler" "github.com/gardener/dependency-watchdog/internal/util" - "github.com/go-logr/logr" + coordinationv1 "k8s.io/api/coordination/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" ) const ( - defaultGetSecretBackoff = 100 * time.Millisecond - defaultGetSecretMaxAttempts = 3 backOffDurationForThrottledRequests = 10 * time.Second // expiryBufferFraction is used to compute a revised expiry time used by the prober to determine expired leases // Using a fraction allows the prober to intervene before KCM marks a node as unknown, but at the same time allowing @@ -39,28 +41,33 @@ const ( // Prober represents a probe to the Kube ApiServer of a shoot type Prober struct { - namespace string - config *papi.Config - scaler dwdScaler.Scaler - shootClientCreator ShootClientCreator - backOff *time.Timer - ctx context.Context - cancelFn context.CancelFunc - l logr.Logger + namespace string + config *papi.Config + workerNodeConditions map[string][]string + scaler dwdScaler.Scaler + seedClient client.Client + shootClientCreator shoot.ClientCreator + backOff *time.Timer + ctx context.Context + cancelFn context.CancelFunc + l logr.Logger + lastErr error // this is currently used only for unit tests } // NewProber creates a new Prober -func NewProber(parentCtx context.Context, namespace string, config *papi.Config, scaler dwdScaler.Scaler, shootClientCreator ShootClientCreator, logger logr.Logger) *Prober { +func NewProber(parentCtx context.Context, seedClient client.Client, namespace string, config *papi.Config, workerNodeConditions map[string][]string, scaler dwdScaler.Scaler, shootClientCreator shoot.ClientCreator, logger logr.Logger) *Prober { pLogger := logger.WithValues("shootNamespace", namespace) ctx, cancelFn := context.WithCancel(parentCtx) return &Prober{ - namespace: namespace, - config: config, - scaler: scaler, - shootClientCreator: shootClientCreator, - ctx: ctx, - cancelFn: cancelFn, - l: pLogger, + namespace: namespace, + config: config, + workerNodeConditions: workerNodeConditions, + scaler: scaler, + seedClient: seedClient, + shootClientCreator: shootClientCreator, + ctx: ctx, + cancelFn: cancelFn, + l: pLogger, } } @@ -85,37 +92,50 @@ func (p *Prober) Run() { wait.JitterUntilWithContext(p.ctx, p.probe, p.config.ProbeInterval.Duration, *p.config.BackoffJitterFactor, true) } -// GetConfig returns the probe config for the prober. -func (p *Prober) GetConfig() *papi.Config { - return p.config -} - func (p *Prober) probe(ctx context.Context) { p.backOffIfNeeded() - shootClient, err := p.setupProbeClient(ctx, p.namespace, p.config.KubeConfigSecretName) - if err != nil { - p.l.Error(err, "Failed to create shoot client using the KubeConfig secret, ignoring error, probe will be re-attempted") - return - } - err = p.probeAPIServer(shootClient) + err := p.probeAPIServer(ctx) if err != nil { + p.recordError(err, errors.ErrProbeAPIServer, "Failed to probe API server") p.l.Info("API server probe failed, Skipping lease probe and scaling operation", "err", err.Error()) return } p.l.Info("API server probe is successful, will conduct node lease probe") - candidateNodeLeases, err := p.probeNodeLeases(shootClient) + shootClient, err := p.setupProbeClient(ctx) if err != nil { + p.recordError(err, errors.ErrSetupProbeClient, "Failed to setup probe client") + p.l.Error(err, "Failed to create shoot client using the KubeConfig secret, ignoring error, probe will be re-attempted") return } + candidateNodeLeases, err := p.probeNodeLeases(ctx, shootClient) + if err != nil { + p.recordError(err, errors.ErrProbeNodeLease, "Failed to probe node leases") + p.l.Error(err, "Failed to probe node leases, ignoring error, probe will be re-attempted") + return + } + if len(candidateNodeLeases) != 1 { + p.checkAndTriggerScale(ctx, candidateNodeLeases) + } else { + p.l.Info("Skipping scaling operation as number of candidate node leases == 1") + } +} + +func (p *Prober) recordError(err error, code errors.ErrorCode, message string) { + p.lastErr = errors.WrapError(err, code, message) +} + +func (p *Prober) checkAndTriggerScale(ctx context.Context, candidateNodeLeases []coordinationv1.Lease) { // revive:disable:early-return if p.shouldPerformScaleUp(candidateNodeLeases) { - if err = p.scaler.ScaleUp(ctx); err != nil { + if err := p.scaler.ScaleUp(ctx); err != nil { + p.recordError(err, errors.ErrScaleUp, "Failed to scale up resources") p.l.Error(err, "Failed to scale up resources") } } else { p.l.Info("Lease probe failed, performing scale down operation if required") - if err = p.scaler.ScaleDown(ctx); err != nil { + if err := p.scaler.ScaleDown(ctx); err != nil { + p.recordError(err, errors.ErrScaleDown, "Failed to scale down resources") p.l.Error(err, "Failed to scale down resources") } return @@ -143,35 +163,77 @@ func (p *Prober) shouldPerformScaleUp(candidateNodeLeases []coordinationv1.Lease return shouldScaleUp } -func (p *Prober) setupProbeClient(ctx context.Context, namespace string, kubeConfigSecretName string) (kubernetes.Interface, error) { - shootClient, err := p.shootClientCreator.CreateClient(ctx, p.l, namespace, kubeConfigSecretName, p.config.ProbeTimeout.Duration) +func (p *Prober) setupProbeClient(ctx context.Context) (client.Client, error) { + shootClient, err := p.shootClientCreator.CreateClient(ctx, p.l, p.config.ProbeTimeout.Duration) if err != nil { + p.setBackOffIfThrottlingError(err) return nil, err } return shootClient, nil } -func (p *Prober) probeAPIServer(shootClient kubernetes.Interface) error { - _, err := shootClient.Discovery().ServerVersion() +func (p *Prober) probeAPIServer(ctx context.Context) error { + discoveryClient, err := p.shootClientCreator.CreateDiscoveryClient(ctx, p.l, p.config.ProbeTimeout.Duration) + if err != nil { + p.l.Error(err, "Failed to create discovery client, probe will be re-attempted") + p.setBackOffIfThrottlingError(err) + return err + } + _, err = discoveryClient.ServerVersion() p.setBackOffIfThrottlingError(err) return err } -func (p *Prober) probeNodeLeases(shootClient kubernetes.Interface) ([]coordinationv1.Lease, error) { - nodes, err := shootClient.CoreV1().Nodes().List(p.ctx, metav1.ListOptions{}) +func (p *Prober) probeNodeLeases(ctx context.Context, shootClient client.Client) ([]coordinationv1.Lease, error) { + nodeNames, err := p.getFilteredNodeNames(ctx, shootClient) if err != nil { + return nil, err + } + return p.getFilteredNodeLeases(ctx, shootClient, nodeNames) +} + +// getFilteredNodeNames filters nodes for which node leases should be eventually checked in the caller. This function filters out the nodes which are: +// 1. Not managed by MCM - these nodes will not be considered for lease probe. +// 2. Unhealthy (checked via node conditions) - these will not be considered for lease probe allowing MCM to replace these nodes. +// 3. If the corresponding Machine object for a node has its state set to Terminating or Failed, the node will not be considered for lease probe. +func (p *Prober) getFilteredNodeNames(ctx context.Context, shootClient client.Client) ([]string, error) { + nodes := &corev1.NodeList{} + if err := shootClient.List(ctx, nodes); err != nil { p.setBackOffIfThrottlingError(err) p.l.Error(err, "Failed to list nodes, will retry probe") return nil, err } - - nodeNames := sets.New[string]() + machines, err := p.getMachines(ctx) + if err != nil { + return nil, err + } + nodeNames := make([]string, 0, len(nodes.Items)) for _, node := range nodes.Items { - nodeNames.Insert(node.Name) + if util.IsNodeManagedByMCM(&node) && + util.IsNodeHealthyByConditions(&node, util.GetWorkerUnhealthyNodeConditions(&node, p.workerNodeConditions)) && + util.GetMachineNotInFailedOrTerminatingState(node.Name, machines) != nil { + nodeNames = append(nodeNames, node.Name) + } } + return nodeNames, nil +} - leases, err := shootClient.CoordinationV1().Leases(nodeLeaseNamespace).List(p.ctx, metav1.ListOptions{}) - if err != nil { +// getMachines will retrieve all machines in the shoot namespace for which this probe is running. +func (p *Prober) getMachines(ctx context.Context) ([]v1alpha1.Machine, error) { + machines := &v1alpha1.MachineList{} + if err := p.seedClient.List(ctx, machines, client.InNamespace(p.namespace)); err != nil { + p.setBackOffIfThrottlingError(err) + p.l.Error(err, "Failed to list machines, will retry probe") + return nil, err + } + return machines.Items, nil +} + +// getFilteredNodeLeases filters out node leases which are not created for given nodeNames. The nodes are filtered via getFilteredNodeNames. +// It is assumed that the node leases have the same name as the corresponding node name for which they are created. +func (p *Prober) getFilteredNodeLeases(ctx context.Context, shootClient client.Client, nodeNames []string) ([]coordinationv1.Lease, error) { + leases := &coordinationv1.LeaseList{} + if err := shootClient.List(ctx, leases, client.InNamespace(nodeLeaseNamespace)); err != nil { p.setBackOffIfThrottlingError(err) p.l.Error(err, "Failed to list leases, will retry probe") return nil, err @@ -179,13 +241,12 @@ func (p *Prober) probeNodeLeases(shootClient kubernetes.Interface) ([]coordinati var filteredLeases []coordinationv1.Lease for _, lease := range leases.Items { - // skip leases belonging to non-existing nodes - if nodeNames.Has(lease.Name) { // node leases have the same names as nodes + if slices.Contains(nodeNames, lease.Name) { + // node leases have the same names as nodes filteredLeases = append(filteredLeases, lease) } } - - return filteredLeases, err + return filteredLeases, nil } func (p *Prober) isLeaseExpired(lease coordinationv1.Lease) bool { @@ -211,7 +272,7 @@ func (p *Prober) doProbe(client kubernetes.Interface) error { } func (p *Prober) setBackOffIfThrottlingError(err error) { - if apierrors.IsTooManyRequests(err) { + if err != nil && apierrors.IsTooManyRequests(err) { p.l.V(4).Info("API server is throttled, backing off", "backOffDuration", backOffDurationForThrottledRequests.Seconds()) p.resetBackoff(backOffDurationForThrottledRequests) } @@ -223,3 +284,18 @@ func (p *Prober) resetBackoff(d time.Duration) { } p.backOff = time.NewTimer(d) } + +// AreWorkerNodeConditionsStale checks if the worker node conditions are up-to-date +func (p *Prober) AreWorkerNodeConditionsStale(newWorkerNodeConditions map[string][]string) bool { + return !reflect.DeepEqual(p.workerNodeConditions, newWorkerNodeConditions) +} + +// IsInBackOff checks if the prober is in backoff. Currently, this is only used for testing purposes. +func (p *Prober) IsInBackOff() bool { + return p.backOff != nil +} + +// GetConfig returns the probe config for the prober. Currently, this is only used for testing purposes. +func (p *Prober) GetConfig() *papi.Config { + return p.config +} diff --git a/internal/prober/prober_test.go b/internal/prober/prober_test.go index ffedcd46..37b1215b 100644 --- a/internal/prober/prober_test.go +++ b/internal/prober/prober_test.go @@ -9,13 +9,23 @@ package prober import ( "context" "errors" - "math" - "strconv" "testing" "time" + perrors "github.com/gardener/dependency-watchdog/internal/prober/errors" + k8sfakes "github.com/gardener/dependency-watchdog/internal/prober/fakes/k8s" + scalefakes "github.com/gardener/dependency-watchdog/internal/prober/fakes/scale" + shootfakes "github.com/gardener/dependency-watchdog/internal/prober/fakes/shoot" + "github.com/gardener/dependency-watchdog/internal/test" + "github.com/gardener/dependency-watchdog/internal/util" + "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" + "github.com/gardener/machine-controller-manager/pkg/util/provider/machineutils" + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/go-logr/logr" - "github.com/golang/mock/gomock" . "github.com/onsi/gomega" coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" @@ -25,180 +35,631 @@ import ( "k8s.io/utils/pointer" papi "github.com/gardener/dependency-watchdog/api/prober" - mockdiscovery "github.com/gardener/dependency-watchdog/internal/mock/client-go/discovery" - mockinterface "github.com/gardener/dependency-watchdog/internal/mock/client-go/kubernetes" - mockcoordinationv1 "github.com/gardener/dependency-watchdog/internal/mock/client-go/kubernetes/coordinationv1" - mockcorev1 "github.com/gardener/dependency-watchdog/internal/mock/client-go/kubernetes/corev1" - mockprober "github.com/gardener/dependency-watchdog/internal/mock/prober" - mockscaler "github.com/gardener/dependency-watchdog/internal/mock/prober/scaler" ) var ( - errFoo = errors.New("unknown error") - proberTestLogger = logr.Discard() - testProbeTimeout = metav1.Duration{Duration: 3 * time.Millisecond} - testProbeInterval = metav1.Duration{Duration: 3 * time.Millisecond} - expiredLeaseRenewTime = metav1.NewMicroTime(time.Now().Add(-(2 * time.Minute))) - nonExpiredLeaseRenewTime = metav1.NewMicroTime(time.Now().Add(-time.Second)) + testProbeTimeout = metav1.Duration{Duration: 100 * time.Millisecond} + testProbeInterval = metav1.Duration{Duration: 100 * time.Millisecond} + testSeedClientScheme = initializeTestScheme() ) -type probeTestMocks struct { - scaler *mockscaler.MockScaler - shootClientCreator *mockprober.MockShootClientCreator - kubernetes *mockinterface.MockInterface - discovery *mockdiscovery.MockDiscoveryInterface - coreV1 *mockcorev1.MockCoreV1Interface - coordinationV1 *mockcoordinationv1.MockCoordinationV1Interface - node *mockcorev1.MockNodeInterface - lease *mockcoordinationv1.MockLeaseInterface -} - -type probeTestCase struct { - name string - nodeList *corev1.NodeList - leaseList *coordinationv1.LeaseList - shootClientCreatorError error - discoveryError error - nodeListError error - leaseListError error - scaleUpError error - scaleDownError error - minScaleUpCount int - maxScaleUpCount int - minScaleDownCount int - maxScaleDownCount int +func initializeTestScheme() *runtime.Scheme { + seedClientScheme := *scheme.Scheme + _ = v1alpha1.AddToScheme(&seedClientScheme) + return &seedClientScheme } func TestAPIServerProbeFailure(t *testing.T) { - testCases := []probeTestCase{ - {name: "Unknown error is returned by api server", discoveryError: errFoo}, - {name: "Forbidden request error is returned by api server", discoveryError: apierrors.NewForbidden(schema.GroupResource{}, "test", errors.New("forbidden"))}, - {name: "Unauthorized request error is returned by api server", discoveryError: apierrors.NewUnauthorized("unauthorized")}, - {name: "Throttling error is returned by api server", discoveryError: apierrors.NewTooManyRequests("Too many requests", 10)}, + t.Parallel() + testCases := []struct { + name string + discoveryErr error + shouldBackOff bool + }{ + {name: "Forbidden request error is returned by api server", discoveryErr: apierrors.NewForbidden(schema.GroupResource{}, "test", errors.New("forbidden")), shouldBackOff: false}, + {name: "Unauthorized request error is returned by api server", discoveryErr: apierrors.NewUnauthorized("unauthorized"), shouldBackOff: false}, + {name: "Throttling error is returned by api server", discoveryErr: apierrors.NewTooManyRequests("Too many requests", 10), shouldBackOff: true}, } + g := NewWithT(t) for _, entry := range testCases { t.Run(entry.name, func(t *testing.T) { - mocks := createAndInitializeMocks(t, entry) + entry := entry + t.Parallel() + scc := shootfakes.NewFakeShootClientBuilder(k8sfakes.NewFakeDiscoveryClient(entry.discoveryErr), k8sfakes.NewFakeClientBuilder().Build()).Build() config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) + + p := NewProber(context.Background(), nil, test.DefaultNamespace, config, nil, nil, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertError(g, err, entry.discoveryErr, perrors.ErrProbeAPIServer) }) } } -func TestSuccessfulProbesShouldRunScaleUp(t *testing.T) { - leaseList := createNodeLeases([]metav1.MicroTime{nonExpiredLeaseRenewTime, nonExpiredLeaseRenewTime, expiredLeaseRenewTime, expiredLeaseRenewTime}) - nodeList := createNodes(len(leaseList.Items)) +func TestDiscoveryClientCreationFailed(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + discoveryClientCreationErr error + shouldBackOff bool + }{ + {name: "Forbidden request error is returned while creating discovery client", discoveryClientCreationErr: apierrors.NewForbidden(schema.GroupResource{}, "test", errors.New("forbidden")), shouldBackOff: false}, + {name: "Unauthorized request error is returned while creating discovery client", discoveryClientCreationErr: apierrors.NewUnauthorized("unauthorized"), shouldBackOff: false}, + {name: "Throttling error is returned while creating discovery client", discoveryClientCreationErr: apierrors.NewTooManyRequests("Too many requests", 10), shouldBackOff: true}, + } + g := NewWithT(t) + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + scc := shootfakes.NewFakeShootClientBuilder(nil, nil).WithDiscoveryClientCreationError(entry.discoveryClientCreationErr).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - testCases := []probeTestCase{ - {name: "Scale Up Succeeds", leaseList: leaseList, nodeList: nodeList, minScaleUpCount: 1, maxScaleUpCount: math.MaxInt8}, - {name: "Scale Up Fails", leaseList: leaseList, nodeList: nodeList, scaleUpError: errors.New("scale Up failed"), minScaleUpCount: 1, maxScaleUpCount: math.MaxInt8}, + p := NewProber(context.Background(), nil, test.DefaultNamespace, config, nil, nil, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertError(g, err, entry.discoveryClientCreationErr, perrors.ErrProbeAPIServer) + }) + } +} + +func TestClientCreationFailed(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + clientCreationErr error + shouldBackOff bool + }{ + {name: "Forbidden request error is returned while creating client", clientCreationErr: apierrors.NewForbidden(schema.GroupResource{}, "test", errors.New("forbidden")), shouldBackOff: false}, + {name: "Unauthorized request error is returned while creating client", clientCreationErr: apierrors.NewUnauthorized("unauthorized"), shouldBackOff: false}, + {name: "Throttling error is returned while creating client", clientCreationErr: apierrors.NewTooManyRequests("Too many requests", 10), shouldBackOff: true}, } + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) for _, entry := range testCases { t.Run(entry.name, func(t *testing.T) { - mocks := createAndInitializeMocks(t, entry) + entry := entry + t.Parallel() + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, nil).WithClientCreationError(entry.clientCreationErr).Build() config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) + + p := NewProber(context.Background(), nil, test.DefaultNamespace, config, nil, nil, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertError(g, err, entry.clientCreationErr, perrors.ErrSetupProbeClient) }) } } -func TestLeaseProbeShouldNotConsiderUnrelatedLeases(t *testing.T) { - leaseList1 := createNodeLeases([]metav1.MicroTime{nonExpiredLeaseRenewTime, expiredLeaseRenewTime, expiredLeaseRenewTime}) - leaseList2 := createNodeLeases([]metav1.MicroTime{expiredLeaseRenewTime, nonExpiredLeaseRenewTime, nonExpiredLeaseRenewTime}) +func TestNoScalingIfErrorInListingNodes(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + nodeListErr *apierrors.StatusError + areLeasesExpired bool + initialDeploymentReplicas int32 + shouldBackOff bool + }{ + {name: "no scale up should happen if error in listing nodes", nodeListErr: apierrors.NewInternalError(errors.New("test internal error")), areLeasesExpired: false, initialDeploymentReplicas: 0, shouldBackOff: false}, + {name: "no scale down should happen if error in listing nodes", nodeListErr: apierrors.NewTooManyRequests("Too many requests", 10), areLeasesExpired: true, initialDeploymentReplicas: 1, shouldBackOff: true}, + } + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{{Name: test.Node1Name, IsExpired: entry.areLeasesExpired}, {Name: test.Node2Name, IsExpired: entry.areLeasesExpired}}) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + + shootClient := initializeShootClientBuilder(nodes, leases).RecordErrorForObjectsWithGVK("List", "", corev1.SchemeGroupVersion.WithKind("Nodes"), entry.nodeListErr).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - testCases := []probeTestCase{ - {name: "Scale Up Succeeds", leaseList: leaseList1, nodeList: createNodes(1), minScaleUpCount: 1, maxScaleUpCount: math.MaxInt8}, - {name: "Scale Down Succeeds", leaseList: leaseList2, nodeList: createNodes(1), minScaleDownCount: 1, maxScaleDownCount: math.MaxInt8}, + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertError(g, err, entry.nodeListErr, perrors.ErrProbeNodeLease) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.initialDeploymentReplicas) + }) } +} +func TestNoScalingIfErrorInListingMachines(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + machineListErr *apierrors.StatusError + areLeasesExpired bool + initialDeploymentReplicas int32 + shouldBackOff bool + }{ + {name: "no scale up should happen if error in listing machines", machineListErr: apierrors.NewInternalError(errors.New("test internal error")), areLeasesExpired: false, initialDeploymentReplicas: 0, shouldBackOff: false}, + {name: "no scale down should happen if error in listing machines", machineListErr: apierrors.NewTooManyRequests("Too many requests", 10), areLeasesExpired: true, initialDeploymentReplicas: 1, shouldBackOff: true}, + } + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) for _, entry := range testCases { t.Run(entry.name, func(t *testing.T) { - mocks := createAndInitializeMocks(t, entry) + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{{Name: test.Node1Name, IsExpired: entry.areLeasesExpired}, {Name: test.Node2Name, IsExpired: entry.areLeasesExpired}}) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).RecordErrorForObjectsWithGVK("List", test.DefaultNamespace, corev1.SchemeGroupVersion.WithKind("Machines"), entry.machineListErr).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertError(g, err, entry.machineListErr, perrors.ErrProbeNodeLease) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.initialDeploymentReplicas) }) } } -func TestLeaseProbeFailureShouldRunScaleDown(t *testing.T) { - leaseList := createNodeLeases([]metav1.MicroTime{nonExpiredLeaseRenewTime, expiredLeaseRenewTime, expiredLeaseRenewTime, expiredLeaseRenewTime}) - nodeList := createNodes(len(leaseList.Items)) +func TestLeaseProbeShouldNotConsiderNodesNotManagedByMCM(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name, Annotations: map[string]string{machineutils.NotManagedByMCM: "true"}}, {Name: test.Node2Name, Annotations: map[string]string{machineutils.NotManagedByMCM: "true"}}, {Name: test.Node3Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine3Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node3Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{{Name: test.Node1Name, IsExpired: true}, {Name: test.Node2Name, IsExpired: true}, {Name: test.Node3Name, IsExpired: true}}) + scaleTargetDeployments := generateScaleTargetDeployments(1) + + g := NewWithT(t) - testCases := []probeTestCase{ - {name: "Scale Down Succeeds", leaseList: leaseList, nodeList: nodeList, minScaleDownCount: 1, maxScaleDownCount: math.MaxInt8}, - {name: "Scale Down Fails", leaseList: leaseList, nodeList: nodeList, scaleDownError: errors.New("scale Down failed"), minScaleDownCount: 1, maxScaleDownCount: math.MaxInt8}, + ctx := context.Background() + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + g.Expect(runProber(p, testProbeTimeout.Duration)).To(BeNil()) + g.Expect(p.IsClosed()).To(BeTrue()) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), 1) +} + +func TestLeaseProbeShouldNotConsiderFailedOrTerminatingMachines(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}, {Name: test.Node3Name}, {Name: test.Node4Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineFailed}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineTerminating}}, + {Name: test.Machine3Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node3Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine4Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node4Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + isLeaseExpired map[string]bool + initialDeploymentReplicas int32 + expectedDeploymentReplicas int32 + }{ + {name: "scale up decision should not consider failed machines", isLeaseExpired: map[string]bool{test.Node1Name: true, test.Node2Name: true, test.Node3Name: false, test.Node4Name: true}, initialDeploymentReplicas: 0, expectedDeploymentReplicas: 1}, + {name: "scale down decision should not consider terminating machines", isLeaseExpired: map[string]bool{test.Node1Name: false, test.Node2Name: false, test.Node3Name: true, test.Node4Name: true}, initialDeploymentReplicas: 1, expectedDeploymentReplicas: 0}, } + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) for _, entry := range testCases { t.Run(entry.name, func(t *testing.T) { - mocks := createAndInitializeMocks(t, entry) - config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: time.Minute}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{ + {Name: test.Node1Name, IsExpired: entry.isLeaseExpired[test.Node1Name]}, + {Name: test.Node2Name, IsExpired: entry.isLeaseExpired[test.Node2Name]}, + {Name: test.Node3Name, IsExpired: entry.isLeaseExpired[test.Node3Name]}, + {Name: test.Node4Name, IsExpired: entry.isLeaseExpired[test.Node4Name]}, + }) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + g.Expect(runProber(p, testProbeTimeout.Duration)).To(BeNil()) + g.Expect(p.IsClosed()).To(BeTrue()) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.expectedDeploymentReplicas) }) } } -func TestLeaseProbeListCallFailureShouldSkipScaling(t *testing.T) { - leaseList := createNodeLeases([]metav1.MicroTime{nonExpiredLeaseRenewTime, nonExpiredLeaseRenewTime, nonExpiredLeaseRenewTime}) - nodeList := createNodes(len(leaseList.Items)) +func TestLeaseProbeShouldNotConsiderUnhealthyNodes(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{ + {Name: test.Node1Name, Labels: map[string]string{util.WorkerPoolLabel: test.Worker1Name}, Conditions: []corev1.NodeCondition{{Type: test.NodeConditionDiskPressure, Status: corev1.ConditionTrue}}}, + {Name: test.Node2Name, Labels: map[string]string{util.WorkerPoolLabel: test.Worker1Name}, Conditions: []corev1.NodeCondition{{Type: test.NodeConditionMemoryPressure, Status: corev1.ConditionTrue}}}, + {Name: test.Node3Name, Labels: map[string]string{util.WorkerPoolLabel: test.Worker2Name}, Conditions: []corev1.NodeCondition{{Type: test.NodeConditionMemoryPressure, Status: corev1.ConditionTrue}}}, // This node will not be considered as unhealthy as the corresponding worker has DefaultUnhealthyNodeConditions which does not include MemoryPressure. + {Name: test.Node4Name, Labels: map[string]string{util.WorkerPoolLabel: test.Worker2Name}}, + }) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineUnknown}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineUnknown}}, + {Name: test.Machine3Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node3Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine4Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node4Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + isLeaseExpired map[string]bool + initialDeploymentReplicas int32 + expectedDeploymentReplicas int32 + }{ + {name: "scale up decision should not consider unhealthy nodes", isLeaseExpired: map[string]bool{test.Node1Name: true, test.Node2Name: true, test.Node3Name: false, test.Node4Name: true}, initialDeploymentReplicas: 0, expectedDeploymentReplicas: 1}, + {name: "scale down decision should not consider unhealthy nodes", isLeaseExpired: map[string]bool{test.Node1Name: false, test.Node2Name: false, test.Node3Name: true, test.Node4Name: true}, initialDeploymentReplicas: 1, expectedDeploymentReplicas: 0}, + } + + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{ + {Name: test.Node1Name, IsExpired: entry.isLeaseExpired[test.Node1Name]}, + {Name: test.Node2Name, IsExpired: entry.isLeaseExpired[test.Node2Name]}, + {Name: test.Node3Name, IsExpired: entry.isLeaseExpired[test.Node3Name]}, + {Name: test.Node4Name, IsExpired: entry.isLeaseExpired[test.Node4Name]}, + }) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, map[string][]string{test.Worker1Name: {test.NodeConditionDiskPressure, test.NodeConditionMemoryPressure}}, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) - testCases := []probeTestCase{ - {name: "Forbidden request error is returned by lease list call", nodeList: nodeList, leaseList: leaseList, leaseListError: apierrors.NewForbidden(schema.GroupResource{}, "test", errors.New("forbidden"))}, - {name: "Unauthorized request error is returned by lease list call", nodeList: nodeList, leaseList: leaseList, leaseListError: apierrors.NewUnauthorized("unauthorized")}, - {name: "Throttling error is returned by lease list call", nodeList: nodeList, leaseListError: apierrors.NewTooManyRequests("Too many requests", 10)}, - {name: "Throttling error is returned by node list call", nodeListError: apierrors.NewTooManyRequests("Too many requests", 10)}, + g.Expect(runProber(p, testProbeTimeout.Duration)).To(BeNil()) + g.Expect(p.IsClosed()).To(BeTrue()) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.expectedDeploymentReplicas) + }) } +} +func TestNoScalingIfErrorInListingLeases(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + leaseListErr *apierrors.StatusError + areLeasesExpired bool + initialDeploymentReplicas int32 + shouldBackOff bool + }{ + {name: "no scale up should happen if error in listing leases", leaseListErr: apierrors.NewInternalError(errors.New("test internal error")), initialDeploymentReplicas: 0, shouldBackOff: false}, + {name: "no scale down should happen if error in listing leases", leaseListErr: apierrors.NewTooManyRequests("Too many requests", 10), initialDeploymentReplicas: 1, shouldBackOff: true}, + } + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) for _, entry := range testCases { t.Run(entry.name, func(t *testing.T) { - mocks := createAndInitializeMocks(t, entry) + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{{Name: test.Node1Name, IsExpired: entry.areLeasesExpired}, {Name: test.Node2Name, IsExpired: entry.areLeasesExpired}}) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + shootClient := initializeShootClientBuilder(nodes, leases).RecordErrorForObjectsWithGVK("List", nodeLeaseNamespace, corev1.SchemeGroupVersion.WithKind("Leases"), entry.leaseListErr).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + assertError(g, err, entry.leaseListErr, perrors.ErrProbeNodeLease) + g.Expect(p.IsInBackOff()).To(Equal(entry.shouldBackOff)) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.initialDeploymentReplicas) }) } } -func TestAPIServerProbeShouldNotRunIfClientNotCreated(t *testing.T) { - err := errors.New("cannot create kubernetes client") - entry := probeTestCase{ - name: "api server probe should not run if client to access it is not created", - shootClientCreatorError: err, +func TestNoScalingInSingleNodeClusters(t *testing.T) { + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + isLeaseExpired bool + initialDeploymentReplicas int32 + }{ + {name: "no scale up should happen", isLeaseExpired: false, initialDeploymentReplicas: 0}, + {name: "no scale down should happen", isLeaseExpired: true, initialDeploymentReplicas: 1}, + } + g := NewWithT(t) + t.Parallel() + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{{Name: test.Node1Name, IsExpired: entry.isLeaseExpired}}) + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + shootClientCreator := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, shootClientCreator, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + g.Expect(err).To(BeNil()) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.initialDeploymentReplicas) + }) } - mocks := createAndInitializeMocks(t, entry) - config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) } -func TestScaleUpShouldHappenIfNoOwnedLeasesPresent(t *testing.T) { - entry := probeTestCase{ - name: "scale up should happen if no owned lease is present", - leaseList: createNodeLeases(nil), - nodeList: createNodes(0), - minScaleUpCount: 1, - maxScaleUpCount: math.MaxInt8, +func TestLeaseProbeShouldNotConsiderOrphanedLeases(t *testing.T) { + t.Parallel() + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + + testCases := []struct { + name string + isLeaseExpired map[string]bool + initialDeploymentReplicas int32 + expectedDeploymentReplicas int32 + }{ + {name: "scale up decision should not consider orphaned leases", isLeaseExpired: map[string]bool{test.Node1Name: false, test.Node2Name: true, test.Node3Name: true, test.Node4Name: true}, initialDeploymentReplicas: 0, expectedDeploymentReplicas: 1}, + {name: "scale down decision should not consider orphaned leases", isLeaseExpired: map[string]bool{test.Node1Name: true, test.Node2Name: true, test.Node3Name: false, test.Node4Name: false}, initialDeploymentReplicas: 1, expectedDeploymentReplicas: 0}, + } + + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + g := NewWithT(t) + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{ + {Name: test.Node1Name, IsExpired: entry.isLeaseExpired[test.Node1Name]}, + {Name: test.Node2Name, IsExpired: entry.isLeaseExpired[test.Node2Name]}, + {Name: test.Node3Name, IsExpired: entry.isLeaseExpired[test.Node3Name]}, + {Name: test.Node4Name, IsExpired: entry.isLeaseExpired[test.Node4Name]}, + }) + scaleTargetDeployments := generateScaleTargetDeployments(entry.initialDeploymentReplicas) + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, nil) + scc := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, scc, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + g.Expect(runProber(p, testProbeTimeout.Duration)).To(BeNil()) + g.Expect(p.IsClosed()).To(BeTrue()) + assertScale(ctx, g, seedClient, getDeploymentRefs(scaleTargetDeployments), entry.expectedDeploymentReplicas) + }) } - mocks := createAndInitializeMocks(t, entry) - config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) - createAndRunProber(t, testProbeInterval.Duration, config, mocks) } -func createAndRunProber(t *testing.T, duration time.Duration, config *papi.Config, interfaces probeTestMocks) { +func TestSuccessfulProbesShouldRunScaleUp(t *testing.T) { + t.Parallel() g := NewWithT(t) - p := NewProber(context.Background(), "default", config, interfaces.scaler, interfaces.shootClientCreator, proberTestLogger) - g.Expect(p.IsClosed()).To(BeFalse()) + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{ + {Name: test.Node1Name, IsExpired: false}, + {Name: test.Node2Name, IsExpired: false}, + }) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + scaleTargetDeployments := generateScaleTargetDeployments(0) + + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + shootClientCreator := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + + testCases := []struct { + name string + scaleUpErr error + }{ + {name: "Scale Up Succeeds"}, + {name: "Scale Up Fails", scaleUpErr: errors.New("scale up failed")}, + } - runProber(p, duration) - g.Expect(p.IsClosed()).To(BeTrue()) + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, entry.scaleUpErr, nil) + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, shootClientCreator, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + if entry.scaleUpErr != nil { + assertError(g, err, entry.scaleUpErr, perrors.ErrScaleUp) + } else { + g.Expect(err).To(BeNil()) + targetDeploymentRefs := getDeploymentRefs(scaleTargetDeployments) + assertScale(ctx, g, seedClient, targetDeploymentRefs, 1) + } + }) + } +} + +func TestLeaseProbeFailureShouldRunScaleDown(t *testing.T) { + t.Parallel() + g := NewWithT(t) + nodes := test.GenerateNodes([]test.NodeSpec{{Name: test.Node1Name}, {Name: test.Node2Name}}) + leases := test.GenerateNodeLeases([]test.NodeLeaseSpec{ + {Name: test.Node1Name, IsExpired: true}, + {Name: test.Node2Name, IsExpired: true}, + }) + machines := test.GenerateMachines([]test.MachineSpec{ + {Name: test.Machine1Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node1Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + {Name: test.Machine2Name, Labels: map[string]string{v1alpha1.NodeLabelKey: test.Node2Name}, CurrentStatus: v1alpha1.CurrentStatus{Phase: v1alpha1.MachineRunning}}, + }, test.DefaultNamespace) + scaleTargetDeployments := generateScaleTargetDeployments(1) + + shootClient := initializeShootClientBuilder(nodes, leases).Build() + seedClient := initializeSeedClientBuilder(machines, scaleTargetDeployments).Build() + shootDiscoveryClient := k8sfakes.NewFakeDiscoveryClient(nil) + shootClientCreator := shootfakes.NewFakeShootClientBuilder(shootDiscoveryClient, shootClient).Build() + + testCases := []struct { + name string + scaleDownErr error + }{ + {name: "Scale Down Succeeds"}, + {name: "Scale Down Fails", scaleDownErr: errors.New("scale down failed")}, + } + + for _, entry := range testCases { + t.Run(entry.name, func(t *testing.T) { + entry := entry + t.Parallel() + ctx := context.Background() + scaler := scalefakes.NewFakeScaler(seedClient, test.DefaultNamespace, nil, entry.scaleDownErr) + config := createConfig(testProbeInterval, metav1.Duration{Duration: time.Microsecond}, metav1.Duration{Duration: 40 * time.Second}, 0.2) + + p := NewProber(ctx, seedClient, test.DefaultNamespace, config, nil, scaler, shootClientCreator, logr.Discard()) + g.Expect(p.IsClosed()).To(BeFalse()) + + err := runProber(p, testProbeTimeout.Duration) + g.Expect(p.IsClosed()).To(BeTrue()) + if entry.scaleDownErr != nil { + assertError(g, err, entry.scaleDownErr, perrors.ErrScaleDown) + } else { + g.Expect(err).To(BeNil()) + targetDeploymentRefs := getDeploymentRefs(scaleTargetDeployments) + assertScale(ctx, g, seedClient, targetDeploymentRefs, 0) + } + }) + } +} + +//---------------------------------- Helper functions ---------------------------------- + +func getDeploymentRefs(deployments []*appsv1.Deployment) []client.ObjectKey { + refs := make([]client.ObjectKey, 0, len(deployments)) + for _, deploy := range deployments { + refs = append(refs, client.ObjectKeyFromObject(deploy)) + } + return refs } -func runProber(p *Prober, d time.Duration) { +func assertScale(ctx context.Context, g *WithT, client client.Client, targetDeploymentRefs []client.ObjectKey, expectedReplicas int32) { + for _, deployRef := range targetDeploymentRefs { + deploy := &appsv1.Deployment{} + g.Expect(client.Get(ctx, deployRef, deploy)).To(Succeed()) + g.Expect(deploy.Spec.Replicas).ToNot(BeNil()) + g.Expect(*deploy.Spec.Replicas).To(Equal(expectedReplicas)) + } +} + +func initializeShootClientBuilder(nodes []*corev1.Node, nodeLeases []*coordinationv1.Lease) *k8sfakes.FakeClientBuilder { + shootObjects := make([]client.Object, 0, len(nodes)+len(nodeLeases)) + for _, node := range nodes { + shootObjects = append(shootObjects, node) + } + for _, lease := range nodeLeases { + shootObjects = append(shootObjects, lease) + } + return k8sfakes.NewFakeClientBuilder(shootObjects...) +} + +func initializeSeedClientBuilder(machines []*v1alpha1.Machine, deployments []*appsv1.Deployment) *k8sfakes.FakeClientBuilder { + seedObjects := make([]client.Object, 0, len(machines)+len(deployments)) + for _, machine := range machines { + seedObjects = append(seedObjects, machine) + } + for _, deploy := range deployments { + seedObjects = append(seedObjects, deploy) + } + return k8sfakes.NewFakeClientBuilder(seedObjects...).WithScheme(testSeedClientScheme) +} + +func generateScaleTargetDeployments(replicas int32) []*appsv1.Deployment { + return []*appsv1.Deployment{ + test.GenerateDeployment(test.KCMDeploymentName, test.DefaultNamespace, test.DefaultImage, replicas, nil), + test.GenerateDeployment(test.MCMDeploymentName, test.DefaultNamespace, test.DefaultImage, replicas, nil), + test.GenerateDeployment(test.CADeploymentName, test.DefaultNamespace, test.DefaultImage, replicas, nil), + } +} + +func runProber(p *Prober, d time.Duration) (err error) { exitAfter := time.NewTimer(d) go p.Run() for { select { case <-exitAfter.C: + err = p.lastErr p.Close() return case <-p.ctx.Done(): @@ -207,34 +668,13 @@ func runProber(p *Prober, d time.Duration) { } } -func createAndInitializeMocks(t *testing.T, testCase probeTestCase) probeTestMocks { - ctrl := gomock.NewController(t) - mocks := probeTestMocks{ - scaler: mockscaler.NewMockScaler(ctrl), - shootClientCreator: mockprober.NewMockShootClientCreator(ctrl), - kubernetes: mockinterface.NewMockInterface(ctrl), - discovery: mockdiscovery.NewMockDiscoveryInterface(ctrl), - coreV1: mockcorev1.NewMockCoreV1Interface(ctrl), - coordinationV1: mockcoordinationv1.NewMockCoordinationV1Interface(ctrl), - node: mockcorev1.NewMockNodeInterface(ctrl), - lease: mockcoordinationv1.NewMockLeaseInterface(ctrl), - } - initializeMocks(mocks, testCase) - return mocks -} - -func initializeMocks(mocks probeTestMocks, testCase probeTestCase) { - mocks.shootClientCreator.EXPECT().CreateClient(gomock.Any(), proberTestLogger, gomock.Any(), gomock.Any(), gomock.Any()).Return(mocks.kubernetes, testCase.shootClientCreatorError).AnyTimes() - mocks.kubernetes.EXPECT().Discovery().Return(mocks.discovery).AnyTimes() - mocks.kubernetes.EXPECT().CoreV1().Return(mocks.coreV1).AnyTimes() - mocks.kubernetes.EXPECT().CoordinationV1().Return(mocks.coordinationV1).AnyTimes() - mocks.coreV1.EXPECT().Nodes().Return(mocks.node).AnyTimes() - mocks.coordinationV1.EXPECT().Leases(nodeLeaseNamespace).Return(mocks.lease).AnyTimes() - mocks.node.EXPECT().List(gomock.Any(), gomock.Any()).Return(testCase.nodeList, testCase.nodeListError).AnyTimes() - mocks.lease.EXPECT().List(gomock.Any(), gomock.Any()).Return(testCase.leaseList, testCase.leaseListError).AnyTimes() - mocks.discovery.EXPECT().ServerVersion().Return(nil, testCase.discoveryError).AnyTimes() - mocks.scaler.EXPECT().ScaleUp(gomock.Any()).Return(testCase.scaleUpError).MaxTimes(testCase.maxScaleUpCount).MinTimes(testCase.minScaleUpCount) - mocks.scaler.EXPECT().ScaleDown(gomock.Any()).Return(testCase.scaleDownError).MaxTimes(testCase.maxScaleDownCount).MinTimes(testCase.minScaleDownCount) +func assertError(g *WithT, err error, expectedError error, expectedErrorCode perrors.ErrorCode) { + g.Expect(err).To(HaveOccurred()) + probeErr := &perrors.ProbeError{} + if errors.As(err, &probeErr) { + g.Expect(probeErr.Code).To(Equal(expectedErrorCode)) + g.Expect(probeErr.Cause).To(Equal(expectedError)) + } } func createConfig(probeInterval metav1.Duration, initialDelay metav1.Duration, kcmNodeMonitorGraceDuration metav1.Duration, backoffJitterFactor float64) *papi.Config { @@ -247,55 +687,3 @@ func createConfig(probeInterval metav1.Duration, initialDelay metav1.Duration, k NodeLeaseFailureFraction: pointer.Float64(DefaultNodeLeaseFailureFraction), } } - -func createNodeLeases(renewTimes []metav1.MicroTime) (leaseList *coordinationv1.LeaseList) { - var items []coordinationv1.Lease - for i, renewTime := range renewTimes { - items = append(items, createNodeLease(name(i), renewTime)) - } - return &coordinationv1.LeaseList{ - Items: items, - } -} - -func createNodes(count int) (nodeList *corev1.NodeList) { - var items []corev1.Node - for i := 0; i < count; i++ { - items = append(items, createNode(name(i))) - } - return &corev1.NodeList{ - Items: items, - } -} - -func name(i int) string { - return "lease-" + strconv.Itoa(i) -} - -func createNodeLease(name string, renewTime metav1.MicroTime) coordinationv1.Lease { - return coordinationv1.Lease{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: "kube-node-lease", - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "Node", - Name: name, - }, - }, - }, - Spec: coordinationv1.LeaseSpec{ - HolderIdentity: &name, - RenewTime: &renewTime, - }, - } -} - -func createNode(name string) corev1.Node { - return corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - } -} diff --git a/internal/prober/probermgr.go b/internal/prober/probermgr.go index b84ff5e6..dbd8be06 100644 --- a/internal/prober/probermgr.go +++ b/internal/prober/probermgr.go @@ -4,7 +4,9 @@ package prober -import "sync" +import ( + "sync" +) // Manager is the convenience interface to manage lifecycle of probers. type Manager interface { diff --git a/internal/prober/probermgr_test.go b/internal/prober/probermgr_test.go index 617016cb..82302b27 100644 --- a/internal/prober/probermgr_test.go +++ b/internal/prober/probermgr_test.go @@ -37,7 +37,7 @@ func TestRegisterNewProberAndCheckIfItExistsAndIsNotClosed(t *testing.T) { mgr, tearDownTest := setupMgrTest(t) defer tearDownTest(mgr) - p := NewProber(context.Background(), proberMgrTestNamespace, &papi.Config{}, nil, nil, pmLogger) + p := NewProber(context.Background(), nil, proberMgrTestNamespace, &papi.Config{}, nil, nil, nil, pmLogger) g.Expect(p).ShouldNot(BeNil(), "NewProber should have returned a non nil Prober") g.Expect(p.namespace).Should(Equal(proberMgrTestNamespace), "The namespace of the created prober should match") g.Expect(mgr.Register(*p)).To(BeTrue(), "mgr.Register should register a new prober") @@ -56,10 +56,10 @@ func TestProberRegistrationWithSameKeyShouldNotOverwriteExistingProber(t *testin mgr, tearDownTest := setupMgrTest(t) defer tearDownTest(mgr) - p1 := NewProber(context.Background(), proberMgrTestNamespace, &papi.Config{KubeConfigSecretName: "bingo"}, nil, nil, pmLogger) + p1 := NewProber(context.Background(), nil, proberMgrTestNamespace, &papi.Config{KubeConfigSecretName: "bingo"}, nil, nil, nil, pmLogger) g.Expect(mgr.Register(*p1)).To(BeTrue(), "mgr.Register should register a new prober") - p2 := NewProber(context.Background(), proberMgrTestNamespace, &papi.Config{KubeConfigSecretName: "zingo"}, nil, nil, pmLogger) + p2 := NewProber(context.Background(), nil, proberMgrTestNamespace, &papi.Config{KubeConfigSecretName: "zingo"}, nil, nil, nil, pmLogger) g.Expect(mgr.Register(*p2)).To(BeFalse(), "mgr.Register should return false if a prober with the same key is already registered") foundProber, ok := mgr.GetProber(proberMgrTestNamespace) @@ -75,7 +75,7 @@ func TestUnregisterExistingProberShouldCloseItAndRemoveItFromManager(t *testing. mgr, tearDownTest := setupMgrTest(t) defer tearDownTest(mgr) - p := NewProber(context.Background(), proberMgrTestNamespace, &papi.Config{}, nil, nil, pmLogger) + p := NewProber(context.Background(), nil, proberMgrTestNamespace, &papi.Config{}, nil, nil, nil, pmLogger) g.Expect(mgr.Register(*p)).To(BeTrue(), "mgr.Register should register a new prober") mgr.Unregister(proberMgrTestNamespace) diff --git a/internal/prober/scaler/.import-restrictions b/internal/prober/scaler/.import-restrictions index b3b64425..98674604 100644 --- a/internal/prober/scaler/.import-restrictions +++ b/internal/prober/scaler/.import-restrictions @@ -7,5 +7,5 @@ rules: - github.com/gardener/dependency-watchdog/api - github.com/gardener/dependency-watchdog/internal/util - github.com/gardener/dependency-watchdog/internal/test - - github.com/gardener/dependency-watchdog/internal/mock + - github.com/gardener/dependency-watchdog/internal/fakes - github.com/gardener/dependency-watchdog/internal/prober/scaler diff --git a/internal/prober/scaler/flow_test.go b/internal/prober/scaler/flow_test.go index fe064ddb..7f5231ac 100644 --- a/internal/prober/scaler/flow_test.go +++ b/internal/prober/scaler/flow_test.go @@ -11,8 +11,6 @@ import ( "github.com/go-logr/logr" - "github.com/gardener/dependency-watchdog/internal/mock/client-go/scale" - "github.com/gardener/dependency-watchdog/internal/mock/controller-runtime/client" "github.com/gardener/gardener/pkg/utils/flow" . "github.com/onsi/gomega" @@ -34,7 +32,7 @@ func TestCreateScaleUpSequentialFlow(t *testing.T) { flowName := "testCreateSequentialFlow" namespace := "test-sequential" - fc := newFlowCreator(&client.MockClient{}, &scale.MockScaleInterface{}, flowTestLogger, &scalerOptions{}, depResInfos) + fc := newFlowCreator(nil, nil, flowTestLogger, &scalerOptions{}, depResInfos) f := fc.createFlow(flowName, namespace, scaleUp) g.Expect(f.flowStepInfos).To(HaveLen(3)) @@ -68,7 +66,7 @@ func TestCreateScaleDownSequentialAndConcurrentFlow(t *testing.T) { flowName := "testCreateSequentialAndConcurrentFlow" namespace := "test-sequential-and-concurrent" - fc := newFlowCreator(&client.MockClient{}, &scale.MockScaleInterface{}, flowTestLogger, &scalerOptions{}, depResInfos) + fc := newFlowCreator(nil, nil, flowTestLogger, &scalerOptions{}, depResInfos) f := fc.createFlow(flowName, namespace, scaleDown) g.Expect(f.flowStepInfos).To(HaveLen(2)) diff --git a/internal/prober/shoot/client.go b/internal/prober/shoot/client.go new file mode 100644 index 00000000..0f942559 --- /dev/null +++ b/internal/prober/shoot/client.go @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 + +package shoot + +import ( + "context" + "fmt" + "time" + + "k8s.io/client-go/discovery" + + "github.com/gardener/dependency-watchdog/internal/util" + "github.com/go-logr/logr" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + defaultGetSecretBackoff = 100 * time.Millisecond + defaultGetSecretMaxAttempts = 3 +) + +// ClientCreator provides a facade to create kubernetes client targeting a shoot. +type ClientCreator interface { + // CreateClient creates a new client.Client to connect to the Kube ApiServer running in the passed-in shoot control namespace. + CreateClient(ctx context.Context, logger logr.Logger, connectionTimeout time.Duration) (client.Client, error) + // CreateDiscoveryClient creates a new discovery.DiscoveryInterface to connect to the Kube ApiServer running in the passed-in shoot control namespace. + CreateDiscoveryClient(ctx context.Context, logger logr.Logger, connectionTimeout time.Duration) (discovery.DiscoveryInterface, error) +} + +// NewClientCreator creates an instance of ClientCreator. +func NewClientCreator(namespace string, secretName string, client client.Client) ClientCreator { + return &clientCreator{ + namespace: namespace, + secretName: secretName, + client: client, + } +} + +type clientCreator struct { + namespace string + secretName string + client client.Client +} + +func (s *clientCreator) CreateClient(ctx context.Context, logger logr.Logger, connectionTimeout time.Duration) (client.Client, error) { + kubeConfigBytes, err := s.getKubeConfigBytesFromSecret(ctx, logger) + if err != nil { + return nil, err + } + return util.CreateClientFromKubeConfigBytes(kubeConfigBytes, connectionTimeout) +} + +func (s *clientCreator) CreateDiscoveryClient(ctx context.Context, logger logr.Logger, connectionTimeout time.Duration) (discovery.DiscoveryInterface, error) { + kubeConfigBytes, err := s.getKubeConfigBytesFromSecret(ctx, logger) + if err != nil { + return nil, err + } + return util.CreateDiscoveryInterfaceFromKubeConfigBytes(kubeConfigBytes, connectionTimeout) +} + +func (s *clientCreator) getKubeConfigBytesFromSecret(ctx context.Context, logger logr.Logger) ([]byte, error) { + operation := fmt.Sprintf("get-secret-%s-for-namespace-%s", s.secretName, s.namespace) + retryResult := util.Retry(ctx, logger, + operation, + func() ([]byte, error) { + return util.GetKubeConfigFromSecret(ctx, s.namespace, s.secretName, s.client, logger) + }, + defaultGetSecretMaxAttempts, + defaultGetSecretBackoff, + canRetrySecretGet) + if retryResult.Err != nil { + return nil, retryResult.Err + } + return retryResult.Value, nil +} + +func canRetrySecretGet(err error) bool { + return !apierrors.IsNotFound(err) +} diff --git a/internal/prober/shoot/client_test.go b/internal/prober/shoot/client_test.go new file mode 100644 index 00000000..f03e0db2 --- /dev/null +++ b/internal/prober/shoot/client_test.go @@ -0,0 +1,124 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 + +//go:build !kind_tests + +package shoot + +import ( + "context" + "path/filepath" + "testing" + "time" + + "k8s.io/apimachinery/pkg/util/rand" + + "github.com/gardener/dependency-watchdog/internal/prober/fakes/k8s" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/gardener/dependency-watchdog/internal/test" + "github.com/go-logr/logr" + . "github.com/onsi/gomega" + + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +var ( + secretPath = filepath.Join("testdata", "secret.yaml") + kubeConfigPath = filepath.Join("testdata", "kubeconfig.yaml") + //envTest test.ControllerTestEnv +) + +func TestSuite(t *testing.T) { + var err error + g := NewWithT(t) + testCases := []struct { + name string + description string + run func(ctx context.Context, t *testing.T, namespace string, k8sClient client.Client) + }{ + {"testSecretNotFound", "secret not found", testSecretNotFound}, + {"testConfigNotFound", "kubeconfig not found", testConfigNotFound}, + {"testCreateShootClient", "shootclient should be created", testCreateShootClient}, + {"testCreateDiscoveryClient", "discoveryclient should be created", testCreateDiscoveryClient}, + } + g.Expect(err).ToNot(HaveOccurred()) + t.Parallel() + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + ctx := context.Background() + k8sClient := k8s.NewFakeClientBuilder().Build() + testNs := rand.String(4) + test.CreateTestNamespace(ctx, g, k8sClient, testNs) + tc.run(ctx, t, testNs, k8sClient) + }) + } +} + +func testSecretNotFound(ctx context.Context, t *testing.T, namespace string, k8sClient client.Client) { + g := NewWithT(t) + cc := NewClientCreator(namespace, "does-not-exist", k8sClient) + k8sInterface, err := cc.CreateClient(ctx, logr.Discard(), time.Second) + g.Expect(apierrors.IsNotFound(err)).To(BeTrue()) + g.Expect(k8sInterface).To(BeNil()) +} + +func testConfigNotFound(ctx context.Context, t *testing.T, namespace string, k8sClient client.Client) { + g := NewWithT(t) + secretName, cleanupFn := createSecret(ctx, g, secretPath, namespace, nil, k8sClient) + defer cleanupFn() + cc := NewClientCreator(namespace, secretName, k8sClient) + shootClient, err := cc.CreateClient(ctx, logr.Discard(), time.Second) + g.Expect(err).To(HaveOccurred()) + g.Expect(apierrors.IsNotFound(err)).To(BeFalse()) + g.Expect(shootClient).To(BeNil()) +} + +func testCreateShootClient(ctx context.Context, t *testing.T, namespace string, k8sClient client.Client) { + g := NewWithT(t) + + kubeConfig, err := test.ReadFile(kubeConfigPath) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(kubeConfig).ToNot(BeNil()) + secretName, cleanupFn := createSecret(ctx, g, secretPath, namespace, map[string][]byte{"kubeconfig": kubeConfig.Bytes()}, k8sClient) + defer cleanupFn() + + cc := NewClientCreator(namespace, secretName, k8sClient) + shootClient, err := cc.CreateClient(ctx, logr.Discard(), time.Second) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(shootClient).ToNot(BeNil()) +} + +func testCreateDiscoveryClient(ctx context.Context, t *testing.T, namespace string, k8sClient client.Client) { + g := NewWithT(t) + + kubeConfig, err := test.ReadFile(kubeConfigPath) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(kubeConfig).ToNot(BeNil()) + secretName, cleanupFn := createSecret(ctx, g, secretPath, namespace, map[string][]byte{"kubeconfig": kubeConfig.Bytes()}, k8sClient) + defer cleanupFn() + + cc := NewClientCreator(namespace, secretName, k8sClient) + discoveryClient, err := cc.CreateDiscoveryClient(ctx, logr.Discard(), time.Second) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(discoveryClient).ToNot(BeNil()) +} + +func createSecret(ctx context.Context, g *WithT, path, namespace string, data map[string][]byte, k8sClient client.Client) (secretName string, cleanupFn func()) { + test.FileExistsOrFail(path) + secret, err := test.GetStructured[corev1.Secret](path) + g.Expect(err).ToNot(HaveOccurred()) + secret.ObjectMeta.Namespace = namespace + secret.Data = data + g.Expect(secret).ToNot(BeNil()) + // create the secret + g.Expect(k8sClient.Create(ctx, secret)).ToNot(HaveOccurred()) + + secretName = secret.Name + cleanupFn = func() { + g.Expect(client.IgnoreNotFound(k8sClient.Delete(ctx, secret))).To(BeNil()) + } + return +} diff --git a/internal/prober/testdata/kubeconfig.yaml b/internal/prober/shoot/testdata/kubeconfig.yaml similarity index 100% rename from internal/prober/testdata/kubeconfig.yaml rename to internal/prober/shoot/testdata/kubeconfig.yaml diff --git a/internal/prober/testdata/secret.yaml b/internal/prober/shoot/testdata/secret.yaml similarity index 100% rename from internal/prober/testdata/secret.yaml rename to internal/prober/shoot/testdata/secret.yaml diff --git a/internal/prober/shootclient.go b/internal/prober/shootclient.go deleted file mode 100644 index c70f349f..00000000 --- a/internal/prober/shootclient.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -package prober - -import ( - "context" - "fmt" - "time" - - "github.com/gardener/dependency-watchdog/internal/util" - "github.com/go-logr/logr" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/client-go/kubernetes" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// ShootClientCreator provides a facade to create kubernetes client targeting a shoot. -type ShootClientCreator interface { - // CreateClient creates a new clientSet to connect to the Kube ApiServer running in the passed-in shoot control namespace. - CreateClient(ctx context.Context, logger logr.Logger, namespace string, secretName string, connectionTimeout time.Duration) (kubernetes.Interface, error) -} - -// NewShootClientCreator creates an instance of ShootClientCreator. -func NewShootClientCreator(client client.Client) ShootClientCreator { - return &shootClientCreator{client} -} - -type shootClientCreator struct { - client.Client -} - -func (s *shootClientCreator) CreateClient(ctx context.Context, logger logr.Logger, namespace string, secretName string, connectionTimeout time.Duration) (kubernetes.Interface, error) { - operation := fmt.Sprintf("get-secret-%s-for-namespace-%s", secretName, namespace) - retryResult := util.Retry(ctx, logger, - operation, - func() ([]byte, error) { - return util.GetKubeConfigFromSecret(ctx, namespace, secretName, s.Client, logger) - }, - defaultGetSecretMaxAttempts, - defaultGetSecretBackoff, - canRetrySecretGet) - if retryResult.Err != nil { - return nil, retryResult.Err - } - return util.CreateClientFromKubeConfigBytes(retryResult.Value, connectionTimeout) -} - -func canRetrySecretGet(err error) bool { - return !apierrors.IsNotFound(err) -} diff --git a/internal/prober/shootclient_test.go b/internal/prober/shootclient_test.go deleted file mode 100644 index bb439dd9..00000000 --- a/internal/prober/shootclient_test.go +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors -// -// SPDX-License-Identifier: Apache-2.0 - -//go:build !kind_tests - -package prober - -import ( - "context" - "path/filepath" - "strings" - "testing" - "time" - - testenv "github.com/gardener/dependency-watchdog/internal/test" - "k8s.io/client-go/kubernetes/scheme" - - "github.com/go-logr/logr" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var ( - secretPath = filepath.Join("testdata", "secret.yaml") - kubeConfigPath = filepath.Join("testdata", "kubeconfig.yaml") - envTest testenv.ControllerTestEnv - sk8sClient client.Client - sctx = context.Background() - secret *corev1.Secret - clientCreator ShootClientCreator - shootClientTestLogger = logr.Discard() -) - -func TestSuite(t *testing.T) { - var err error - g := NewWithT(t) - tests := []struct { - name string - description string - run func(t *testing.T, namespace string) - }{ - {"testSecretNotFound", "secret not found", testSecretNotFound}, - {"testConfigNotFound", "kubeconfig not found", testConfigNotFound}, - {"testCreateShootClient", "shootclient should be created", testCreateShootClient}, - } - envTest, err = testenv.CreateDefaultControllerTestEnv(scheme.Scheme, nil) - g.Expect(err).ToNot(HaveOccurred()) - sk8sClient = envTest.GetClient() - for _, test := range tests { - ns := testenv.CreateTestNamespace(context.Background(), g, sk8sClient, strings.ToLower(test.name)) - t.Run(test.description, func(t *testing.T) { - test.run(t, ns) - }) - } - envTest.Delete() -} - -func testSecretNotFound(t *testing.T, namespace string) { - g := NewWithT(t) - setupShootClientTest(t, namespace) - k8sInterface, err := clientCreator.CreateClient(sctx, shootClientTestLogger, secret.ObjectMeta.Namespace, secret.ObjectMeta.Name, time.Second) - g.Expect(apierrors.IsNotFound(err)).To(BeTrue()) - g.Expect(k8sInterface).ToNot(HaveOccurred()) -} - -func testConfigNotFound(t *testing.T, namespace string) { - g := NewWithT(t) - teardown := setupShootClientTest(t, namespace) - defer teardown() - err := sk8sClient.Create(sctx, secret) - g.Expect(err).ToNot(HaveOccurred()) - shootClient, err := clientCreator.CreateClient(sctx, shootClientTestLogger, secret.ObjectMeta.Namespace, secret.ObjectMeta.Name, time.Second) - g.Expect(err).To(HaveOccurred()) - g.Expect(apierrors.IsNotFound(err)).To(BeFalse()) - g.Expect(shootClient).ToNot(HaveOccurred()) - -} - -func testCreateShootClient(t *testing.T, namespace string) { - g := NewWithT(t) - teardown := setupShootClientTest(t, namespace) - defer teardown() - kubeconfig, err := testenv.ReadFile(kubeConfigPath) - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(kubeconfig).ToNot(BeNil()) - secret.Data = map[string][]byte{ - "kubeconfig": kubeconfig.Bytes(), - } - err = sk8sClient.Create(sctx, secret) - g.Expect(err).ToNot(HaveOccurred()) - - shootClient, err := clientCreator.CreateClient(sctx, shootClientTestLogger, secret.ObjectMeta.Namespace, secret.ObjectMeta.Name, time.Second) - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(shootClient).ToNot(BeNil()) -} - -func setupShootClientTest(t *testing.T, namespace string) func() { - var err error - g := NewWithT(t) - testenv.FileExistsOrFail(secretPath) - secret, err = testenv.GetStructured[corev1.Secret](secretPath) - secret.ObjectMeta.Namespace = namespace - g.Expect(err).ToNot(HaveOccurred()) - g.Expect(secret).ToNot(BeNil()) - clientCreator = NewShootClientCreator(sk8sClient) - - return func() { - err := sk8sClient.Delete(sctx, secret) - g.Expect(err).ShouldNot(HaveOccurred()) - } -} diff --git a/internal/prober/types/doc.go b/internal/prober/types/doc.go new file mode 100644 index 00000000..6a1ac913 --- /dev/null +++ b/internal/prober/types/doc.go @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 + +// Package types contains the API definitions for the dependency-watchdog prober. +// These apis are not meant to be exposed for direct consumption outside this project +package types diff --git a/internal/prober/types/types.go b/internal/prober/types/types.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/internal/prober/types/types.go @@ -0,0 +1 @@ +package types diff --git a/internal/test/cluster.go b/internal/test/cluster.go index cedd1942..3c36dbb1 100644 --- a/internal/test/cluster.go +++ b/internal/test/cluster.go @@ -5,20 +5,54 @@ package test import ( - "fmt" - "math/rand" - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" gardenerv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/json" + "k8s.io/apimachinery/pkg/util/rand" "k8s.io/utils/pointer" ) -// CreateClusterResource creates a test cluster and shoot resources. -// This should only be used for unit testing. -func CreateClusterResource(numWorkers int, nodeMonitorGracePeriod *metav1.Duration, rawShoot bool) (*gardenerv1alpha1.Cluster, *gardencorev1beta1.Shoot, error) { +// ClusterBuilder is a builder for the cluster resource. +type ClusterBuilder struct { + numWorkers int + nodeMonitorGracePeriod *metav1.Duration + rawShoot bool + workerNodeConditions [][]string +} + +// NewClusterBuilder creates a new instance of ClusterBuilder. +func NewClusterBuilder() *ClusterBuilder { + return &ClusterBuilder{} +} + +// WithWorkerCount sets the worker count for the cluster. +func (b *ClusterBuilder) WithWorkerCount(workerCount int) *ClusterBuilder { + b.numWorkers = workerCount + return b +} + +// WithNodeMonitorGracePeriod sets the node monitor grace period for the cluster. +func (b *ClusterBuilder) WithNodeMonitorGracePeriod(nodeMonitorGracePeriod *metav1.Duration) *ClusterBuilder { + b.nodeMonitorGracePeriod = nodeMonitorGracePeriod + return b +} + +// WithRawShoot sets the raw shoot for the cluster. +func (b *ClusterBuilder) WithRawShoot(rawShoot bool) *ClusterBuilder { + b.rawShoot = rawShoot + return b +} + +// WithWorkerNodeConditions sets the worker node conditions for the cluster. +func (b *ClusterBuilder) WithWorkerNodeConditions(workerNodeConditions [][]string) *ClusterBuilder { + b.workerNodeConditions = workerNodeConditions + return b +} + +// Build builds the cluster resource. +func (b *ClusterBuilder) Build() (*gardenerv1alpha1.Cluster, *gardencorev1beta1.Shoot, error) { cloudProfile := gardencorev1beta1.CloudProfile{ ObjectMeta: metav1.ObjectMeta{ Name: "aws", @@ -42,8 +76,8 @@ func CreateClusterResource(numWorkers int, nodeMonitorGracePeriod *metav1.Durati }, }, } - shoot := CreateShoot(seed.Name, numWorkers, nodeMonitorGracePeriod) - if rawShoot { + shoot := createShoot(seed.Name, b.numWorkers, b.workerNodeConditions, b.nodeMonitorGracePeriod) + if b.rawShoot { shootBytes, err := json.Marshal(shoot) if err != nil { return nil, nil, err @@ -55,9 +89,9 @@ func CreateClusterResource(numWorkers int, nodeMonitorGracePeriod *metav1.Durati return &cluster, &shoot, nil } -// CreateShoot creates a shoot resources. +// createShoot creates a shoot resources. // This should only be used for unit testing. -func CreateShoot(seedName string, numWorkers int, nodeMonitorGracePeriod *metav1.Duration) gardencorev1beta1.Shoot { +func createShoot(seedName string, workerCount int, workerNodeConditions [][]string, nodeMonitorGracePeriod *metav1.Duration) gardencorev1beta1.Shoot { end := "00 08 * * 1,2,3,4,5" start := "30 19 * * 1,2,3,4,5" location := "Asia/Calcutta" @@ -80,7 +114,7 @@ func CreateShoot(seedName string, numWorkers int, nodeMonitorGracePeriod *metav1 }, Provider: gardencorev1beta1.Provider{ Type: "aws", - Workers: createWorkers(numWorkers), + Workers: createWorkers(workerCount, workerNodeConditions), }, }, Status: gardencorev1beta1.ShootStatus{ @@ -94,16 +128,22 @@ func CreateShoot(seedName string, numWorkers int, nodeMonitorGracePeriod *metav1 } } -func createWorkers(numWorkers int) []gardencorev1beta1.Worker { - workers := make([]gardencorev1beta1.Worker, 0, numWorkers) - for i := 0; i < numWorkers; i++ { - mx := rand.Int31n(5) +// createWorkers creates worker resources with the given count and corresponding node conditions. +func createWorkers(workerCount int, workerNodeConditions [][]string) []gardencorev1beta1.Worker { + workers := make([]gardencorev1beta1.Worker, 0, workerCount) + for i := 0; i < workerCount; i++ { + mx := rand.Intn(5) w := gardencorev1beta1.Worker{ - Name: fmt.Sprintf("worker-pool-%d", i), + Name: rand.String(4), Machine: gardencorev1beta1.Machine{}, - Maximum: mx, + Maximum: int32(mx), Minimum: 1, } + if i < len(workerNodeConditions) { + w.MachineControllerManagerSettings = &gardencorev1beta1.MachineControllerManagerSettings{ + NodeConditions: workerNodeConditions[i], + } + } workers = append(workers, w) } return workers diff --git a/internal/test/constants.go b/internal/test/constants.go new file mode 100644 index 00000000..4b6351c3 --- /dev/null +++ b/internal/test/constants.go @@ -0,0 +1,42 @@ +package test + +// DefaultNamespace is the default namespace used in tests +const DefaultNamespace = "test" + +// Constants for node conditions +const ( + NodeConditionDiskPressure = "DiskPressure" + NodeConditionMemoryPressure = "MemoryPressure" + NodeConditionPIDPressure = "PIDPressure" + NodeConditionNetworkReady = "NetworkReady" +) + +// Constants for worker names +const ( + Worker1Name = "worker-1" + Worker2Name = "worker-2" +) + +// Constants for deployments +const ( + MCMDeploymentName = "machine-controller-manager" + KCMDeploymentName = "kube-controller-manager" + CADeploymentName = "cluster-autoscaler" + DefaultImage = "registry.k8s.io/pause:3.5" +) + +// Constants for node names +const ( + Node1Name = "node-1" + Node2Name = "node-2" + Node3Name = "node-3" + Node4Name = "node-4" +) + +// Constants for machine names +const ( + Machine1Name = "machine-1" + Machine2Name = "machine-2" + Machine3Name = "machine-3" + Machine4Name = "machine-4" +) diff --git a/internal/test/k8sresources.go b/internal/test/k8sresources.go new file mode 100644 index 00000000..9898e6eb --- /dev/null +++ b/internal/test/k8sresources.go @@ -0,0 +1,137 @@ +package test + +import ( + "time" + + "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" + appsv1 "k8s.io/api/apps/v1" + coordinationv1 "k8s.io/api/coordination/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" +) + +// NodeSpec is a specification for a node. +type NodeSpec struct { + Name string + Annotations map[string]string + Labels map[string]string + Conditions []corev1.NodeCondition +} + +// NodeLeaseSpec is a specification for a node lease. +type NodeLeaseSpec struct { + Name string + IsExpired bool + IsOwnerRefSet bool +} + +// MachineSpec is a specification for a machine. +type MachineSpec struct { + Name string + Labels map[string]string + CurrentStatus v1alpha1.CurrentStatus + Namespace string +} + +// GenerateDeployment generates a deployment object with the given parameters. +func GenerateDeployment(name, namespace, imageName string, replicas int32, annotations map[string]string) *appsv1.Deployment { + labels := map[string]string{"app": name} + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: labels, + Annotations: annotations, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + Selector: &metav1.LabelSelector{ + MatchLabels: labels, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + }, + Spec: corev1.PodSpec{ + Volumes: nil, + InitContainers: nil, + Containers: []corev1.Container{{Name: name, Image: imageName, Ports: []corev1.ContainerPort{{ContainerPort: 80}}}}, + }, + }, + }, + } +} + +// GenerateNodeLeases generates leases based on the given lease specs. +func GenerateNodeLeases(leaseSpecs []NodeLeaseSpec) []*coordinationv1.Lease { + var leases []*coordinationv1.Lease + for _, leaseSpec := range leaseSpecs { + leases = append(leases, createNodeLease(leaseSpec.Name, leaseSpec.IsExpired)) + } + return leases +} + +// GenerateNodes generates nodes based on the given node specs. +func GenerateNodes(nodeSpecs []NodeSpec) []*corev1.Node { + var nodes []*corev1.Node + for _, nodeSpec := range nodeSpecs { + nodes = append(nodes, &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeSpec.Name, + Annotations: nodeSpec.Annotations, + Labels: nodeSpec.Labels, + }, + Status: corev1.NodeStatus{ + Conditions: nodeSpec.Conditions, + }, + }) + } + return nodes +} + +// GenerateMachines generates machines based on the given machine specs. +func GenerateMachines(machineSpecs []MachineSpec, namespace string) []*v1alpha1.Machine { + var machines []*v1alpha1.Machine + for _, machineSpec := range machineSpecs { + machines = append(machines, &v1alpha1.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: machineSpec.Name, + Namespace: namespace, + Labels: machineSpec.Labels, + }, + Status: v1alpha1.MachineStatus{ + CurrentStatus: machineSpec.CurrentStatus, + }, + }) + } + return machines +} + +func createNodeLease(name string, isExpired bool) *coordinationv1.Lease { + lease := coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: "kube-node-lease", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Node", + Name: name, + }, + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: &name, + LeaseDurationSeconds: pointer.Int32(40), + }, + } + if isExpired { + renewTime := metav1.NewMicroTime(time.Now().Add(-time.Minute)) + lease.Spec.RenewTime = &renewTime + } else { + renewTime := metav1.NewMicroTime(time.Now().Add(-10 * time.Second)) + lease.Spec.RenewTime = &renewTime + } + return &lease +} diff --git a/internal/test/util.go b/internal/test/k8sutil.go similarity index 53% rename from internal/test/util.go rename to internal/test/k8sutil.go index faaa55a6..cb927b7e 100644 --- a/internal/test/util.go +++ b/internal/test/k8sutil.go @@ -5,23 +5,17 @@ package test import ( - "bytes" "context" - "errors" "fmt" - "log" - "os" - "testing" . "github.com/onsi/gomega" - "sigs.k8s.io/controller-runtime/pkg/envtest" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" ) // GetStructured reads the file present at the given filePath and returns a structured object based on the type T. @@ -60,52 +54,14 @@ func GetUnstructured(filePath string) (*unstructured.Unstructured, error) { return unstructuredObject, nil } -// ReadFile reads the file present at the given filePath and returns a byte Buffer containing its contents. -func ReadFile(filePath string) (*bytes.Buffer, error) { - f, err := os.Open(filePath) - if err != nil { - return nil, err - } - defer func() { _ = f.Close() }() - - buff := new(bytes.Buffer) - _, err = buff.ReadFrom(f) - if err != nil { - return nil, err - } - return buff, nil -} - -// FileExistsOrFail checks if the given filepath is valid and returns an error if file is not found or does not exist. -func FileExistsOrFail(filepath string) { - var err error - if _, err = os.Stat(filepath); errors.Is(err, os.ErrNotExist) { - log.Fatalf("%s does not exist. This should not have happened. Check testdata directory.\n", filepath) - } - if err != nil { - log.Fatalf("Error occured in finding file %s : %v", filepath, err) - } -} - -// ValidateIfFileExists validates the existence of a file -func ValidateIfFileExists(file string, t *testing.T) { - g := NewWithT(t) - var err error - if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { - t.Fatalf("%s does not exist. This should not have happened. Check testdata directory.\n", file) - } - g.Expect(err).ToNot(HaveOccurred(), "File at path %v should exist") -} - // CreateTestNamespace creates a namespace with the given namePrefix -func CreateTestNamespace(ctx context.Context, g *WithT, cli client.Client, namePrefix string) string { +func CreateTestNamespace(ctx context.Context, g *WithT, cli client.Client, name string) { ns := corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - GenerateName: namePrefix + "-", + Name: name, }, } g.Expect(cli.Create(ctx, &ns)).To(Succeed()) - return ns.Name } // TeardownEnv cancels the context and stops testenv. @@ -114,27 +70,3 @@ func TeardownEnv(g *WithT, testEnv *envtest.Environment, cancelFn context.Cancel err := testEnv.Stop() g.Expect(err).NotTo(HaveOccurred()) } - -// MergeMaps merges newMaps with an oldMap. Keys defined in the new Map which are present in the old Map will be overwritten. -func MergeMaps[T any](oldMap map[string]T, newMaps ...map[string]T) map[string]T { - var out map[string]T - - if oldMap != nil { - out = make(map[string]T) - } - for k, v := range oldMap { - out[k] = v - } - - for _, newMap := range newMaps { - if newMap != nil && out == nil { - out = make(map[string]T) - } - - for k, v := range newMap { - out[k] = v - } - } - - return out -} diff --git a/internal/test/kind.go b/internal/test/kind.go index 7fb2bbfa..211b7e54 100644 --- a/internal/test/kind.go +++ b/internal/test/kind.go @@ -174,31 +174,7 @@ func (kc *kindCluster) CreateNamespace(name string) error { } func (kc *kindCluster) CreateDeployment(name, namespace, imageName string, replicas int32, annotations map[string]string) error { - labels := map[string]string{"app": name} - deployment := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Labels: labels, - Annotations: annotations, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: labels, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: labels, - }, - Spec: corev1.PodSpec{ - Volumes: nil, - InitContainers: nil, - Containers: []corev1.Container{{Name: name, Image: imageName, Ports: []corev1.ContainerPort{{ContainerPort: 80}}}}, - }, - }, - }, - } + deployment := GenerateDeployment(name, namespace, imageName, replicas, annotations) return kc.client.Create(context.Background(), deployment) } diff --git a/internal/test/miscellaneous.go b/internal/test/miscellaneous.go new file mode 100644 index 00000000..a8756714 --- /dev/null +++ b/internal/test/miscellaneous.go @@ -0,0 +1,48 @@ +package test + +import ( + "bytes" + "errors" + "log" + "os" + "testing" + + . "github.com/onsi/gomega" +) + +// ReadFile reads the file present at the given filePath and returns a byte Buffer containing its contents. +func ReadFile(filePath string) (*bytes.Buffer, error) { + f, err := os.Open(filePath) + if err != nil { + return nil, err + } + defer func() { _ = f.Close() }() + + buff := new(bytes.Buffer) + _, err = buff.ReadFrom(f) + if err != nil { + return nil, err + } + return buff, nil +} + +// FileExistsOrFail checks if the given filepath is valid and returns an error if file is not found or does not exist. +func FileExistsOrFail(filepath string) { + var err error + if _, err = os.Stat(filepath); errors.Is(err, os.ErrNotExist) { + log.Fatalf("%s does not exist. This should not have happened. Check testdata directory.\n", filepath) + } + if err != nil { + log.Fatalf("Error occured in finding file %s : %v", filepath, err) + } +} + +// ValidateIfFileExists validates the existence of a file +func ValidateIfFileExists(file string, t *testing.T) { + g := NewWithT(t) + var err error + if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { + t.Fatalf("%s does not exist. This should not have happened. Check testdata directory.\n", file) + } + g.Expect(err).ToNot(HaveOccurred(), "File at path %v should exist") +} diff --git a/internal/util/k8shelper.go b/internal/util/k8shelper.go index 3084084e..e380b4f1 100644 --- a/internal/util/k8shelper.go +++ b/internal/util/k8shelper.go @@ -10,6 +10,8 @@ import ( "net/http" "time" + "k8s.io/client-go/discovery" + "github.com/go-logr/logr" autoscalingv1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -55,7 +57,29 @@ func GetKubeConfigFromSecret(ctx context.Context, namespace, secretName string, // CreateClientFromKubeConfigBytes creates a client to connect to the Kube ApiServer using the kubeConfigBytes passed as a parameter // It will also set a connection timeout and will disable KeepAlive. -func CreateClientFromKubeConfigBytes(kubeConfigBytes []byte, connectionTimeout time.Duration) (kubernetes.Interface, error) { +func CreateClientFromKubeConfigBytes(kubeConfigBytes []byte, connectionTimeout time.Duration) (client.Client, error) { + config, err := createRestConfigFromKubeConfigBytes(kubeConfigBytes, connectionTimeout) + if err != nil { + return nil, err + } + return client.New(config, client.Options{}) +} + +// CreateDiscoveryInterfaceFromKubeConfigBytes creates a discovery interface to connect to the Kube ApiServer using the kubeConfigBytes passed as a parameter +// It will also set a connection timeout and will disable KeepAlive. +func CreateDiscoveryInterfaceFromKubeConfigBytes(kubeConfigBytes []byte, connectionTimeout time.Duration) (discovery.DiscoveryInterface, error) { + config, err := createRestConfigFromKubeConfigBytes(kubeConfigBytes, connectionTimeout) + if err != nil { + return nil, err + } + clientSet, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, err + } + return clientSet.Discovery(), nil +} + +func createRestConfigFromKubeConfigBytes(kubeConfigBytes []byte, connectionTimeout time.Duration) (*rest.Config, error) { clientConfig, err := clientcmd.NewClientConfigFromBytes(kubeConfigBytes) if err != nil { return nil, err @@ -72,7 +96,7 @@ func CreateClientFromKubeConfigBytes(kubeConfigBytes []byte, connectionTimeout t config.Wrap(func(rt http.RoundTripper) http.RoundTripper { return transport }) - return kubernetes.NewForConfig(config) + return config, nil } // Client created for probing the Kube ApiServer needs to have 'KeepAlive` disabled to ensure diff --git a/internal/util/node.go b/internal/util/node.go new file mode 100644 index 00000000..b365c831 --- /dev/null +++ b/internal/util/node.go @@ -0,0 +1,73 @@ +package util + +import ( + "slices" + + "github.com/gardener/gardener/pkg/apis/core/v1beta1" + "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // WorkerPoolLabel is the label key for the worker pool. It is used to determine the worker pool to which the node belongs. + WorkerPoolLabel = "worker.gardener.cloud/pool" + nodeNameLabel = "node" + nodeNotManagedByMCMAnnotationKey = "node.machine.sapcloud.io/not-managed-by-mcm" +) + +// DefaultUnhealthyNodeConditions are the default node conditions which indicate that the node is unhealthy. +// These conditions are borrowed from MCM where these conditions are used to decide if a node is unhealthy and should be replaced. +// NOTE: If these default set of node conditions are changed in MCM, make sure to change it here as well. +var DefaultUnhealthyNodeConditions = []string{"KernelDeadlock", "ReadonlyFilesystem", "DiskPressure", "NetworkUnavailable"} + +// IsNodeHealthyByConditions determines if a node is healthy by checking that none of the given unhealthyWorkerConditionNames have Status set to true. +func IsNodeHealthyByConditions(node *corev1.Node, unhealthyWorkerConditionNames []string) bool { + for _, nc := range node.Status.Conditions { + if slices.Contains(unhealthyWorkerConditionNames, string(nc.Type)) { + if nc.Status == corev1.ConditionTrue { + return false + } + } + } + return true +} + +// IsNodeManagedByMCM determines if a node is managed by MCM by checking if the node has the annotation nodeNotManagedByMCMAnnotationKey"node.machine.sapcloud.io/not-managed-by-mcm" set. +func IsNodeManagedByMCM(node *corev1.Node) bool { + return !metav1.HasAnnotation(node.ObjectMeta, nodeNotManagedByMCMAnnotationKey) +} + +// GetEffectiveNodeConditionsForWorkers initializes the node conditions per worker. +func GetEffectiveNodeConditionsForWorkers(shoot *v1beta1.Shoot) map[string][]string { + workerNodeConditions := make(map[string][]string) + for _, worker := range shoot.Spec.Provider.Workers { + if worker.MachineControllerManagerSettings != nil { + workerNodeConditions[worker.Name] = GetSliceOrDefault(worker.MachineControllerManagerSettings.NodeConditions, DefaultUnhealthyNodeConditions) + } + } + return workerNodeConditions +} + +// GetWorkerUnhealthyNodeConditions returns the configured node conditions for the pool where this node belongs. +// Worker name is extracted from the node labels. +func GetWorkerUnhealthyNodeConditions(node *corev1.Node, workerNodeConditions map[string][]string) []string { + if poolName, foundWorkerPoolLabel := node.Labels[WorkerPoolLabel]; foundWorkerPoolLabel { + if conditions, foundWorkerPoolNodeConditions := workerNodeConditions[poolName]; foundWorkerPoolNodeConditions { + return conditions + } + } + return DefaultUnhealthyNodeConditions +} + +// GetMachineNotInFailedOrTerminatingState returns the machine corresponding to the node which is not in failed or terminating phase. +// It will return nil if no machine is found corresponding to the node or if the machine is in failed or terminating phase. +func GetMachineNotInFailedOrTerminatingState(nodeName string, machines []v1alpha1.Machine) *v1alpha1.Machine { + for _, machine := range machines { + nodeLabelValue := machine.Labels[nodeNameLabel] + if nodeLabelValue == nodeName && machine.Status.CurrentStatus.Phase != v1alpha1.MachineFailed && machine.Status.CurrentStatus.Phase != v1alpha1.MachineTerminating { + return &machine + } + } + return nil +} diff --git a/internal/util/util.go b/internal/util/util.go index 42f91a66..67a7ea36 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -50,3 +50,11 @@ func GetValOrDefault[T any](val *T, defaultVal T) *T { } return val } + +// GetSliceOrDefault assigns the default value if the slice is nil or empty +func GetSliceOrDefault[T any](val []T, defaultVal []T) []T { + if len(val) == 0 { + return defaultVal + } + return val +} diff --git a/internal/util/util_test.go b/internal/util/util_test.go index 13114671..c6c47019 100644 --- a/internal/util/util_test.go +++ b/internal/util/util_test.go @@ -91,3 +91,24 @@ func TestFillDefaultIfNil(t *testing.T) { testFloat = GetValOrDefault(testFloat, 2.0) g.Expect(*testFloat).To(Equal(1.0)) } + +func TestGetSliceOrDefault(t *testing.T) { + defaultSlice := []string{"bingo"} + + tests := []struct { + description string + inputSlice []string + expectedOutputSlice []string + }{ + {description: "default slice should be returned if input slice is nil", inputSlice: nil, expectedOutputSlice: defaultSlice}, + {description: "default slice should be returned if input slice is empty", inputSlice: []string{}, expectedOutputSlice: defaultSlice}, + {description: "input slice should be returned if it is not nil or empty", inputSlice: []string{"bingo", "tringo"}, expectedOutputSlice: []string{"bingo", "tringo"}}, + } + g := NewWithT(t) + t.Parallel() + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + g.Expect(GetSliceOrDefault(test.inputSlice, test.expectedOutputSlice)).To(Equal(test.expectedOutputSlice)) + }) + } +}