From 2df6e0ee93fcaea51693b6923a0ea5b1df8a9aa9 Mon Sep 17 00:00:00 2001 From: Francesco Cheinasso Date: Wed, 31 May 2023 11:06:13 +0200 Subject: [PATCH] indexer --- cmd/liqo-controller-manager/main.go | 8 +++- .../nodefailure_controller.go | 20 ++------- .../nodefailure_controller_test.go | 3 +- pkg/utils/indexer/doc.go | 16 +++++++ pkg/utils/indexer/indexer.go | 43 +++++++++++++++++++ 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 pkg/utils/indexer/doc.go create mode 100644 pkg/utils/indexer/indexer.go diff --git a/cmd/liqo-controller-manager/main.go b/cmd/liqo-controller-manager/main.go index f7d1671361..6c1604bc6f 100644 --- a/cmd/liqo-controller-manager/main.go +++ b/cmd/liqo-controller-manager/main.go @@ -71,6 +71,7 @@ import ( argsutils "github.com/liqotech/liqo/pkg/utils/args" "github.com/liqotech/liqo/pkg/utils/csr" liqoerrors "github.com/liqotech/liqo/pkg/utils/errors" + "github.com/liqotech/liqo/pkg/utils/indexer" "github.com/liqotech/liqo/pkg/utils/mapper" "github.com/liqotech/liqo/pkg/utils/restcfg" "github.com/liqotech/liqo/pkg/vkMachinery" @@ -231,6 +232,11 @@ func main() { mgr.GetWebhookServer().Register("/validate/namespace-offloading", nsoffwh.New()) mgr.GetWebhookServer().Register("/mutate/pod", podwh.New(mgr.GetClient())) + if err := indexer.IndexField(ctx, mgr, &corev1.Pod{}, indexer.FieldNodeNameFromPod, indexer.ExtractNodeName); err != nil { + klog.Errorf("Unable to setup the indexer for the Pod nodeName field: %v", err) + os.Exit(1) + } + clientset := kubernetes.NewForConfigOrDie(config) namespaceManager := tenantnamespace.NewCachedManager(ctx, clientset) @@ -414,7 +420,7 @@ func main() { Client: mgr.GetClient(), Scheme: mgr.GetScheme(), } - if err = nodeFailureReconciler.SetupWithManager(ctx, mgr); err != nil { + if err = nodeFailureReconciler.SetupWithManager(mgr); err != nil { klog.Errorf("Unable to start the nodeFailureReconciler", err) os.Exit(1) } diff --git a/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller.go b/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller.go index fb360b4fc0..5dc2ee812d 100644 --- a/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller.go +++ b/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller.go @@ -34,10 +34,9 @@ import ( "github.com/liqotech/liqo/pkg/consts" "github.com/liqotech/liqo/pkg/utils" + "github.com/liqotech/liqo/pkg/utils/indexer" ) -var nodeNameField = "spec.nodeName" - // NodeFailureReconciler reconciles a Node object. type NodeFailureReconciler struct { client.Client @@ -68,7 +67,7 @@ func (r *NodeFailureReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Node NotReady: delete all terminating pods that are managed by shadowpods var pods corev1.PodList offloadedPodSelector := client.MatchingLabelsSelector{Selector: labels.Set{consts.ManagedByLabelKey: consts.ManagedByShadowPodValue}.AsSelector()} - nodePodSelector := client.MatchingFieldsSelector{Selector: fields.OneTermEqualSelector(nodeNameField, node.Name)} + nodePodSelector := client.MatchingFieldsSelector{Selector: fields.OneTermEqualSelector(indexer.FieldNodeNameFromPod, node.Name)} if err := r.List(ctx, &pods, offloadedPodSelector, nodePodSelector); err != nil { klog.Errorf("unable to list pods: %v", err) return ctrl.Result{}, err @@ -110,21 +109,8 @@ func getPodTerminatingEventHandler() handler.EventHandler { }} } -func extractNodeNameFromPod(rawObj client.Object) []string { - pod, ok := rawObj.(*corev1.Pod) - if !ok { - return []string{} - } - return []string{pod.Spec.NodeName} -} - // SetupWithManager monitors updates on nodes and watch for pods that are terminating and managed by a ShadowPod. -func (r *NodeFailureReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error { - // Add field containing node Name to the Field Indexer - if err := mgr.GetFieldIndexer().IndexField(ctx, &corev1.Pod{}, nodeNameField, extractNodeNameFromPod); err != nil { - return err - } - +func (r *NodeFailureReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&corev1.Node{}). Watches(&source.Kind{Type: &corev1.Pod{}}, getPodTerminatingEventHandler()). diff --git a/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller_test.go b/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller_test.go index 0cac37a738..794835bb25 100644 --- a/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller_test.go +++ b/pkg/liqo-controller-manager/nodefailure-controller/nodefailure_controller_test.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/utils/indexer" ) var _ = Describe("NodeFailureController", func() { @@ -135,7 +136,7 @@ var _ = Describe("NodeFailureController", func() { fakeClientBuilder = fake.NewClientBuilder(). WithScheme(scheme.Scheme). - WithIndex(&corev1.Pod{}, nodeNameField, extractNodeNameFromPod) + WithIndex(&corev1.Pod{}, indexer.FieldNodeNameFromPod, indexer.ExtractNodeName) }) JustBeforeEach(func() { diff --git a/pkg/utils/indexer/doc.go b/pkg/utils/indexer/doc.go new file mode 100644 index 0000000000..d4a1e667cc --- /dev/null +++ b/pkg/utils/indexer/doc.go @@ -0,0 +1,16 @@ +// Copyright 2019-2023 The Liqo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package indexer provides indexers for controller-runtime managers. +package indexer diff --git a/pkg/utils/indexer/indexer.go b/pkg/utils/indexer/indexer.go new file mode 100644 index 0000000000..974ae481dc --- /dev/null +++ b/pkg/utils/indexer/indexer.go @@ -0,0 +1,43 @@ +// Copyright 2019-2023 The Liqo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package indexer + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + ctrlruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + // FieldNodeNameFromPod is the field name of the node name of a pod. + FieldNodeNameFromPod = "spec.nodeName" +) + +// ExtractNodeName returns the node name of the given object. +func ExtractNodeName(rawObj client.Object) []string { + switch obj := rawObj.(type) { + case *corev1.Pod: + return []string{obj.Spec.NodeName} + default: + return []string{} + } +} + +// IndexField indexes the given field on the given object. +func IndexField(ctx context.Context, mgr ctrlruntime.Manager, obj client.Object, field string, indexerFunc client.IndexerFunc) error { + return mgr.GetFieldIndexer().IndexField(ctx, obj, field, indexerFunc) +}