github.com/argoproj/argo-events@v1.9.1/controllers/sensor/controller.go (about) 1 /* 2 Copyright 2020 BlackRock, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sensor 18 19 import ( 20 "context" 21 "fmt" 22 23 "go.uber.org/zap" 24 "k8s.io/apimachinery/pkg/api/equality" 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/apimachinery/pkg/types" 28 ctrl "sigs.k8s.io/controller-runtime" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 31 "sigs.k8s.io/controller-runtime/pkg/reconcile" 32 33 "github.com/argoproj/argo-events/common" 34 "github.com/argoproj/argo-events/common/logging" 35 eventbusv1alpha1 "github.com/argoproj/argo-events/pkg/apis/eventbus/v1alpha1" 36 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" 37 ) 38 39 const ( 40 // ControllerName is name of the controller 41 ControllerName = "sensor-controller" 42 43 finalizerName = ControllerName 44 ) 45 46 type reconciler struct { 47 client client.Client 48 scheme *runtime.Scheme 49 50 sensorImage string 51 logger *zap.SugaredLogger 52 } 53 54 // NewReconciler returns a new reconciler 55 func NewReconciler(client client.Client, scheme *runtime.Scheme, sensorImage string, logger *zap.SugaredLogger) reconcile.Reconciler { 56 return &reconciler{client: client, scheme: scheme, sensorImage: sensorImage, logger: logger} 57 } 58 59 func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 60 sensor := &v1alpha1.Sensor{} 61 if err := r.client.Get(ctx, req.NamespacedName, sensor); err != nil { 62 if apierrors.IsNotFound(err) { 63 r.logger.Warnw("WARNING: sensor not found", "request", req) 64 return reconcile.Result{}, nil 65 } 66 r.logger.Errorw("unable to get sensor ctl", zap.Any("request", req), zap.Error(err)) 67 return ctrl.Result{}, err 68 } 69 log := r.logger.With("namespace", sensor.Namespace).With("sensor", sensor.Name) 70 ctx = logging.WithLogger(ctx, log) 71 sensorCopy := sensor.DeepCopy() 72 reconcileErr := r.reconcile(ctx, sensorCopy) 73 if reconcileErr != nil { 74 log.Errorw("reconcile error", zap.Error(reconcileErr)) 75 } 76 if r.needsUpdate(sensor, sensorCopy) { 77 // Use a DeepCopy to update, because it will be mutated afterwards, with empty Status. 78 if err := r.client.Update(ctx, sensorCopy.DeepCopy()); err != nil { 79 return reconcile.Result{}, err 80 } 81 } 82 if err := r.client.Status().Update(ctx, sensorCopy); err != nil { 83 return reconcile.Result{}, err 84 } 85 return ctrl.Result{}, reconcileErr 86 } 87 88 // reconcile does the real logic 89 func (r *reconciler) reconcile(ctx context.Context, sensor *v1alpha1.Sensor) error { 90 log := logging.FromContext(ctx) 91 if !sensor.DeletionTimestamp.IsZero() { 92 log.Info("deleting sensor") 93 if controllerutil.ContainsFinalizer(sensor, finalizerName) { 94 // Finalizer logic should be added here. 95 controllerutil.RemoveFinalizer(sensor, finalizerName) 96 } 97 return nil 98 } 99 controllerutil.AddFinalizer(sensor, finalizerName) 100 101 sensor.Status.InitConditions() 102 103 eventBus := &eventbusv1alpha1.EventBus{} 104 eventBusName := common.DefaultEventBusName 105 if len(sensor.Spec.EventBusName) > 0 { 106 eventBusName = sensor.Spec.EventBusName 107 } 108 err := r.client.Get(ctx, types.NamespacedName{Namespace: sensor.Namespace, Name: eventBusName}, eventBus) 109 if err != nil { 110 if apierrors.IsNotFound(err) { 111 sensor.Status.MarkDeployFailed("EventBusNotFound", "EventBus not found.") 112 log.Errorw("EventBus not found", "eventBusName", eventBusName, "error", err) 113 return fmt.Errorf("eventbus %s not found", eventBusName) 114 } 115 sensor.Status.MarkDeployFailed("GetEventBusFailed", "Failed to get EventBus.") 116 log.Errorw("failed to get EventBus", "eventBusName", eventBusName, "error", err) 117 return err 118 } 119 120 if err := ValidateSensor(sensor, eventBus); err != nil { 121 log.Errorw("validation error", "error", err) 122 return err 123 } 124 args := &AdaptorArgs{ 125 Image: r.sensorImage, 126 Sensor: sensor, 127 Labels: map[string]string{ 128 "controller": "sensor-controller", 129 common.LabelSensorName: sensor.Name, 130 common.LabelOwnerName: sensor.Name, 131 }, 132 } 133 return Reconcile(r.client, eventBus, args, log) 134 } 135 136 func (r *reconciler) needsUpdate(old, new *v1alpha1.Sensor) bool { 137 if old == nil { 138 return true 139 } 140 if !equality.Semantic.DeepEqual(old.Finalizers, new.Finalizers) { 141 return true 142 } 143 return false 144 }