...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/predicate/predicate.go

Documentation: github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/predicate

     1  // Copyright 2022 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package predicate
    16  
    17  import (
    18  	"reflect"
    19  
    20  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
    21  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/util/slice"
    22  
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"sigs.k8s.io/controller-runtime/pkg/event"
    25  	"sigs.k8s.io/controller-runtime/pkg/predicate"
    26  )
    27  
    28  // This predicate will react to changes only when there is something relevant to
    29  // send to the underlying API.
    30  type UnderlyingResourceOutOfSyncPredicate struct {
    31  	predicate.Funcs
    32  }
    33  
    34  // Update implements default UpdateEvent filter for validating changes that require
    35  // updates to the underlying API.
    36  func (UnderlyingResourceOutOfSyncPredicate) Update(e event.UpdateEvent) bool {
    37  	// Kubernetes deletions manifest as API updates with the deletion
    38  	// timestamp set when it previously was not.
    39  	if e.ObjectOld.GetDeletionTimestamp().IsZero() &&
    40  		!e.ObjectNew.GetDeletionTimestamp().IsZero() {
    41  		return true
    42  	}
    43  
    44  	// The deletion defender finalizer being removed signifies the controller
    45  	// may now proceed with finalizing deletion on GCP.
    46  	if hasDeletionDefenderFinalizerBeenRemoved(e.ObjectOld, e.ObjectNew) {
    47  		return true
    48  	}
    49  
    50  	// Container annotation changes should trigger reconciliations as some
    51  	// resources rely on container annotation changes for cross-container
    52  	// migrations on GCP (e.g. moving Projects/Folders to different parent
    53  	// Folders/Organizations)
    54  	if !areContainerAnnotationsEqual(e.ObjectOld.GetAnnotations(), e.ObjectNew.GetAnnotations()) {
    55  		return true
    56  	}
    57  
    58  	// Labels updates should be propagated to the underlying API
    59  	if !reflect.DeepEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels()) {
    60  		return true
    61  	}
    62  
    63  	// The object's generation will increment when the spec is updated, so a different
    64  	// generation implies potential work to be done on the underlying API.
    65  	if e.ObjectNew.GetGeneration() != e.ObjectOld.GetGeneration() {
    66  		return true
    67  	}
    68  
    69  	return false
    70  }
    71  
    72  // Delete always returns false, as resources deleted directly from the
    73  // API server should not be reconciled. We process user-requested deletions
    74  // via the updated DeletionTimestamp.
    75  func (UnderlyingResourceOutOfSyncPredicate) Delete(_ event.DeleteEvent) bool {
    76  	return false
    77  }
    78  
    79  func hasDeletionDefenderFinalizerBeenRemoved(ObjectOld, ObjectNew metav1.Object) bool {
    80  	return slice.StringSliceContains(ObjectOld.GetFinalizers(), k8s.DeletionDefenderFinalizerName) &&
    81  		!slice.StringSliceContains(ObjectNew.GetFinalizers(), k8s.DeletionDefenderFinalizerName)
    82  }
    83  
    84  func areContainerAnnotationsEqual(a, b map[string]string) bool {
    85  	for _, x := range k8s.ContainerAnnotations {
    86  		if a[x] != b[x] {
    87  			return false
    88  		}
    89  	}
    90  	return true
    91  }
    92  

View as plain text