@@ -20,7 +20,6 @@ import (
2020 "context"
2121 "fmt"
2222 "os"
23- "strings"
2423
2524 "github.com/application-stacks/runtime-component-operator/common"
2625 "github.com/pkg/errors"
@@ -50,7 +49,6 @@ import (
5049 networkingv1 "k8s.io/api/networking/v1"
5150 kerrors "k8s.io/apimachinery/pkg/api/errors"
5251 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
53- "k8s.io/apimachinery/pkg/types"
5452 servingv1 "knative.dev/serving/pkg/apis/serving/v1"
5553 "sigs.k8s.io/controller-runtime/pkg/client"
5654)
@@ -87,7 +85,7 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
8785
8886 ns , err := appstacksutils .GetOperatorNamespace ()
8987 // When running the operator locally, `ns` will be empty string
90- if ns == "" {
88+ if err != nil || ns == "" {
9189 // Since this method can be called directly from unit test, populate `watchNamespaces`.
9290 if r .watchNamespaces == nil {
9391 r .watchNamespaces , err = appstacksutils .GetWatchNamespaces ()
@@ -122,7 +120,7 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
122120
123121 // Fetch the RuntimeComponent instance
124122 instance := & appstacksv1beta2.RuntimeComponent {}
125- var ba common.BaseComponent = instance
123+ // var ba common.BaseComponent = instance
126124 err = r .GetClient ().Get (context .TODO (), req .NamespacedName , instance )
127125 if err != nil {
128126 if kerrors .IsNotFound (err ) {
@@ -167,57 +165,13 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
167165 Namespace : instance .Namespace ,
168166 }
169167
170- imageReferenceOld := instance .Status .ImageReference
171- instance .Status .ImageReference = instance .Spec .ApplicationImage
172- if r .IsOpenShift () {
173- image , err := imageutil .ParseDockerImageReference (instance .Spec .ApplicationImage )
174- if err == nil {
175- isTag := & imagev1.ImageStreamTag {}
176- isTagName := imageutil .JoinImageStreamTag (image .Name , image .Tag )
177- isTagNamespace := image .Namespace
178- if isTagNamespace == "" {
179- isTagNamespace = instance .Namespace
180- }
181- key := types.NamespacedName {Name : isTagName , Namespace : isTagNamespace }
182- err = r .GetAPIReader ().Get (context .Background (), key , isTag )
183- // Call ManageError only if the error type is not found or is not forbidden. Forbidden could happen
184- // when the operator tries to call GET for ImageStreamTags on a namespace that doesn't exists (e.g.
185- // cannot get imagestreamtags.image.openshift.io in the namespace "navidsh": no RBAC policy matched)
186- if err == nil {
187- image := isTag .Image
188- if image .DockerImageReference != "" {
189- instance .Status .ImageReference = image .DockerImageReference
190- }
191- } else if err != nil && ! kerrors .IsNotFound (err ) && ! kerrors .IsForbidden (err ) && ! strings .Contains (isTagName , "/" ) {
192- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
193- }
194- }
195- }
196- if imageReferenceOld != instance .Status .ImageReference {
197- reqLogger .Info ("Updating status.imageReference" , "status.imageReference" , instance .Status .ImageReference )
198- err = r .UpdateStatus (instance )
199- if err != nil {
200- reqLogger .Error (err , "Error updating RuntimeComponent status" )
201- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
202- }
168+ if err = r .UpdateImageReference (instance ); err != nil {
169+ reqLogger .Error (err , "Error updating RuntimeComponent" )
170+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
203171 }
204172
205- if instance .Spec .ServiceAccountName == nil || * instance .Spec .ServiceAccountName == "" {
206- serviceAccount := & corev1.ServiceAccount {ObjectMeta : defaultMeta }
207- err = r .CreateOrUpdate (serviceAccount , instance , func () error {
208- return appstacksutils .CustomizeServiceAccount (serviceAccount , instance , r .GetClient ())
209- })
210- if err != nil {
211- reqLogger .Error (err , "Failed to reconcile ServiceAccount" )
212- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
213- }
214- } else {
215- serviceAccount := & corev1.ServiceAccount {ObjectMeta : defaultMeta }
216- err = r .DeleteResource (serviceAccount )
217- if err != nil {
218- reqLogger .Error (err , "Failed to delete ServiceAccount" )
219- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
220- }
173+ if err = r .UpdateServiceAccount (instance , defaultMeta ); err != nil {
174+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
221175 }
222176
223177 // Check if the ServiceAccount has a valid pull secret before creating the deployment/statefulset
@@ -235,44 +189,10 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
235189 }
236190
237191 if instance .Spec .CreateKnativeService != nil && * instance .Spec .CreateKnativeService {
238- // Clean up non-Knative resources
239- resources := []client.Object {
240- & corev1.Service {ObjectMeta : defaultMeta },
241- & corev1.Service {ObjectMeta : metav1.ObjectMeta {Name : instance .Name + "-headless" , Namespace : instance .Namespace }},
242- & appsv1.Deployment {ObjectMeta : defaultMeta },
243- & appsv1.StatefulSet {ObjectMeta : defaultMeta },
244- & autoscalingv1.HorizontalPodAutoscaler {ObjectMeta : defaultMeta },
245- }
246- err = r .DeleteResources (resources )
192+ err = r .UpdateKnativeService (instance , defaultMeta , isKnativeSupported )
247193 if err != nil {
248- reqLogger .Error (err , "Failed to clean up non-Knative resources" )
249194 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
250- }
251-
252- if ok , _ := r .IsGroupVersionSupported (networkingv1 .SchemeGroupVersion .String (), "Ingress" ); ok {
253- r .DeleteResource (& networkingv1.Ingress {ObjectMeta : defaultMeta })
254- }
255-
256- if r .IsOpenShift () {
257- route := & routev1.Route {ObjectMeta : defaultMeta }
258- err = r .DeleteResource (route )
259- if err != nil {
260- reqLogger .Error (err , "Failed to clean up non-Knative resource Route" )
261- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
262- }
263- }
264-
265- if isKnativeSupported {
266- ksvc := & servingv1.Service {ObjectMeta : defaultMeta }
267- err = r .CreateOrUpdate (ksvc , instance , func () error {
268- appstacksutils .CustomizeKnativeService (ksvc , instance )
269- return nil
270- })
271-
272- if err != nil {
273- reqLogger .Error (err , "Failed to reconcile Knative Service" )
274- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
275- }
195+ } else {
276196 return r .ManageSuccess (common .StatusConditionTypeReconciled , instance )
277197 }
278198 return r .ManageError (errors .New ("failed to reconcile Knative service as operator could not find Knative CRDs" ), common .StatusConditionTypeReconciled , instance )
@@ -287,75 +207,25 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
287207 }
288208 }
289209
290- useCertmanager , err := r .GenerateSvcCertSecret ( ba , "rco" , "Runtime Component Operator" , "runtime-component-operator" )
210+ useCertmanager , err := r .UpdateSvcCertSecret ( instance , "rco" , "Runtime Component Operator" , "runtime-component-operator" )
291211 if err != nil {
292- reqLogger .Error (err , "Failed to reconcile CertManager Certificate" )
293212 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
294213 }
295- if ba .GetService ().GetCertificateSecretRef () != nil {
296- ba .GetStatus ().SetReference (common .StatusReferenceCertSecretName , * ba .GetService ().GetCertificateSecretRef ())
297- }
298214
299- svc := & corev1.Service {ObjectMeta : defaultMeta }
300- err = r .CreateOrUpdate (svc , instance , func () error {
301- appstacksutils .CustomizeService (svc , ba )
302- svc .Annotations = appstacksutils .MergeMaps (svc .Annotations , instance .Spec .Service .Annotations )
303- if ! useCertmanager && r .IsOpenShift () {
304- appstacksutils .AddOCPCertAnnotation (ba , svc )
305- }
306- monitoringEnabledLabelName := getMonitoringEnabledLabelName (ba )
307- if instance .Spec .Monitoring != nil {
308- svc .Labels [monitoringEnabledLabelName ] = "true"
309- } else {
310- delete (svc .Labels , monitoringEnabledLabelName )
311- }
312- return nil
313- })
314- if err != nil {
315- reqLogger .Error (err , "Failed to reconcile Service" )
215+ if err = r .UpdateService (instance , defaultMeta , useCertmanager ); err != nil {
316216 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
317217 }
318218
319- networkPolicy := & networkingv1.NetworkPolicy {ObjectMeta : defaultMeta }
320- if np := instance .Spec .NetworkPolicy ; ! np .IsDisabled () {
321- err = r .CreateOrUpdate (networkPolicy , instance , func () error {
322- appstacksutils .CustomizeNetworkPolicy (networkPolicy , r .IsOpenShift (), instance )
323- return nil
324- })
325- if err != nil {
326- reqLogger .Error (err , "Failed to reconcile network policy" )
327- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
328- }
329- } else {
330- if err := r .DeleteResource (networkPolicy ); err != nil {
331- reqLogger .Error (err , "Failed to delete network policy" )
332- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
333- }
219+ if err = r .UpdateNetworkPolicy (instance , defaultMeta ); err != nil {
220+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
334221 }
335222
336- err = r .ReconcileBindings (instance )
337- if err != nil {
338- return r .ManageError (err , common .StatusConditionTypeReconciled , ba )
223+ if err = r .ReconcileBindings (instance ); err != nil {
224+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
339225 }
340226
341227 if instance .Spec .StatefulSet != nil {
342- // Delete Deployment if exists
343- deploy := & appsv1.Deployment {ObjectMeta : defaultMeta }
344- err = r .DeleteResource (deploy )
345-
346- if err != nil {
347- reqLogger .Error (err , "Failed to delete Deployment" )
348- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
349- }
350- svc := & corev1.Service {ObjectMeta : metav1.ObjectMeta {Name : instance .Name + "-headless" , Namespace : instance .Namespace }}
351- err = r .CreateOrUpdate (svc , instance , func () error {
352- appstacksutils .CustomizeService (svc , instance )
353- svc .Spec .ClusterIP = corev1 .ClusterIPNone
354- svc .Spec .Type = corev1 .ServiceTypeClusterIP
355- return nil
356- })
357- if err != nil {
358- reqLogger .Error (err , "Failed to reconcile headless Service" )
228+ if err = r .UpdateStatefulSetReq (instance , defaultMeta ); err != nil {
359229 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
360230 }
361231
@@ -375,22 +245,10 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
375245 }
376246
377247 } else {
378- // Delete StatefulSet if exists
379- statefulSet := & appsv1.StatefulSet {ObjectMeta : defaultMeta }
380- err = r .DeleteResource (statefulSet )
381- if err != nil {
382- reqLogger .Error (err , "Failed to delete Statefulset" )
248+ if err = r .UpdateDeploymentReq (instance , defaultMeta ); err != nil {
383249 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
384250 }
385251
386- // Delete StatefulSet if exists
387- headlesssvc := & corev1.Service {ObjectMeta : metav1.ObjectMeta {Name : instance .Name + "-headless" , Namespace : instance .Namespace }}
388- err = r .DeleteResource (headlesssvc )
389-
390- if err != nil {
391- reqLogger .Error (err , "Failed to delete headless Service" )
392- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
393- }
394252 deploy := & appsv1.Deployment {ObjectMeta : defaultMeta }
395253 err = r .CreateOrUpdate (deploy , instance , func () error {
396254 appstacksutils .CustomizeDeployment (deploy , instance )
@@ -404,79 +262,26 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
404262 reqLogger .Error (err , "Failed to reconcile Deployment" )
405263 return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
406264 }
407-
408265 }
409266
410- if instance .Spec .Autoscaling != nil {
411- hpa := & autoscalingv1.HorizontalPodAutoscaler {ObjectMeta : defaultMeta }
412- err = r .CreateOrUpdate (hpa , instance , func () error {
413- appstacksutils .CustomizeHPA (hpa , instance )
414- return nil
415- })
416-
417- if err != nil {
418- reqLogger .Error (err , "Failed to reconcile HorizontalPodAutoscaler" )
419- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
420- }
421- } else {
422- hpa := & autoscalingv1.HorizontalPodAutoscaler {ObjectMeta : defaultMeta }
423- err = r .DeleteResource (hpa )
424- if err != nil {
425- reqLogger .Error (err , "Failed to delete HorizontalPodAutoscaler" )
426- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
427- }
267+ if err = r .UpdateAutoscaling (instance , defaultMeta ); err != nil {
268+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
428269 }
429270
430271 if ok , err := r .IsGroupVersionSupported (routev1 .SchemeGroupVersion .String (), "Route" ); err != nil {
431272 reqLogger .Error (err , fmt .Sprintf ("Failed to check if %s is supported" , routev1 .SchemeGroupVersion .String ()))
432273 r .ManageError (err , common .StatusConditionTypeReconciled , instance )
433274 } else if ok {
434- if instance .Spec .Expose != nil && * instance .Spec .Expose {
435- route := & routev1.Route {ObjectMeta : defaultMeta }
436- err = r .CreateOrUpdate (route , instance , func () error {
437- key , cert , caCert , destCACert , err := r .GetRouteTLSValues (ba )
438- if err != nil {
439- return err
440- }
441- appstacksutils .CustomizeRoute (route , ba , key , cert , caCert , destCACert )
442-
443- return nil
444- })
445- if err != nil {
446- reqLogger .Error (err , "Failed to reconcile Route" )
447- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
448- }
449- } else {
450- route := & routev1.Route {ObjectMeta : defaultMeta }
451- err = r .DeleteResource (route )
452- if err != nil {
453- reqLogger .Error (err , "Failed to delete Route" )
454- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
455- }
275+ if err = r .UpdateRoute (instance , defaultMeta ); err != nil {
276+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
456277 }
457278 } else {
458-
459279 if ok , err := r .IsGroupVersionSupported (networkingv1 .SchemeGroupVersion .String (), "Ingress" ); err != nil {
460280 reqLogger .Error (err , fmt .Sprintf ("Failed to check if %s is supported" , networkingv1 .SchemeGroupVersion .String ()))
461281 r .ManageError (err , common .StatusConditionTypeReconciled , instance )
462282 } else if ok {
463- if instance .Spec .Expose != nil && * instance .Spec .Expose {
464- ing := & networkingv1.Ingress {ObjectMeta : defaultMeta }
465- err = r .CreateOrUpdate (ing , instance , func () error {
466- appstacksutils .CustomizeIngress (ing , instance )
467- return nil
468- })
469- if err != nil {
470- reqLogger .Error (err , "Failed to reconcile Ingress" )
471- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
472- }
473- } else {
474- ing := & networkingv1.Ingress {ObjectMeta : defaultMeta }
475- err = r .DeleteResource (ing )
476- if err != nil {
477- reqLogger .Error (err , "Failed to delete Ingress" )
478- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
479- }
283+ if err = r .UpdateIngress (instance , defaultMeta ); err != nil {
284+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
480285 }
481286 }
482287 }
@@ -485,25 +290,9 @@ func (r *RuntimeComponentReconciler) Reconcile(ctx context.Context, req ctrl.Req
485290 reqLogger .Error (err , fmt .Sprintf ("Failed to check if %s is supported" , prometheusv1 .SchemeGroupVersion .String ()))
486291 r .ManageError (err , common .StatusConditionTypeReconciled , instance )
487292 } else if ok {
488- if instance .Spec .Monitoring != nil && (instance .Spec .CreateKnativeService == nil || ! * instance .Spec .CreateKnativeService ) {
489- sm := & prometheusv1.ServiceMonitor {ObjectMeta : defaultMeta }
490- err = r .CreateOrUpdate (sm , instance , func () error {
491- appstacksutils .CustomizeServiceMonitor (sm , instance )
492- return nil
493- })
494- if err != nil {
495- reqLogger .Error (err , "Failed to reconcile ServiceMonitor" )
496- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
497- }
498- } else {
499- sm := & prometheusv1.ServiceMonitor {ObjectMeta : defaultMeta }
500- err = r .DeleteResource (sm )
501- if err != nil {
502- reqLogger .Error (err , "Failed to delete ServiceMonitor" )
503- return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
504- }
293+ if err = r .UpdateServiceMonitor (instance , defaultMeta ); err != nil {
294+ return r .ManageError (err , common .StatusConditionTypeReconciled , instance )
505295 }
506-
507296 } else {
508297 reqLogger .V (1 ).Info (fmt .Sprintf ("%s is not supported" , prometheusv1 .SchemeGroupVersion .String ()))
509298 }
0 commit comments