@@ -25,9 +25,8 @@ import (
2525 "github.com/aws/amazon-vpc-resource-controller-k8s/pkg/utils"
2626 "github.com/go-logr/logr"
2727 "github.com/prometheus/client_golang/prometheus"
28- "golang.org/x/sync/semaphore"
2928 v1 "k8s.io/api/core/v1"
30- apierrors "k8s.io/apimachinery/pkg/api/errors"
29+ "k8s.io/apimachinery/pkg/api/errors"
3130 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3231 "k8s.io/apimachinery/pkg/runtime"
3332 "k8s.io/apimachinery/pkg/types"
@@ -36,7 +35,6 @@ import (
3635 ctrl "sigs.k8s.io/controller-runtime"
3736 "sigs.k8s.io/controller-runtime/pkg/client"
3837 "sigs.k8s.io/controller-runtime/pkg/controller"
39- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
4038 "sigs.k8s.io/controller-runtime/pkg/metrics"
4139)
4240
@@ -77,8 +75,7 @@ type CNINodeReconciler struct {
7775 clusterName string
7876 vpcId string
7977 finalizerManager k8s.FinalizerManager
80- deletePool * semaphore.Weighted
81- newResourceCleaner func (nodeID string , eC2Wrapper ec2API.EC2Wrapper , vpcID string , log logr.Logger ) cleanup.ResourceCleaner
78+ newResourceCleaner func (nodeID string , eC2Wrapper ec2API.EC2Wrapper , vpcID string ) cleanup.ResourceCleaner
8279}
8380
8481func NewCNINodeReconciler (
@@ -91,8 +88,7 @@ func NewCNINodeReconciler(
9188 clusterName string ,
9289 vpcId string ,
9390 finalizerManager k8s.FinalizerManager ,
94- maxConcurrentWorkers int ,
95- newResourceCleaner func (nodeID string , eC2Wrapper ec2API.EC2Wrapper , vpcID string , log logr.Logger ) cleanup.ResourceCleaner ,
91+ newResourceCleaner func (nodeID string , eC2Wrapper ec2API.EC2Wrapper , vpcID string ) cleanup.ResourceCleaner ,
9692) * CNINodeReconciler {
9793 return & CNINodeReconciler {
9894 Client : client ,
@@ -104,7 +100,6 @@ func NewCNINodeReconciler(
104100 clusterName : clusterName ,
105101 vpcId : vpcId ,
106102 finalizerManager : finalizerManager ,
107- deletePool : semaphore .NewWeighted (int64 (maxConcurrentWorkers )),
108103 newResourceCleaner : newResourceCleaner ,
109104 }
110105}
@@ -123,7 +118,7 @@ func (r *CNINodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
123118 nodeFound := true
124119 node := & v1.Node {}
125120 if err := r .Client .Get (ctx , req .NamespacedName , node ); err != nil {
126- if apierrors .IsNotFound (err ) {
121+ if errors .IsNotFound (err ) {
127122 nodeFound = false
128123 } else {
129124 r .log .Error (err , "failed to get the node object in CNINode reconciliation, will retry" )
@@ -133,50 +128,66 @@ func (r *CNINodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
133128 }
134129
135130 if cniNode .GetDeletionTimestamp ().IsZero () {
131+ shouldPatch := false
136132 cniNodeCopy := cniNode .DeepCopy ()
137- shouldPatch , err := r .ensureTagsAndLabels (cniNodeCopy , node )
138- shouldPatch = controllerutil .AddFinalizer (cniNodeCopy , config .NodeTerminationFinalizer ) || shouldPatch
139-
140- if shouldPatch {
141- r .log .Info ("patching CNINode to add fields Tags, Labels and finalizer" , "cninode" , cniNode .Name )
142- if err := r .Client .Patch (ctx , cniNodeCopy , client .MergeFromWithOptions (cniNode , client.MergeFromWithOptimisticLock {})); err != nil {
143- if apierrors .IsConflict (err ) {
144- r .log .Info ("failed to update cninode" , "cninode" , cniNode .Name , "error" , err )
145- return ctrl.Result {Requeue : true }, nil
133+ // Add cluster name tag if it does not exist
134+ val , ok := cniNode .Spec .Tags [config .VPCCNIClusterNameKey ]
135+ if ! ok || val != r .clusterName {
136+ if len (cniNodeCopy .Spec .Tags ) != 0 {
137+ cniNodeCopy .Spec .Tags [config .VPCCNIClusterNameKey ] = r .clusterName
138+ } else {
139+ cniNodeCopy .Spec .Tags = map [string ]string {
140+ config .VPCCNIClusterNameKey : r .clusterName ,
146141 }
147- return ctrl.Result {}, err
148142 }
143+ shouldPatch = true
149144 }
150- return ctrl.Result {}, err
145+ // if node exists, get & add OS label if it does not exist on CNINode
146+ if nodeFound {
147+ nodeLabelOS := node .ObjectMeta .Labels [config .NodeLabelOS ]
148+ val , ok = cniNode .ObjectMeta .Labels [config .NodeLabelOS ]
149+ if ! ok || val != nodeLabelOS {
150+ if len (cniNodeCopy .ObjectMeta .Labels ) != 0 {
151+ cniNodeCopy .ObjectMeta .Labels [config .NodeLabelOS ] = nodeLabelOS
152+ } else {
153+ cniNodeCopy .ObjectMeta .Labels = map [string ]string {
154+ config .NodeLabelOS : nodeLabelOS ,
155+ }
156+ }
157+ shouldPatch = true
158+ }
159+ }
160+
161+ if shouldPatch {
162+ r .log .Info ("patching CNINode to add required fields Tags and Labels" , "cninode" , cniNode .Name )
163+ return ctrl.Result {}, r .Client .Patch (ctx , cniNodeCopy , client .MergeFromWithOptions (cniNode , client.MergeFromWithOptimisticLock {}))
164+ }
165+
166+ // Add finalizer if it does not exist
167+ if err := r .finalizerManager .AddFinalizers (ctx , cniNode , config .NodeTerminationFinalizer ); err != nil {
168+ r .log .Error (err , "failed to add finalizer on CNINode, will retry" , "cniNode" , cniNode .Name , "finalizer" , config .NodeTerminationFinalizer )
169+ return ctrl.Result {}, err
170+ }
171+ return ctrl.Result {}, nil
172+
151173 } else { // CNINode is marked for deletion
152174 if ! nodeFound {
153175 // node is also deleted, proceed with running the cleanup routine and remove the finalizer
176+
154177 // run cleanup for Linux nodes only
155178 if val , ok := cniNode .ObjectMeta .Labels [config .NodeLabelOS ]; ok && val == config .OSLinux {
156179 r .log .Info ("running the finalizer routine on cniNode" , "cniNode" , cniNode .Name )
157180 // run cleanup when node id is present
158181 if nodeID , ok := cniNode .Spec .Tags [config .NetworkInterfaceNodeIDKey ]; ok && nodeID != "" {
159- if ! r . deletePool . TryAcquire ( 1 ) {
160- r .log .Info ( "d, will requeue request " )
161- return ctrl. Result { RequeueAfter : 10 * time . Second }, nil
182+ if err := r . newResourceCleaner ( nodeID , r . eC2Wrapper , r . vpcId ). DeleteLeakedResources (); err != nil {
183+ r .log .Error ( err , "failed to cleanup resources during node termination " )
184+ ec2API . NodeTerminationENICleanupFailure . Inc ()
162185 }
163- go func (nodeID string ) {
164- defer r .deletePool .Release (1 )
165- childCtx , cancel := context .WithTimeout (ctx , config .NodeTerminationTimeout )
166- defer cancel ()
167- if err := r .newResourceCleaner (nodeID , r .eC2Wrapper , r .vpcId , r .log ).DeleteLeakedResources (childCtx ); err != nil {
168- r .log .Error (err , "failed to cleanup resources during node termination" )
169- ec2API .NodeTerminationENICleanupFailure .Inc ()
170- }
171- }(nodeID )
172186 }
173187 }
174188
175- if err := r .removeFinalizer (ctx , cniNode , config .NodeTerminationFinalizer ); err != nil {
189+ if err := r .finalizerManager . RemoveFinalizers (ctx , cniNode , config .NodeTerminationFinalizer ); err != nil {
176190 r .log .Error (err , "failed to remove finalizer on CNINode, will retry" , "cniNode" , cniNode .Name , "finalizer" , config .NodeTerminationFinalizer )
177- if apierrors .IsConflict (err ) {
178- return ctrl.Result {Requeue : true }, nil
179- }
180191 return ctrl.Result {}, err
181192 }
182193 return ctrl.Result {}, nil
@@ -196,7 +207,7 @@ func (r *CNINodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
196207 Spec : cniNode .Spec ,
197208 }
198209
199- if err := r .removeFinalizer (ctx , cniNode , config .NodeTerminationFinalizer ); err != nil {
210+ if err := r .finalizerManager . RemoveFinalizers (ctx , cniNode , config .NodeTerminationFinalizer ); err != nil {
200211 r .log .Error (err , "failed to remove finalizer on CNINode, will retry" )
201212 return ctrl.Result {}, err
202213 }
@@ -241,7 +252,7 @@ func (r *CNINodeReconciler) waitTillCNINodeDeleted(nameSpacedCNINode types.Names
241252 oldCNINode := & v1alpha1.CNINode {}
242253
243254 return wait .PollUntilContextTimeout (context .TODO (), 500 * time .Millisecond , time .Second * 3 , true , func (ctx context.Context ) (bool , error ) {
244- if err := r .Client .Get (ctx , nameSpacedCNINode , oldCNINode ); err != nil && apierrors .IsNotFound (err ) {
255+ if err := r .Client .Get (ctx , nameSpacedCNINode , oldCNINode ); err != nil && errors .IsNotFound (err ) {
245256 return true , nil
246257 }
247258 return false , nil
@@ -255,45 +266,3 @@ func (r *CNINodeReconciler) createCNINodeFromObj(ctx context.Context, newCNINode
255266 return r .Client .Create (ctx , newCNINode )
256267 })
257268}
258-
259- func (r * CNINodeReconciler ) ensureTagsAndLabels (cniNode * v1alpha1.CNINode , node * v1.Node ) (bool , error ) {
260- shouldPatch := false
261- var err error
262- if cniNode .Spec .Tags == nil {
263- cniNode .Spec .Tags = make (map [string ]string )
264- }
265- // add cluster name tag if it does not exist
266- if cniNode .Spec .Tags [config .VPCCNIClusterNameKey ] != r .clusterName {
267- cniNode .Spec .Tags [config .VPCCNIClusterNameKey ] = r .clusterName
268- shouldPatch = true
269- }
270- if node != nil {
271- var nodeID string
272- nodeID , err = utils .GetNodeID (node )
273-
274- if nodeID != "" && cniNode .Spec .Tags [config .NetworkInterfaceNodeIDKey ] != nodeID {
275- cniNode .Spec .Tags [config .NetworkInterfaceNodeIDKey ] = nodeID
276- shouldPatch = true
277- }
278-
279- // add node label if it does not exist
280- if cniNode .ObjectMeta .Labels == nil {
281- cniNode .ObjectMeta .Labels = make (map [string ]string )
282- }
283- if cniNode .ObjectMeta .Labels [config .NodeLabelOS ] != node .ObjectMeta .Labels [config .NodeLabelOS ] {
284- cniNode .ObjectMeta .Labels [config .NodeLabelOS ] = node .ObjectMeta .Labels [config .NodeLabelOS ]
285- shouldPatch = true
286- }
287- }
288- return shouldPatch , err
289- }
290-
291- func (r * CNINodeReconciler ) removeFinalizer (ctx context.Context , cniNode * v1alpha1.CNINode , finalizer string ) error {
292- cniNodeCopy := cniNode .DeepCopy ()
293-
294- if controllerutil .RemoveFinalizer (cniNodeCopy , finalizer ) {
295- r .log .Info ("removing finalizer for cninode" , "name" , cniNode .GetName (), "finalizer" , finalizer )
296- return r .Client .Patch (ctx , cniNodeCopy , client .MergeFromWithOptions (cniNode , client.MergeFromWithOptimisticLock {}))
297- }
298- return nil
299- }
0 commit comments