squakez commented on code in PR #6902:
URL: https://github.com/apache/camel-k/pull/6902#discussion_r4409854846


##########
pkg/controller/integration/camel_monitor_regression_test.go:
##########
@@ -0,0 +1,70 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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 integration

Review Comment:
   why these tests are under `camel_monitor_regression_test.go` and not in the 
`camel_monitor_test`?



##########
pkg/controller/integration/camel_monitor.go:
##########
@@ -44,166 +39,161 @@ import (
        "github.com/apache/camel-k/v2/pkg/client"
        "github.com/apache/camel-k/v2/pkg/platform"
        "github.com/apache/camel-k/v2/pkg/util/kubernetes"
-)
-
-var camelMonitorGVK = 
monitorv1alpha1.SchemeGroupVersion.WithKind(monitorv1alpha1.AppKind)
-
-const (
-       camelMonitorDiscoveryTimeout = 10 * time.Second
+       "github.com/apache/camel-k/v2/pkg/util/log"
 )
 
 // updateCamelMonitorCondition reports resource discovery, independently of 
runtime readiness.
-// Lookup failures use the existing action error/retry path.
+// It is called only when the optional monitor watch is enabled.
 func updateCamelMonitorCondition(ctx context.Context, c ctrl.Reader, 
integration *v1.Integration) error {
-       monitor := monitorv1alpha1.NewCamelMonitor(integration.Namespace, 
integration.Name)
-       err := c.Get(ctx, ctrl.ObjectKeyFromObject(&monitor), &monitor)
+       monitors := &monitorv1alpha1.CamelMonitorList{}
+       err := c.List(ctx, monitors, ctrl.InNamespace(integration.Namespace))
        available := false
        if err == nil {
-               available, err = camelMonitorOwnedByIntegration(ctx, c, 
&monitor, integration)
+               for i := range monitors.Items {
+                       name, lookupErr := camelMonitorIntegrationName(ctx, c, 
&monitors.Items[i])
+                       if lookupErr != nil {
+                               err = lookupErr
+                       }
+                       if name == integration.Name {
+                               available = true
+
+                               break
+                       }
+               }
        }
        switch {
+       case available:
+               
integration.Status.SetCondition(v1.IntegrationConditionCamelMonitorAvailable, 
corev1.ConditionTrue,
+                       "CamelMonitorAvailable", "An associated CamelMonitor 
resource is available")
        case k8serrors.IsNotFound(err), meta.IsNoMatchError(err):
                
integration.Status.RemoveCondition(v1.IntegrationConditionCamelMonitorAvailable)
        case err != nil:
                
integration.Status.SetCondition(v1.IntegrationConditionCamelMonitorAvailable, 
corev1.ConditionUnknown,
                        "CamelMonitorLookupFailed", err.Error())
 
                return err
-       case available:
-               
integration.Status.SetCondition(v1.IntegrationConditionCamelMonitorAvailable, 
corev1.ConditionTrue,
-                       "CamelMonitorAvailable", "An associated CamelMonitor 
resource is available")
        default:
                
integration.Status.RemoveCondition(v1.IntegrationConditionCamelMonitorAvailable)
        }
 
        return nil
 }
 
-// A monitor can belong directly to the Integration or to its 
Deployment/CronJob.
-// Only these two hops are followed, in the Integration namespace, with UID 
checks
-// at both edges. Names and labels alone do not establish ownership.
-func camelMonitorOwnedByIntegration(ctx context.Context, c ctrl.Reader, 
monitor *monitorv1alpha1.CamelMonitor, integration *v1.Integration) (bool, 
error) {
-       if monitor.GetNamespace() != integration.Namespace || monitor.GetName() 
!= integration.Name {
-               return false, nil
-       }
-       for _, owner := range monitor.ObjectMeta.GetOwnerReferences() {
-               if ownerMatchesIntegration(owner, integration) {
-                       return true, nil
-               }
+// Synthetic monitors in the official API retain their source as annotations 
rather
+// than copying its discovery label. Resolve that source in the same namespace 
and
+// use its existing Integration label; monitor names need not equal 
Integration names.
+func camelMonitorIntegrationName(ctx context.Context, c ctrl.Reader, object 
ctrl.Object) (string, error) {
+       label := os.Getenv(kubernetes.CamelMonitorOperatorLabelEnvVar)
+       if label == "" {
+               return "", nil
        }
-       var lookupErr error
-       for _, owner := range monitor.ObjectMeta.GetOwnerReferences() {
-               gv, err := schema.ParseGroupVersion(owner.APIVersion)
-               if err != nil || owner.UID == "" || owner.Name != 
integration.Name {
-                       continue
-               }
-               supportedWorkload := (gv.Group == "apps" && owner.Kind == 
"Deployment") || (gv.Group == "batch" && owner.Kind == "CronJob")
-               if !supportedWorkload {
-                       continue
-               }
-               workload, err := kubernetes.GetUnstructured(ctx, c, 
gv.WithKind(owner.Kind), owner.Name, integration.Namespace)
-               if err != nil {
-                       if !k8serrors.IsNotFound(err) && 
!meta.IsNoMatchError(err) {
-                               lookupErr = err
-                       }
-
-                       continue
-               }
-               if workload.GetUID() != owner.UID {
-                       continue
+       if monitor, ok := object.(*monitorv1alpha1.CamelMonitor); ok {
+               if name := monitor.Labels[label]; name != "" {
+                       return name, nil
                }
-               for _, reference := range workload.GetOwnerReferences() {
-                       if ownerMatchesIntegration(reference, integration) {
-                               return true, nil
-                       }
+               var err error
+               object, err = camelMonitorWorkload(ctx, c, monitor)
+               if err != nil || object == nil {
+                       return "", err
                }
        }
+       if object.GetLabels()[label] == "" {
+               return "", nil
+       }
 
-       return false, lookupErr
-}
-
-func ownerMatchesIntegration(owner metav1.OwnerReference, integration 
*v1.Integration) bool {
-       gv, err := schema.ParseGroupVersion(owner.APIVersion)
-
-       return err == nil && gv.Group == v1.SchemeGroupVersion.Group && 
owner.Kind == v1.IntegrationKind &&
-               owner.Name == integration.Name && owner.UID != "" && owner.UID 
== integration.UID
+       return object.GetLabels()[v1.IntegrationLabel], nil
 }
 
-// Enqueue the same-name Integration even if the new owner no longer matches:
-// deletes and ownership changes must also clear a previously true condition.
-// Association is checked when reconciling, never inferred from the name alone.
-func camelMonitorEnqueueRequests(_ context.Context, object ctrl.Object) 
[]reconcile.Request {
-       return []reconcile.Request{{NamespacedName: 
ctrl.ObjectKeyFromObject(object)}}
-}
+func camelMonitorWorkload(ctx context.Context, c ctrl.Reader, monitor 
*monitorv1alpha1.CamelMonitor) (ctrl.Object, error) {
+       name := monitor.Annotations[monitorv1alpha1.MonitorImportedNameLabel]
+       if name == "" {
+               return nil, nil
+       }
+       var workload ctrl.Object
+       switch monitor.Annotations[monitorv1alpha1.MonitorImportedKindLabel] {
+       case "Deployment":
+               workload = &appsv1.Deployment{}
+       case "CronJob":

Review Comment:
   We also support Knative Service



##########
pkg/controller/integration/integration_controller.go:
##########
@@ -400,11 +405,19 @@ func watchIntegrationResources(c client.Client, b 
*builder.Builder) {
                Owns(&appsv1.Deployment{}, 
builder.WithPredicates(StatusChangedPredicate{})).
                // Watch for the owned Builds
                Owns(&v1.Build{}, 
builder.WithPredicates(StatusChangedPredicate{}))
+       if camelMonitorEnabled {
+               b.Watches(&appsv1.Deployment{}, camelMonitorEventHandler(c),

Review Comment:
   Why are we watching deployment as well? we should only be interested in 
watching `cmon` resources.



##########
pkg/controller/integration/integration_controller.go:
##########
@@ -300,22 +300,27 @@ func add(mgr manager.Manager, c client.Client, r 
reconcile.Reconciler) error {
                                },
                        }))
 
+       camelMonitorEnabled, err := watchCamelMonitorResources(c, b)

Review Comment:
   I'd maintain the same logic we have for the other observed objects. The 
`watchCamelMonitorResources` should be moved directly in the watching resouces 
logic (as it is done for Knative Service or Cronjob for example). Then, the 
action can set the monitor flag by repeating the verification of CRDs 
existence. If the api is installed, then it should monitor regularly the 
availability of the `cmon` resources.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to