You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2024/01/09 14:21:50 UTC

(camel-k) 02/08: chore: require Pods to have integration label

This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 43d60c10c111e4ec6e3ea7008bce152b4776d3be
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Thu Nov 30 10:34:06 2023 +0100

    chore: require Pods to have integration label
---
 pkg/cmd/operator/operator.go                       |  1 +
 .../integration/integration_controller.go          | 28 ------------------
 pkg/controller/integration/monitor.go              | 34 ++++++++++++----------
 pkg/controller/integration/monitor_cronjob.go      | 12 ++------
 pkg/controller/integration/monitor_deployment.go   |  9 ++----
 pkg/controller/integration/monitor_knative.go      | 12 ++------
 6 files changed, 26 insertions(+), 70 deletions(-)

diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index ab59ab638..04b5ea8b2 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -188,6 +188,7 @@ func Run(healthPort, monitoringPort int32, leaderElection bool, leaderElectionID
 	selector := labels.NewSelector().Add(*hasIntegrationLabel)
 
 	selectors := map[ctrl.Object]cache.ByObject{
+		&corev1.Pod{}:        {Label: selector},
 		&appsv1.Deployment{}: {Label: selector},
 		&batchv1.Job{}:       {Label: selector},
 		&servingv1.Service{}: {Label: selector},
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index c3dcd30f4..1979b9d4a 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -27,7 +27,6 @@ import (
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -458,33 +457,6 @@ func watchKnativeResources(ctx context.Context, c client.Client, b *builder.Buil
 			}),
 			builder.WithPredicates(NonManagedObjectPredicate{}),
 		).
-			// We must watch also Revisions, since it's the object that really change when a Knative service scales up and down
-			Watches(&servingv1.Revision{},
-				handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a ctrl.Object) []reconcile.Request {
-					revision, ok := a.(*servingv1.Revision)
-					if !ok {
-						log.Error(fmt.Errorf("type assertion failed: %v", a), "Failed to retrieve to retrieve KnativeService Revision")
-						return []reconcile.Request{}
-					}
-					ksvc := &servingv1.Service{
-						TypeMeta: metav1.TypeMeta{
-							Kind:       "Service",
-							APIVersion: servingv1.SchemeGroupVersion.String(),
-						},
-						ObjectMeta: metav1.ObjectMeta{
-							Name:      revision.Labels["serving.knative.dev/service"],
-							Namespace: revision.Namespace,
-						},
-					}
-					err := c.Get(ctx, ctrl.ObjectKeyFromObject(ksvc), ksvc)
-					if err != nil {
-						// The revision does not belong to any managed (owned or imported) KnativeService, just discard
-						return []reconcile.Request{}
-					}
-					return nonManagedCamelAppEnqueueRequestsFromMapFunc(ctx, c, &NonManagedCamelKnativeService{ksvc: ksvc})
-				}),
-				builder.WithPredicates(NonManagedObjectPredicate{}),
-			).
 			// Watch for the owned CronJobs
 			Owns(&servingv1.Service{}, builder.WithPredicates(StatusChangedPredicate{}))
 	}
diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index 5630f09c7..e2d3b32a3 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -28,7 +28,6 @@ import (
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/selection"
 
@@ -136,26 +135,30 @@ func (action *monitorAction) monitorPods(ctx context.Context, environment *trait
 	if err != nil {
 		return nil, err
 	}
-	if controller.isEmptySelector() {
+
+	// In order to simplify the monitoring and have a minor resource requirement, we will watch only those Pods
+	// which are labeled with `camel.apache.org/integration`. This is a design choice that requires the user to
+	// voluntarily add a label to their Pods (via template, possibly) in order to monitor the non managed Camel applications.
+
+	if !controller.hasTemplateIntegrationLabel() {
 		// This is happening when the Deployment, CronJob, etc resources
-		// have no selector or labels to identify sibling Pods.
+		// miss the Integration label, required to identify sibling Pods.
 		integration.Status.Phase = v1.IntegrationPhaseCannotMonitor
 		integration.Status.SetConditions(
 			v1.IntegrationCondition{
-				Type:    v1.IntegrationConditionMonitoringPodsAvailable,
-				Status:  corev1.ConditionFalse,
-				Reason:  v1.IntegrationConditionMonitoringPodsAvailableReason,
-				Message: fmt.Sprintf("Could not find any selector for %s. Make sure to include any label in the template and the Pods generated to inherit such label for monitoring purposes.", controller.getControllerName()),
+				Type:   v1.IntegrationConditionMonitoringPodsAvailable,
+				Status: corev1.ConditionFalse,
+				Reason: v1.IntegrationConditionMonitoringPodsAvailableReason,
+				Message: fmt.Sprintf(
+					"Could not find `camel.apache.org/integration: %s` label in the %s template. Make sure to include this label in the template for Pod monitoring purposes.",
+					integration.GetName(),
+					controller.getControllerName(),
+				),
 			},
 		)
 		return integration, nil
 	}
 
-	controllerSelector := controller.getSelector()
-	selector, err := metav1.LabelSelectorAsSelector(&controllerSelector)
-	if err != nil {
-		return nil, err
-	}
 	integration.Status.SetConditions(
 		v1.IntegrationCondition{
 			Type:   v1.IntegrationConditionMonitoringPodsAvailable,
@@ -166,13 +169,13 @@ func (action *monitorAction) monitorPods(ctx context.Context, environment *trait
 	// Enforce the scale sub-resource label selector.
 	// It is used by the HPA that queries the scale sub-resource endpoint,
 	// to list the pods owned by the integration.
-	integration.Status.Selector = selector.String()
+	integration.Status.Selector = v1.IntegrationLabel + "=" + integration.Name
 
 	// Update the replicas count
 	pendingPods := &corev1.PodList{}
 	err = action.client.List(ctx, pendingPods,
 		ctrl.InNamespace(integration.Namespace),
-		&ctrl.ListOptions{LabelSelector: selector},
+		ctrl.MatchingLabels{v1.IntegrationLabel: integration.Name},
 		ctrl.MatchingFields{"status.phase": string(corev1.PodPending)})
 	if err != nil {
 		return nil, err
@@ -180,7 +183,7 @@ func (action *monitorAction) monitorPods(ctx context.Context, environment *trait
 	runningPods := &corev1.PodList{}
 	err = action.client.List(ctx, runningPods,
 		ctrl.InNamespace(integration.Namespace),
-		&ctrl.ListOptions{LabelSelector: selector},
+		ctrl.MatchingLabels{v1.IntegrationLabel: integration.Name},
 		ctrl.MatchingFields{"status.phase": string(corev1.PodRunning)})
 	if err != nil {
 		return nil, err
@@ -296,6 +299,7 @@ type controller interface {
 	updateReadyCondition(readyPods int) bool
 	getSelector() metav1.LabelSelector
 	isEmptySelector() bool
+	hasTemplateIntegrationLabel() bool
 	getControllerName() string
 }
 
diff --git a/pkg/controller/integration/monitor_cronjob.go b/pkg/controller/integration/monitor_cronjob.go
index f5b9a6419..caa0a67a7 100644
--- a/pkg/controller/integration/monitor_cronjob.go
+++ b/pkg/controller/integration/monitor_cronjob.go
@@ -23,7 +23,6 @@ import (
 
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -112,15 +111,8 @@ func (c *cronJobController) updateReadyCondition(readyPods int) bool {
 	return false
 }
 
-func (c *cronJobController) getSelector() metav1.LabelSelector {
-	// We use all the labels which will be transferred to the Pod generated
-	return metav1.LabelSelector{
-		MatchLabels: c.obj.Spec.JobTemplate.Spec.Template.Labels,
-	}
-}
-
-func (c *cronJobController) isEmptySelector() bool {
-	return c.obj.Spec.JobTemplate.Spec.Template.Labels == nil
+func (c *cronJobController) hasTemplateIntegrationLabel() bool {
+	return c.obj.Spec.JobTemplate.Spec.Template.Labels[v1.IntegrationLabel] != ""
 }
 
 func (c *cronJobController) getControllerName() string {
diff --git a/pkg/controller/integration/monitor_deployment.go b/pkg/controller/integration/monitor_deployment.go
index e3325f8ea..08b0c35e9 100644
--- a/pkg/controller/integration/monitor_deployment.go
+++ b/pkg/controller/integration/monitor_deployment.go
@@ -23,7 +23,6 @@ import (
 
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/v2/pkg/util/kubernetes"
@@ -93,12 +92,8 @@ func (c *deploymentController) updateReadyCondition(readyPods int) bool {
 	return false
 }
 
-func (c *deploymentController) getSelector() metav1.LabelSelector {
-	return *c.obj.Spec.Selector
-}
-
-func (c *deploymentController) isEmptySelector() bool {
-	return c.obj.Spec.Selector.MatchExpressions == nil && c.obj.Spec.Selector.MatchLabels == nil
+func (c *deploymentController) hasTemplateIntegrationLabel() bool {
+	return c.obj.Spec.Template.Labels[v1.IntegrationLabel] != ""
 }
 
 func (c *deploymentController) getControllerName() string {
diff --git a/pkg/controller/integration/monitor_knative.go b/pkg/controller/integration/monitor_knative.go
index ed614f1a1..1c7019598 100644
--- a/pkg/controller/integration/monitor_knative.go
+++ b/pkg/controller/integration/monitor_knative.go
@@ -22,7 +22,6 @@ import (
 	"fmt"
 
 	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 
@@ -66,15 +65,8 @@ func (c *knativeServiceController) updateReadyCondition(readyPods int) bool {
 	return false
 }
 
-func (c *knativeServiceController) getSelector() metav1.LabelSelector {
-	// We use all the labels which will be transferred to the Pod generated
-	return metav1.LabelSelector{
-		MatchLabels: c.obj.Spec.Template.Labels,
-	}
-}
-
-func (c *knativeServiceController) isEmptySelector() bool {
-	return c.obj.Spec.Template.Labels == nil
+func (c *knativeServiceController) hasTemplateIntegrationLabel() bool {
+	return c.obj.Spec.Template.Labels[v1.IntegrationLabel] != ""
 }
 
 func (c *knativeServiceController) getControllerName() string {