You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2024/05/31 07:32:56 UTC

(camel-k) 03/03: feat(lint): enable nestif

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

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

commit fc32f809312b71a0d712625041306983a0b5a858
Author: Luca Burgazzoli <lb...@gmail.com>
AuthorDate: Tue May 14 14:58:28 2024 +0200

    feat(lint): enable nestif
---
 .golangci.yml                                      |  12 +-
 addons/keda/keda.go                                |   9 +-
 addons/master/master.go                            |  75 +++---
 addons/strimzi/strimzi.go                          | 138 +++++++----
 addons/telemetry/telemetry.go                      | 104 ++++----
 addons/tracing/tracing.go                          |  44 ++--
 addons/vault/aws/aws_secrets_manager.go            |  60 ++---
 addons/vault/azure/azure_key_vault.go              |  76 +++---
 addons/vault/hashicorp/hashicorp_vault.go          |  36 +--
 e2e/common/traits/health_test.go                   |   8 +
 pkg/apis/camel/v1/maven_types_support.go           |   1 +
 pkg/controller/build/build_controller.go           |  90 ++++---
 pkg/controller/build/monitor_pod.go                |   1 +
 pkg/controller/build/monitor_routine.go            |   1 +
 pkg/controller/integration/build_kit.go            | 101 ++++----
 pkg/controller/integration/initialize.go           |  43 ++--
 .../integration/integration_controller.go          | 124 +++++-----
 pkg/controller/integration/monitor.go              |   4 +
 pkg/controller/integration/monitor_cronjob.go      |  52 ++--
 pkg/controller/integrationkit/build.go             | 175 +++++++------
 pkg/controller/integrationkit/initialize.go        |  90 ++++---
 .../integrationkit/integrationkit_controller.go    |  52 ++--
 .../integrationplatform_controller.go              |  55 +++--
 pkg/controller/integrationplatform/monitor.go      |   2 +
 .../integrationprofile_controller.go               |  54 ++--
 pkg/controller/kameletbinding/error_handler.go     |  46 ++--
 .../kameletbinding/kameletbinding_controller.go    |  41 +--
 pkg/controller/pipe/error_handler.go               |  44 ++--
 pkg/controller/pipe/pipe_controller.go             |  41 +--
 pkg/controller/synthetic/synthetic.go              |  73 ++++--
 pkg/platform/defaults.go                           |  73 +++---
 pkg/platform/platform.go                           |  10 +-
 pkg/trait/builder.go                               | 137 ++++++----
 pkg/trait/camel.go                                 |   1 +
 pkg/trait/container.go                             | 121 +++++----
 pkg/trait/cron.go                                  |  88 ++++---
 pkg/trait/jvm.go                                   |   4 +-
 pkg/trait/kamelets.go                              |  71 +++---
 pkg/trait/knative.go                               | 248 ++++++++++---------
 pkg/trait/knative_service.go                       |   1 +
 pkg/trait/platform.go                              |  87 ++++---
 pkg/trait/pull_secret.go                           |  73 ++++--
 pkg/trait/quarkus.go                               |   1 +
 pkg/trait/registry.go                              |  48 ++--
 pkg/trait/security_context.go                      |  44 ++--
 pkg/trait/trait_configure.go                       |  49 ++--
 pkg/util/bindings/kamelet.go                       | 275 +++++++++++----------
 pkg/util/bindings/knative_ref.go                   |   5 +
 pkg/util/camel/camel_runtime_catalog.go            |  17 +-
 pkg/util/digest/digest.go                          |   1 +
 pkg/util/kubernetes/log/pod_scraper.go             |   2 +
 pkg/util/kubernetes/replace.go                     |  24 +-
 pkg/util/maven/maven_command.go                    |  90 ++++---
 pkg/util/source/inspector_xml.go                   |   2 +-
 pkg/util/source/inspector_yaml.go                  |   1 +
 pkg/util/watch/watch.go                            |   3 +
 56 files changed, 1751 insertions(+), 1377 deletions(-)

diff --git a/.golangci.yml b/.golangci.yml
index 35f763a68..c17f6affc 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -58,6 +58,17 @@ run:
 issues:
   exclude-files:
     - test_support.go
+  exclude-rules:
+    # Exclude some linters from running on deprecated code.
+    - path: pkg/cmd
+      linters:
+        - nestif
+    - path: pkg/install
+      linters:
+        - nestif
+    - path: pkg/util/olm
+      linters:
+        - nestif
 linters:
   enable-all: true
   disable:
@@ -90,7 +101,6 @@ linters:
     - err113
     - gomnd
     - ireturn
-    - nestif
     - nilnil
     - nlreturn
     - paralleltest
diff --git a/addons/keda/keda.go b/addons/keda/keda.go
index 184dbdb90..550fc045f 100644
--- a/addons/keda/keda.go
+++ b/addons/keda/keda.go
@@ -137,10 +137,11 @@ func (t *kedaTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondition
 
 func (t *kedaTrait) Apply(e *trait.Environment) error {
 	if e.IntegrationInPhase(camelv1.IntegrationPhaseInitialization) {
-		if t.HackControllerReplicas == nil || *t.HackControllerReplicas {
-			if err := t.hackControllerReplicas(e); err != nil {
-				return err
-			}
+		if !pointer.BoolDeref(t.HackControllerReplicas, false) {
+			return nil
+		}
+		if err := t.hackControllerReplicas(e); err != nil {
+			return err
 		}
 	} else if e.IntegrationInRunningPhases() {
 		if err := t.addScalingResources(e); err != nil {
diff --git a/addons/master/master.go b/addons/master/master.go
index 9fc0fe293..845b8bd15 100644
--- a/addons/master/master.go
+++ b/addons/master/master.go
@@ -94,51 +94,54 @@ func (t *masterTrait) Configure(e *trait.Environment) (bool, *trait.TraitConditi
 	if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseBuildingKit) && !e.IntegrationInRunningPhases() {
 		return false, nil, nil
 	}
-	if pointer.BoolDeref(t.Auto, true) {
-		// Check if the master component has been used
-		sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, t.Client, e.Integration, e.Resources)
-		if err != nil {
-			return false, nil, err
-		}
 
-		meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
-		if err != nil {
-			return false, nil, err
-		}
+	if !pointer.BoolDeref(t.Auto, true) {
+		return pointer.BoolDeref(t.Enabled, false), nil, nil
+	}
 
-		if t.Enabled == nil {
-			for _, endpoint := range meta.FromURIs {
-				if uri.GetComponent(endpoint) == masterComponent {
-					enabled := true
-					t.Enabled = &enabled
-				}
-			}
-			// No master component, can skip the trait execution
-			if !pointer.BoolDeref(t.Enabled, false) {
-				return false, nil, nil
+	// Check if the master component has been used
+	sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, t.Client, e.Integration, e.Resources)
+	if err != nil {
+		return false, nil, err
+	}
+
+	meta, err := metadata.ExtractAll(e.CamelCatalog, sources)
+	if err != nil {
+		return false, nil, err
+	}
+
+	if t.Enabled == nil {
+		for _, endpoint := range meta.FromURIs {
+			if uri.GetComponent(endpoint) == masterComponent {
+				enabled := true
+				t.Enabled = &enabled
 			}
 		}
-		if t.IncludeDelegateDependencies == nil || *t.IncludeDelegateDependencies {
-			t.delegateDependencies = findAdditionalDependencies(e, meta)
+		// No master component, can skip the trait execution
+		if !pointer.BoolDeref(t.Enabled, false) {
+			return false, nil, nil
 		}
+	}
+	if t.IncludeDelegateDependencies == nil || *t.IncludeDelegateDependencies {
+		t.delegateDependencies = findAdditionalDependencies(e, meta)
+	}
 
-		if t.ResourceName == nil {
-			val := e.Integration.Name + "-lock"
-			t.ResourceName = &val
-		}
+	if t.ResourceName == nil {
+		val := e.Integration.Name + "-lock"
+		t.ResourceName = &val
+	}
 
-		if t.ResourceType == nil {
-			t.ResourceType = pointer.String(leaseResourceType)
-		}
+	if t.ResourceType == nil {
+		t.ResourceType = pointer.String(leaseResourceType)
+	}
 
-		if t.LabelKey == nil {
-			val := v1.IntegrationLabel
-			t.LabelKey = &val
-		}
+	if t.LabelKey == nil {
+		val := v1.IntegrationLabel
+		t.LabelKey = &val
+	}
 
-		if t.LabelValue == nil {
-			t.LabelValue = &e.Integration.Name
-		}
+	if t.LabelValue == nil {
+		t.LabelValue = &e.Integration.Name
 	}
 
 	return pointer.BoolDeref(t.Enabled, false), nil, nil
diff --git a/addons/strimzi/strimzi.go b/addons/strimzi/strimzi.go
index 5d5c58895..623fd5782 100644
--- a/addons/strimzi/strimzi.go
+++ b/addons/strimzi/strimzi.go
@@ -128,42 +128,11 @@ func (s BindingProvider) fromKafkaTopicToCamel(ctx bindings.BindingContext, endp
 		props = make(map[string]string)
 	}
 	if props["brokers"] == "" {
-		// build the client if needed
-		if s.Client == nil {
-			kafkaClient, err := internalclientset.NewForConfig(ctx.Client.GetConfig())
-			if err != nil {
-				return nil, err
-			}
-			s.Client = kafkaClient
-		}
-		// look them up: first, look at the CR name
-		topic, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).Get(ctx.Ctx, endpoint.Ref.Name, v1.GetOptions{})
-		if err != nil {
-			if k8serrors.IsNotFound(err) {
-				// if not found, then, look at the .status.topicName (it may be autogenerated)
-				topicList, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).List(ctx.Ctx, v1.ListOptions{
-					FieldSelector: "status.topicName=" + endpoint.Ref.Name,
-				})
-				if err != nil {
-					return nil, err
-				}
-				if len(topicList.Items) == 0 {
-					return nil, fmt.Errorf("couldn't find any KafkaTopic with either name or topicName %s", endpoint.Ref.Name)
-				}
-				// Just return the first item
-				topic = &topicList.Items[0]
-			} else {
-				return nil, err
-			}
-		}
-		clusterName := topic.Labels[v1beta2.StrimziKafkaClusterLabel]
-		if clusterName == "" {
-			return nil, fmt.Errorf("no %q label defined on topic %s", v1beta2.StrimziKafkaClusterLabel, endpoint.Ref.Name)
-		}
-		bootstrapServers, err := s.getBootstrapServers(ctx, clusterName)
+		bootstrapServers, err := s.lookupBootstrapServers(ctx, endpoint)
 		if err != nil {
 			return nil, err
 		}
+
 		props["brokers"] = bootstrapServers
 	}
 
@@ -173,6 +142,33 @@ func (s BindingProvider) fromKafkaTopicToCamel(ctx bindings.BindingContext, endp
 	}, nil
 }
 
+func (s BindingProvider) lookupBootstrapServers(ctx bindings.BindingContext, endpoint camelv1.Endpoint) (string, error) {
+	// build the client if needed
+	if s.Client == nil {
+		kafkaClient, err := internalclientset.NewForConfig(ctx.Client.GetConfig())
+		if err != nil {
+			return "", err
+		}
+		s.Client = kafkaClient
+	}
+
+	topic, err := s.lookupTopic(ctx, endpoint)
+	if err != nil {
+		return "", err
+	}
+
+	clusterName := topic.Labels[v1beta2.StrimziKafkaClusterLabel]
+	if clusterName == "" {
+		return "", fmt.Errorf("no %q label defined on topic %s", v1beta2.StrimziKafkaClusterLabel, endpoint.Ref.Name)
+	}
+	bootstrapServers, err := s.getBootstrapServers(ctx, clusterName)
+	if err != nil {
+		return "", err
+	}
+
+	return bootstrapServers, nil
+}
+
 func (s BindingProvider) getBootstrapServers(ctx bindings.BindingContext, clusterName string) (string, error) {
 	cluster, err := s.Client.KafkaV1beta2().Kafkas(ctx.Namespace).Get(ctx.Ctx, clusterName, v1.GetOptions{})
 	if err != nil {
@@ -192,6 +188,31 @@ func (s BindingProvider) getBootstrapServers(ctx bindings.BindingContext, cluste
 	return "", fmt.Errorf("cluster %q has no listeners of name %q", clusterName, v1beta2.StrimziListenerNamePlain)
 }
 
+func (s BindingProvider) lookupTopic(ctx bindings.BindingContext, endpoint camelv1.Endpoint) (*v1beta2.KafkaTopic, error) {
+	// first check by KafkaTopic name
+	topic, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).Get(ctx.Ctx, endpoint.Ref.Name, v1.GetOptions{})
+	if err != nil && !k8serrors.IsNotFound(err) {
+		return nil, err
+	}
+	if err == nil {
+		return topic, nil
+	}
+
+	// if not found, then, look at the .status.topicName (it may be autogenerated)
+	topics, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).List(ctx.Ctx, v1.ListOptions{
+		FieldSelector: "status.topicName=" + endpoint.Ref.Name,
+	})
+
+	if err != nil {
+		return nil, err
+	}
+	if len(topics.Items) == 0 {
+		return nil, fmt.Errorf("couldn't find any KafkaTopic with either name or topicName %s", endpoint.Ref.Name)
+	}
+
+	return &topics.Items[0], nil
+}
+
 // Order --.
 func (s BindingProvider) Order() int {
 	return bindings.OrderStandard
@@ -235,27 +256,7 @@ func (s V1alpha1BindingProvider) Translate(ctx bindings.V1alpha1BindingContext,
 	}
 
 	if props["brokers"] == "" {
-		// build the client if needed
-		if s.Client == nil {
-			kafkaClient, err := internalclientset.NewForConfig(ctx.Client.GetConfig())
-			if err != nil {
-				return nil, err
-			}
-			s.Client = kafkaClient
-		}
-
-		// look them up
-		topic, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).Get(ctx.Ctx, endpoint.Ref.Name, v1.GetOptions{})
-		if err != nil {
-			return nil, err
-		}
-
-		clusterName := topic.Labels[v1beta2.StrimziKafkaClusterLabel]
-		if clusterName == "" {
-			return nil, fmt.Errorf("no %q label defined on topic %s", v1beta2.StrimziKafkaClusterLabel, endpoint.Ref.Name)
-		}
-
-		bootstrapServers, err := s.getBootstrapServers(ctx, clusterName)
+		bootstrapServers, err := s.lookupBootstrapServers(ctx, endpoint)
 		if err != nil {
 			return nil, err
 		}
@@ -297,3 +298,32 @@ func (s V1alpha1BindingProvider) getBootstrapServers(ctx bindings.V1alpha1Bindin
 func (s V1alpha1BindingProvider) Order() int {
 	return bindings.OrderStandard
 }
+
+func (s V1alpha1BindingProvider) lookupBootstrapServers(ctx bindings.V1alpha1BindingContext, endpoint camelv1alpha1.Endpoint) (string, error) {
+	// build the client if needed
+	if s.Client == nil {
+		kafkaClient, err := internalclientset.NewForConfig(ctx.Client.GetConfig())
+		if err != nil {
+			return "", err
+		}
+		s.Client = kafkaClient
+	}
+
+	// look them up
+	topic, err := s.Client.KafkaV1beta2().KafkaTopics(ctx.Namespace).Get(ctx.Ctx, endpoint.Ref.Name, v1.GetOptions{})
+	if err != nil {
+		return "", err
+	}
+
+	clusterName := topic.Labels[v1beta2.StrimziKafkaClusterLabel]
+	if clusterName == "" {
+		return "", fmt.Errorf("no %q label defined on topic %s", v1beta2.StrimziKafkaClusterLabel, endpoint.Ref.Name)
+	}
+
+	bootstrapServers, err := s.getBootstrapServers(ctx, clusterName)
+	if err != nil {
+		return "", err
+	}
+
+	return bootstrapServers, nil
+}
diff --git a/addons/telemetry/telemetry.go b/addons/telemetry/telemetry.go
index ff0ca9fa1..fb9e6b86b 100644
--- a/addons/telemetry/telemetry.go
+++ b/addons/telemetry/telemetry.go
@@ -98,36 +98,40 @@ func (t *telemetryTrait) Configure(e *trait.Environment) (bool, *trait.TraitCond
 	if e.CamelCatalog == nil {
 		return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil
 	}
+
+	if !pointer.BoolDeref(t.Auto, true) {
+		return true, nil, nil
+	}
+
 	var condition *trait.TraitCondition
-	if pointer.BoolDeref(t.Auto, true) {
-		if t.Endpoint == "" {
-			for _, locator := range discovery.TelemetryLocators {
-				endpoint, err := locator.FindEndpoint(e.Ctx, t.Client, t.L, e)
-				if err != nil {
-					return false, nil, err
-				}
-				if endpoint != "" {
-					t.L.Infof("Using tracing endpoint: %s", endpoint)
-					condition = trait.NewIntegrationCondition(
-						"Telemetry",
-						v1.IntegrationConditionTraitInfo,
-						corev1.ConditionTrue,
-						"TracingEndpoint",
-						endpoint,
-					)
-					t.Endpoint = endpoint
-					break
-				}
+
+	if t.Endpoint == "" {
+		for _, locator := range discovery.TelemetryLocators {
+			endpoint, err := locator.FindEndpoint(e.Ctx, t.Client, t.L, e)
+			if err != nil {
+				return false, nil, err
+			}
+			if endpoint != "" {
+				t.L.Infof("Using tracing endpoint: %s", endpoint)
+				condition = trait.NewIntegrationCondition(
+					"Telemetry",
+					v1.IntegrationConditionTraitInfo,
+					corev1.ConditionTrue,
+					"TracingEndpoint",
+					endpoint,
+				)
+				t.Endpoint = endpoint
+				break
 			}
 		}
+	}
 
-		if t.ServiceName == "" {
-			t.ServiceName = e.Integration.Name
-		}
+	if t.ServiceName == "" {
+		t.ServiceName = e.Integration.Name
+	}
 
-		if t.Sampler == "" {
-			t.Sampler = "on"
-		}
+	if t.Sampler == "" {
+		t.Sampler = "on"
 	}
 
 	return true, condition, nil
@@ -175,30 +179,32 @@ func (t *telemetryTrait) setCatalogConfiguration(e *trait.Environment) {
 
 // Deprecated: to be removed in future release in favor of func setCatalogConfiguration().
 func (t *telemetryTrait) setProperties(e *trait.Environment) {
-	if e.CamelCatalog != nil {
-		provider := e.CamelCatalog.CamelCatalogSpec.Runtime.Provider
-		properties := telemetryProperties[provider]
-		if appPropEnabled := properties[propEnabled]; appPropEnabled != "" {
-			e.ApplicationProperties[appPropEnabled] = "true"
-		}
-		if appPropEndpoint := properties[propEndpoint]; appPropEndpoint != "" && t.Endpoint != "" {
-			e.ApplicationProperties[appPropEndpoint] = t.Endpoint
-		}
-		if appPropServiceName := properties[propServiceName]; appPropServiceName != "" && t.ServiceName != "" {
-			e.ApplicationProperties[appPropServiceName] = "service.name=" + t.ServiceName
-		}
-		if appPropSampler := properties[propSampler]; appPropSampler != "" && t.Sampler != "" {
-			e.ApplicationProperties[appPropSampler] = t.Sampler
-		}
-		if appPropSamplerRatio := properties[propSamplerRatio]; appPropSamplerRatio != "" && t.SamplerRatio != "" {
-			e.ApplicationProperties[appPropSamplerRatio] = t.SamplerRatio
-		}
-		if appPropSamplerParentBased := properties[propSamplerParentBased]; appPropSamplerParentBased != "" {
-			if pointer.BoolDeref(t.SamplerParentBased, true) {
-				e.ApplicationProperties[appPropSamplerParentBased] = "true"
-			} else {
-				e.ApplicationProperties[appPropSamplerParentBased] = boolean.FalseString
-			}
+	if e.CamelCatalog == nil {
+		return
+	}
+
+	provider := e.CamelCatalog.CamelCatalogSpec.Runtime.Provider
+	properties := telemetryProperties[provider]
+	if appPropEnabled := properties[propEnabled]; appPropEnabled != "" {
+		e.ApplicationProperties[appPropEnabled] = "true"
+	}
+	if appPropEndpoint := properties[propEndpoint]; appPropEndpoint != "" && t.Endpoint != "" {
+		e.ApplicationProperties[appPropEndpoint] = t.Endpoint
+	}
+	if appPropServiceName := properties[propServiceName]; appPropServiceName != "" && t.ServiceName != "" {
+		e.ApplicationProperties[appPropServiceName] = "service.name=" + t.ServiceName
+	}
+	if appPropSampler := properties[propSampler]; appPropSampler != "" && t.Sampler != "" {
+		e.ApplicationProperties[appPropSampler] = t.Sampler
+	}
+	if appPropSamplerRatio := properties[propSamplerRatio]; appPropSamplerRatio != "" && t.SamplerRatio != "" {
+		e.ApplicationProperties[appPropSamplerRatio] = t.SamplerRatio
+	}
+	if appPropSamplerParentBased := properties[propSamplerParentBased]; appPropSamplerParentBased != "" {
+		if pointer.BoolDeref(t.SamplerParentBased, true) {
+			e.ApplicationProperties[appPropSamplerParentBased] = "true"
+		} else {
+			e.ApplicationProperties[appPropSamplerParentBased] = boolean.FalseString
 		}
 	}
 }
diff --git a/addons/tracing/tracing.go b/addons/tracing/tracing.go
index 8bbab9126..7acbd7d47 100644
--- a/addons/tracing/tracing.go
+++ b/addons/tracing/tracing.go
@@ -95,32 +95,34 @@ func (t *tracingTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondit
 		return false, trait.NewIntegrationConditionPlatformDisabledCatalogMissing(), nil
 	}
 
-	if pointer.BoolDeref(t.Auto, true) {
-		if t.Endpoint == "" {
-			for _, locator := range discovery.TracingLocators {
-				endpoint, err := locator.FindEndpoint(e.Ctx, t.Client, t.L, e)
-				if err != nil {
-					return false, nil, err
-				}
-				if endpoint != "" {
-					t.L.Infof("Using tracing endpoint: %s", endpoint)
-					t.Endpoint = endpoint
-					break
-				}
+	if !pointer.BoolDeref(t.Auto, true) {
+		return true, nil, nil
+	}
+
+	if t.Endpoint == "" {
+		for _, locator := range discovery.TracingLocators {
+			endpoint, err := locator.FindEndpoint(e.Ctx, t.Client, t.L, e)
+			if err != nil {
+				return false, nil, err
+			}
+			if endpoint != "" {
+				t.L.Infof("Using tracing endpoint: %s", endpoint)
+				t.Endpoint = endpoint
+				break
 			}
 		}
+	}
 
-		if t.ServiceName == "" {
-			t.ServiceName = e.Integration.Name
-		}
+	if t.ServiceName == "" {
+		t.ServiceName = e.Integration.Name
+	}
 
-		if t.SamplerType == nil {
-			t.SamplerType = &defaultSamplerType
-		}
+	if t.SamplerType == nil {
+		t.SamplerType = &defaultSamplerType
+	}
 
-		if t.SamplerParam == nil {
-			t.SamplerParam = &defaultSamplerParam
-		}
+	if t.SamplerParam == nil {
+		t.SamplerParam = &defaultSamplerParam
 	}
 
 	return true, nil, nil
diff --git a/addons/vault/aws/aws_secrets_manager.go b/addons/vault/aws/aws_secrets_manager.go
index 86d1c31b6..a89ec8cdf 100644
--- a/addons/vault/aws/aws_secrets_manager.go
+++ b/addons/vault/aws/aws_secrets_manager.go
@@ -110,37 +110,39 @@ func (t *awsSecretsManagerTrait) Apply(environment *trait.Environment) error {
 		util.StringSliceUniqueAdd(&environment.Integration.Status.Capabilities, v1.CapabilityAwsSecretsManager)
 	}
 
-	if environment.IntegrationInRunningPhases() {
-		hits := rex.FindAllStringSubmatch(t.AccessKey, -1)
-		if len(hits) >= 1 {
-			var res, _ = v1.DecodeValueSource(t.AccessKey, "aws-access-key", "The access Key provided is not valid")
-			if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
-				return err
-			} else if secretValue != "" {
-				environment.ApplicationProperties["camel.vault.aws.accessKey"] = string([]byte(secretValue))
-			}
-		} else {
-			environment.ApplicationProperties["camel.vault.aws.accessKey"] = t.AccessKey
-		}
-		hits = rex.FindAllStringSubmatch(t.SecretKey, -1)
-		if len(hits) >= 1 {
-			var res, _ = v1.DecodeValueSource(t.SecretKey, "aws-secret-key", "The secret Key provided is not valid")
-			if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
-				return err
-			} else if secretValue != "" {
-				environment.ApplicationProperties["camel.vault.aws.secretKey"] = string([]byte(secretValue))
-			}
-		} else {
-			environment.ApplicationProperties["camel.vault.aws.secretKey"] = t.SecretKey
+	if !environment.IntegrationInRunningPhases() {
+		return nil
+	}
+
+	hits := rex.FindAllStringSubmatch(t.AccessKey, -1)
+	if len(hits) >= 1 {
+		var res, _ = v1.DecodeValueSource(t.AccessKey, "aws-access-key", "The access Key provided is not valid")
+		if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
+			return err
+		} else if secretValue != "" {
+			environment.ApplicationProperties["camel.vault.aws.accessKey"] = string([]byte(secretValue))
 		}
-		environment.ApplicationProperties["camel.vault.aws.region"] = t.Region
-		environment.ApplicationProperties["camel.vault.aws.defaultCredentialsProvider"] = strconv.FormatBool(*t.UseDefaultCredentialsProvider)
-		environment.ApplicationProperties["camel.vault.aws.refreshEnabled"] = strconv.FormatBool(*t.RefreshEnabled)
-		environment.ApplicationProperties["camel.main.context-reload-enabled"] = strconv.FormatBool(*t.ContextReloadEnabled)
-		environment.ApplicationProperties["camel.vault.aws.refreshPeriod"] = t.RefreshPeriod
-		if t.Secrets != "" {
-			environment.ApplicationProperties["camel.vault.aws.secrets"] = t.Secrets
+	} else {
+		environment.ApplicationProperties["camel.vault.aws.accessKey"] = t.AccessKey
+	}
+	hits = rex.FindAllStringSubmatch(t.SecretKey, -1)
+	if len(hits) >= 1 {
+		var res, _ = v1.DecodeValueSource(t.SecretKey, "aws-secret-key", "The secret Key provided is not valid")
+		if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
+			return err
+		} else if secretValue != "" {
+			environment.ApplicationProperties["camel.vault.aws.secretKey"] = string([]byte(secretValue))
 		}
+	} else {
+		environment.ApplicationProperties["camel.vault.aws.secretKey"] = t.SecretKey
+	}
+	environment.ApplicationProperties["camel.vault.aws.region"] = t.Region
+	environment.ApplicationProperties["camel.vault.aws.defaultCredentialsProvider"] = strconv.FormatBool(*t.UseDefaultCredentialsProvider)
+	environment.ApplicationProperties["camel.vault.aws.refreshEnabled"] = strconv.FormatBool(*t.RefreshEnabled)
+	environment.ApplicationProperties["camel.main.context-reload-enabled"] = strconv.FormatBool(*t.ContextReloadEnabled)
+	environment.ApplicationProperties["camel.vault.aws.refreshPeriod"] = t.RefreshPeriod
+	if t.Secrets != "" {
+		environment.ApplicationProperties["camel.vault.aws.secrets"] = t.Secrets
 	}
 
 	return nil
diff --git a/addons/vault/azure/azure_key_vault.go b/addons/vault/azure/azure_key_vault.go
index a02fd2c17..e1a534415 100644
--- a/addons/vault/azure/azure_key_vault.go
+++ b/addons/vault/azure/azure_key_vault.go
@@ -81,6 +81,10 @@ type Trait struct {
 	BlobContainerName string `property:"blob-container-name" json:"blobContainerName,omitempty"`
 }
 
+var (
+	azureKeyValueRex = regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
+)
+
 type azureKeyVaultTrait struct {
 	trait.BaseTrait
 	Trait `property:",squash"`
@@ -117,48 +121,50 @@ func (t *azureKeyVaultTrait) Configure(environment *trait.Environment) (bool, *t
 }
 
 func (t *azureKeyVaultTrait) Apply(environment *trait.Environment) error {
-	rex := regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
+
 	if environment.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
 		util.StringSliceUniqueAdd(&environment.Integration.Status.Capabilities, v1.CapabilityAzureKeyVault)
 	}
 
-	if environment.IntegrationInRunningPhases() {
-		hits := rex.FindAllStringSubmatch(t.ClientSecret, -1)
-		if len(hits) >= 1 {
-			var res, _ = v1.DecodeValueSource(t.ClientSecret, "azure-key-vault-client-secret", "The Azure Key Vault Client Secret provided is not valid")
-			if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
-				return err
-			} else if secretValue != "" {
-				environment.ApplicationProperties["camel.vault.azure.clientSecret"] = string([]byte(secretValue))
-			}
-		} else {
-			environment.ApplicationProperties["camel.vault.azure.clientSecret"] = t.ClientSecret
-		}
-		hits = rex.FindAllStringSubmatch(t.BlobAccessKey, -1)
-		if len(hits) >= 1 {
-			var res, _ = v1.DecodeValueSource(t.BlobAccessKey, "azure-storage-blob-access-key", "The Azure Storage Blob Access Key provided is not valid")
-			if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
-				return err
-			} else if secretValue != "" {
-				environment.ApplicationProperties["camel.vault.azure.blobAccessKey"] = string([]byte(secretValue))
-			}
-		} else {
-			environment.ApplicationProperties["camel.vault.azure.blobAccessKey"] = t.BlobAccessKey
+	if !environment.IntegrationInRunningPhases() {
+		return nil
+	}
+
+	hits := azureKeyValueRex.FindAllStringSubmatch(t.ClientSecret, -1)
+	if len(hits) >= 1 {
+		var res, _ = v1.DecodeValueSource(t.ClientSecret, "azure-key-vault-client-secret", "The Azure Key Vault Client Secret provided is not valid")
+		if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
+			return err
+		} else if secretValue != "" {
+			environment.ApplicationProperties["camel.vault.azure.clientSecret"] = string([]byte(secretValue))
 		}
-		environment.ApplicationProperties["camel.vault.azure.tenantId"] = t.TenantID
-		environment.ApplicationProperties["camel.vault.azure.clientId"] = t.ClientID
-		environment.ApplicationProperties["camel.vault.azure.vaultName"] = t.VaultName
-		environment.ApplicationProperties["camel.vault.azure.refreshEnabled"] = strconv.FormatBool(*t.RefreshEnabled)
-		environment.ApplicationProperties["camel.vault.azure.azureIdentityEnabled"] = strconv.FormatBool(*t.AzureIdentityEnabled)
-		environment.ApplicationProperties["camel.main.context-reload-enabled"] = strconv.FormatBool(*t.ContextReloadEnabled)
-		environment.ApplicationProperties["camel.vault.azure.refreshPeriod"] = t.RefreshPeriod
-		if t.Secrets != "" {
-			environment.ApplicationProperties["camel.vault.azure.secrets"] = t.Secrets
+	} else {
+		environment.ApplicationProperties["camel.vault.azure.clientSecret"] = t.ClientSecret
+	}
+	hits = azureKeyValueRex.FindAllStringSubmatch(t.BlobAccessKey, -1)
+	if len(hits) >= 1 {
+		var res, _ = v1.DecodeValueSource(t.BlobAccessKey, "azure-storage-blob-access-key", "The Azure Storage Blob Access Key provided is not valid")
+		if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
+			return err
+		} else if secretValue != "" {
+			environment.ApplicationProperties["camel.vault.azure.blobAccessKey"] = string([]byte(secretValue))
 		}
-		environment.ApplicationProperties["camel.vault.azure.eventhubConnectionString"] = t.EventhubConnectionString
-		environment.ApplicationProperties["camel.vault.azure.blobAccountName"] = t.BlobAccountName
-		environment.ApplicationProperties["camel.vault.azure.blobContainerName"] = t.BlobContainerName
+	} else {
+		environment.ApplicationProperties["camel.vault.azure.blobAccessKey"] = t.BlobAccessKey
+	}
+	environment.ApplicationProperties["camel.vault.azure.tenantId"] = t.TenantID
+	environment.ApplicationProperties["camel.vault.azure.clientId"] = t.ClientID
+	environment.ApplicationProperties["camel.vault.azure.vaultName"] = t.VaultName
+	environment.ApplicationProperties["camel.vault.azure.refreshEnabled"] = strconv.FormatBool(*t.RefreshEnabled)
+	environment.ApplicationProperties["camel.vault.azure.azureIdentityEnabled"] = strconv.FormatBool(*t.AzureIdentityEnabled)
+	environment.ApplicationProperties["camel.main.context-reload-enabled"] = strconv.FormatBool(*t.ContextReloadEnabled)
+	environment.ApplicationProperties["camel.vault.azure.refreshPeriod"] = t.RefreshPeriod
+	if t.Secrets != "" {
+		environment.ApplicationProperties["camel.vault.azure.secrets"] = t.Secrets
 	}
+	environment.ApplicationProperties["camel.vault.azure.eventhubConnectionString"] = t.EventhubConnectionString
+	environment.ApplicationProperties["camel.vault.azure.blobAccountName"] = t.BlobAccountName
+	environment.ApplicationProperties["camel.vault.azure.blobContainerName"] = t.BlobContainerName
 
 	return nil
 }
diff --git a/addons/vault/hashicorp/hashicorp_vault.go b/addons/vault/hashicorp/hashicorp_vault.go
index 914ca3f7d..2542e157e 100644
--- a/addons/vault/hashicorp/hashicorp_vault.go
+++ b/addons/vault/hashicorp/hashicorp_vault.go
@@ -86,23 +86,29 @@ func (t *hashicorpVaultTrait) Apply(environment *trait.Environment) error {
 		util.StringSliceUniqueAdd(&environment.Integration.Status.Capabilities, v1.CapabilityHashicorpVault)
 	}
 
-	if environment.IntegrationInRunningPhases() {
-		hits := rex.FindAllStringSubmatch(t.Token, -1)
-		if len(hits) >= 1 {
-			var res, _ = v1.DecodeValueSource(t.Token, "hashicorp-vault-token", "The Hashicorp Vault Token provided is not valid")
-			if secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res); err != nil {
-				return err
-			} else if secretValue != "" {
-				environment.ApplicationProperties["camel.vault.hashicorp.token"] = string([]byte(secretValue))
-			}
-		} else {
-			environment.ApplicationProperties["camel.vault.hashicorp.token"] = t.Token
+	if !environment.IntegrationInRunningPhases() {
+		return nil
+	}
+
+	hits := rex.FindAllStringSubmatch(t.Token, -1)
+	if len(hits) >= 1 {
+		var res, _ = v1.DecodeValueSource(t.Token, "hashicorp-vault-token", "The Hashicorp Vault Token provided is not valid")
+
+		secretValue, err := kubernetes.ResolveValueSource(environment.Ctx, environment.Client, environment.Platform.Namespace, &res)
+		if err != nil {
+			return err
 		}
-		environment.ApplicationProperties["camel.vault.hashicorp.host"] = t.Host
-		environment.ApplicationProperties["camel.vault.hashicorp.port"] = t.Port
-		environment.ApplicationProperties["camel.vault.hashicorp.engine"] = t.Engine
-		environment.ApplicationProperties["camel.vault.hashicorp.scheme"] = t.Scheme
+		if secretValue != "" {
+			environment.ApplicationProperties["camel.vault.hashicorp.token"] = secretValue
+		}
+	} else {
+		environment.ApplicationProperties["camel.vault.hashicorp.token"] = t.Token
 	}
 
+	environment.ApplicationProperties["camel.vault.hashicorp.host"] = t.Host
+	environment.ApplicationProperties["camel.vault.hashicorp.port"] = t.Port
+	environment.ApplicationProperties["camel.vault.hashicorp.engine"] = t.Engine
+	environment.ApplicationProperties["camel.vault.hashicorp.scheme"] = t.Scheme
+
 	return nil
 }
diff --git a/e2e/common/traits/health_test.go b/e2e/common/traits/health_test.go
index 61d469d7f..22a402d32 100644
--- a/e2e/common/traits/health_test.go
+++ b/e2e/common/traits/health_test.go
@@ -77,7 +77,13 @@ func TestHealthTrait(t *testing.T) {
 			g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
 
 			pods := IntegrationPods(t, ctx, ns, name)()
+
+			t.Logf("Stopping routes for integration %s/%s (%d)", ns, name, len(pods))
+
 			for i, pod := range pods {
+
+				t.Logf("Stopping route on integration pod %s/%s", pod.Namespace, pod.Name)
+
 				// Stop the Camel route
 				request := map[string]string{
 					"type":      "exec",
@@ -100,6 +106,8 @@ func TestHealthTrait(t *testing.T) {
 				g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
 					WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
 					WithTransform(IntegrationConditionMessage, Equal(fmt.Sprintf("%d/3 pods are not ready", i+1)))))
+
+				t.Logf("Route on integration pod %s/%s stopped", pod.Namespace, pod.Name)
 			}
 
 			g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
diff --git a/pkg/apis/camel/v1/maven_types_support.go b/pkg/apis/camel/v1/maven_types_support.go
index a38d77f70..b186252cd 100644
--- a/pkg/apis/camel/v1/maven_types_support.go
+++ b/pkg/apis/camel/v1/maven_types_support.go
@@ -21,6 +21,7 @@ import (
 	"encoding/xml"
 )
 
+//nolint:nestif
 func (in *MavenArtifact) GetDependencyID() string {
 	mvn := "mvn:" + in.GroupID + ":" + in.ArtifactID
 	if in.Classifier != "" {
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 4c95574e4..45aee6a67 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -21,6 +21,8 @@ import (
 	"context"
 	"time"
 
+	"github.com/apache/camel-k/v2/pkg/util/log"
+
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -180,51 +182,32 @@ func (r *reconcileBuild) Reconcile(ctx context.Context, request reconcile.Reques
 		a.InjectLogger(targetLog)
 		a.InjectRecorder(r.recorder)
 
-		if a.CanHandle(target) {
-			targetLog.Debugf("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
+
+		targetLog.Debugf("Invoking action %s", a.Name())
+
+		newTarget, err := a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
+			return reconcile.Result{}, err
+		}
 
-			newTarget, err := a.Handle(ctx, target)
+		if newTarget != nil {
+			err := r.update(ctx, targetLog, &instance, newTarget)
 			if err != nil {
-				camelevent.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
-			if newTarget != nil {
-				if err := r.update(ctx, &instance, newTarget); err != nil {
-					camelevent.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
-					return reconcile.Result{}, err
-				}
-
-				if newTarget.Status.Phase != instance.Status.Phase {
-					targetLog.Info(
-						"State transition",
-						"phase-from", instance.Status.Phase,
-						"phase-to", newTarget.Status.Phase,
-					)
-
-					if newTarget.Status.Phase == v1.BuildPhaseError || newTarget.Status.Phase == v1.BuildPhaseFailed {
-						reason := string(newTarget.Status.Phase)
-
-						if newTarget.Status.Failure != nil {
-							reason = newTarget.Status.Failure.Reason
-						}
-
-						targetLog.Info(
-							"Build error",
-							"reason", reason,
-							"error-message", newTarget.Status.Error)
-					}
-				}
-
-				target = newTarget
-			}
+			target = newTarget
+		}
 
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyBuildUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyBuildUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 
-			break
-		}
+		break
 	}
 
 	if target.Status.Phase == v1.BuildPhaseScheduling || target.Status.Phase == v1.BuildPhaseFailed {
@@ -241,9 +224,34 @@ func (r *reconcileBuild) Reconcile(ctx context.Context, request reconcile.Reques
 	return reconcile.Result{}, nil
 }
 
-func (r *reconcileBuild) update(ctx context.Context, base *v1.Build, target *v1.Build) error {
+func (r *reconcileBuild) update(ctx context.Context, l log.Logger, base *v1.Build, target *v1.Build) error {
 	target.Status.ObservedGeneration = base.Generation
-	err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(base))
 
-	return err
+	if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(base)); err != nil {
+		camelevent.NotifyBuildError(ctx, r.client, r.recorder, base, target, err)
+		return err
+	}
+
+	if target.Status.Phase != base.Status.Phase {
+		l.Info(
+			"State transition",
+			"phase-from", base.Status.Phase,
+			"phase-to", target.Status.Phase,
+		)
+
+		if target.Status.Phase == v1.BuildPhaseError || target.Status.Phase == v1.BuildPhaseFailed {
+			reason := string(target.Status.Phase)
+
+			if target.Status.Failure != nil {
+				reason = target.Status.Failure.Reason
+			}
+
+			l.Info(
+				"Build error",
+				"reason", reason,
+				"error-message", target.Status.Error)
+		}
+	}
+
+	return nil
 }
diff --git a/pkg/controller/build/monitor_pod.go b/pkg/controller/build/monitor_pod.go
index b45948c54..8c5cde77f 100644
--- a/pkg/controller/build/monitor_pod.go
+++ b/pkg/controller/build/monitor_pod.go
@@ -68,6 +68,7 @@ func (action *monitorPodAction) Handle(ctx context.Context, build *v1.Build) (*v
 		return nil, err
 	}
 
+	//nolint:nestif
 	if pod == nil {
 		switch build.Status.Phase {
 
diff --git a/pkg/controller/build/monitor_routine.go b/pkg/controller/build/monitor_routine.go
index 3c3b3ce52..10975594a 100644
--- a/pkg/controller/build/monitor_routine.go
+++ b/pkg/controller/build/monitor_routine.go
@@ -96,6 +96,7 @@ func (action *monitorRoutineAction) Handle(ctx context.Context, build *v1.Build)
 	return nil, nil
 }
 
+//nolint:nestif
 func (action *monitorRoutineAction) runBuild(ctx context.Context, build *v1.Build) {
 	defer routines.Delete(build.Name)
 
diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go
index 0605e0113..acbc01966 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -62,52 +62,12 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integr
 	// IntegrationKit may be nil if its being upgraded
 	//
 	if integration.Status.IntegrationKit != nil {
-		// IntegrationKit fully defined so find it
-		action.L.Debugf("Finding integration kit %s for integration %s\n",
-			integration.Status.IntegrationKit.Name, integration.Name)
-		kit, err := kubernetes.GetIntegrationKit(ctx, action.client,
-			integration.Status.IntegrationKit.Name, integration.Status.IntegrationKit.Namespace)
+		it, err := action.checkIntegrationKit(ctx, integration)
 		if err != nil {
-			return nil, fmt.Errorf("unable to find integration kit %s/%s: %w",
-				integration.Status.IntegrationKit.Namespace, integration.Status.IntegrationKit.Name, err)
+			return nil, err
 		}
 
-		if kit.Labels[v1.IntegrationKitTypeLabel] == v1.IntegrationKitTypePlatform {
-			match, err := integrationMatches(ctx, action.client, integration, kit)
-			if err != nil {
-				return nil, fmt.Errorf("unable to match any integration kit with integration %s/%s: %w",
-					integration.Namespace, integration.Name, err)
-
-			} else if !match {
-				// We need to re-generate a kit, or search for a new one that
-				// matches the integration, so let's remove the association
-				// with the kit.
-
-				//
-				// All tests & conditionals check for a nil assignment
-				//
-				action.L.Debug("No match found between integration and integrationkit. Resetting integration's integrationkit to empty",
-					"integration", integration.Name,
-					"integrationkit", integration.Status.IntegrationKit.Name,
-					"namespace", integration.Namespace)
-				integration.SetIntegrationKit(nil)
-				return integration, nil
-			}
-		}
-
-		if kit.Status.Phase == v1.IntegrationKitPhaseError {
-			integration.Status.Phase = v1.IntegrationPhaseError
-			integration.SetIntegrationKit(kit)
-			return integration, nil
-		}
-
-		if kit.Status.Phase == v1.IntegrationKitPhaseReady {
-			integration.Status.Phase = v1.IntegrationPhaseDeploying
-			integration.SetIntegrationKit(kit)
-			return integration, nil
-		}
-
-		return nil, nil
+		return it, nil
 	}
 
 	action.L.Debug("No kit specified in integration status so looking up", "integration", integration.Name, "namespace", integration.Namespace)
@@ -190,3 +150,58 @@ kits:
 
 	return integration, nil
 }
+
+func (action *buildKitAction) checkIntegrationKit(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) {
+
+	// IntegrationKit fully defined so find it
+	action.L.Debugf("Finding integration kit %s for integration %s\n",
+		integration.Status.IntegrationKit.Name, integration.Name)
+
+	kit, err := kubernetes.GetIntegrationKit(ctx, action.client,
+		integration.Status.IntegrationKit.Name, integration.Status.IntegrationKit.Namespace)
+	if err != nil {
+		return nil, fmt.Errorf("unable to find integration kit %s/%s: %w",
+			integration.Status.IntegrationKit.Namespace, integration.Status.IntegrationKit.Name, err)
+	}
+
+	if kit.Labels[v1.IntegrationKitTypeLabel] == v1.IntegrationKitTypePlatform {
+		match, err := integrationMatches(ctx, action.client, integration, kit)
+		if err != nil {
+			return nil, fmt.Errorf("unable to match any integration kit with integration %s/%s: %w",
+				integration.Namespace, integration.Name, err)
+
+		}
+
+		if !match {
+			// We need to re-generate a kit, or search for a new one that
+			// matches the integration, so let's remove the association
+			// with the kit.
+
+			//
+			// All tests & conditionals check for a nil assignment
+			//
+			action.L.Debug("No match found between integration and integrationkit. Resetting integration's integrationkit to empty",
+				"integration", integration.Name,
+				"integrationkit", integration.Status.IntegrationKit.Name,
+				"namespace", integration.Namespace)
+
+			integration.SetIntegrationKit(nil)
+
+			return integration, nil
+		}
+	}
+
+	if kit.Status.Phase == v1.IntegrationKitPhaseError {
+		integration.Status.Phase = v1.IntegrationPhaseError
+		integration.SetIntegrationKit(kit)
+		return integration, nil
+	}
+
+	if kit.Status.Phase == v1.IntegrationKitPhaseReady {
+		integration.Status.Phase = v1.IntegrationPhaseDeploying
+		integration.SetIntegrationKit(kit)
+		return integration, nil
+	}
+
+	return nil, nil
+}
diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go
index ad8891647..3f40fac9b 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -66,24 +66,12 @@ func (action *initializeAction) Handle(ctx context.Context, integration *v1.Inte
 	}
 
 	if integration.Status.IntegrationKit == nil {
-		if integration.Spec.IntegrationKit != nil && integration.Spec.IntegrationKit.Name != "" {
-			kitNamespace := integration.Spec.IntegrationKit.Namespace
-			kitName := integration.Spec.IntegrationKit.Name
-
-			if kitNamespace == "" {
-				pl, err := platform.GetForResource(ctx, action.client, integration)
-				if err != nil && !k8serrors.IsNotFound(err) {
-					return nil, err
-				}
-				if pl != nil {
-					kitNamespace = pl.Namespace
-				}
-			}
-			kit := v1.NewIntegrationKit(kitNamespace, kitName)
-			integration.SetIntegrationKit(kit)
-		} else {
-			integration.Status.IntegrationKit = nil
+		ikt, err := action.lookupIntegrationKit(ctx, integration)
+		if err != nil {
+			return nil, err
 		}
+
+		integration.SetIntegrationKit(ikt)
 	}
 
 	integration.Status.Phase = v1.IntegrationPhaseBuildingKit
@@ -97,6 +85,27 @@ func (action *initializeAction) Handle(ctx context.Context, integration *v1.Inte
 	return integration, nil
 }
 
+func (action *initializeAction) lookupIntegrationKit(ctx context.Context, integration *v1.Integration) (*v1.IntegrationKit, error) {
+	if integration.Spec.IntegrationKit == nil || integration.Spec.IntegrationKit.Name == "" {
+		return nil, nil
+	}
+
+	kitNamespace := integration.Spec.IntegrationKit.Namespace
+	kitName := integration.Spec.IntegrationKit.Name
+
+	if kitNamespace == "" {
+		pl, err := platform.GetForResource(ctx, action.client, integration)
+		if err != nil && !k8serrors.IsNotFound(err) {
+			return nil, err
+		}
+		if pl != nil {
+			kitNamespace = pl.Namespace
+		}
+	}
+
+	return v1.NewIntegrationKit(kitNamespace, kitName), nil
+}
+
 func (action *initializeAction) importFromExternalApp(integration *v1.Integration) (*v1.Integration, error) {
 	readyMessage := fmt.Sprintf(
 		"imported from %s %s",
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 456c05b4d..4fbdc39b4 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -239,32 +239,35 @@ func enqueueRequestsFromConfigFunc(ctx context.Context, c client.Client, res ctr
 func integrationProfileEnqueueRequestsFromMapFunc(ctx context.Context, c client.Client, profile *v1.IntegrationProfile) []reconcile.Request {
 	var requests []reconcile.Request
 
-	if profile.Status.Phase == v1.IntegrationProfilePhaseReady {
-		list := &v1.IntegrationList{}
+	if profile.Status.Phase != v1.IntegrationProfilePhaseReady {
+		return requests
+	}
 
-		// Do global search in case of global operator
-		var opts []ctrl.ListOption
-		if !platform.IsCurrentOperatorGlobal() {
-			opts = append(opts, ctrl.InNamespace(profile.Namespace))
-		}
+	list := &v1.IntegrationList{}
 
-		if err := c.List(ctx, list, opts...); err != nil {
-			log.Error(err, "Failed to list integrations")
-			return requests
-		}
+	// Do global search in case of global operator
+	var opts []ctrl.ListOption
 
-		for i := range list.Items {
-			integration := list.Items[i]
-			if integration.Status.Phase == v1.IntegrationPhaseRunning && v1.GetIntegrationProfileAnnotation(&integration) == profile.Name {
-				if profileNamespace := v1.GetIntegrationProfileNamespaceAnnotation(&integration); profileNamespace == "" || profileNamespace == profile.Namespace {
-					log.Infof("IntegrationProfile %s changed, notify integration: %s", profile.Name, integration.Name)
-					requests = append(requests, reconcile.Request{
-						NamespacedName: types.NamespacedName{
-							Namespace: integration.Namespace,
-							Name:      integration.Name,
-						},
-					})
-				}
+	if !platform.IsCurrentOperatorGlobal() {
+		opts = append(opts, ctrl.InNamespace(profile.Namespace))
+	}
+
+	if err := c.List(ctx, list, opts...); err != nil {
+		log.Error(err, "Failed to list integrations")
+		return requests
+	}
+
+	for i := range list.Items {
+		integration := list.Items[i]
+		if integration.Status.Phase == v1.IntegrationPhaseRunning && v1.GetIntegrationProfileAnnotation(&integration) == profile.Name {
+			if profileNamespace := v1.GetIntegrationProfileNamespaceAnnotation(&integration); profileNamespace == "" || profileNamespace == profile.Namespace {
+				log.Infof("IntegrationProfile %s changed, notify integration: %s", profile.Name, integration.Name)
+				requests = append(requests, reconcile.Request{
+					NamespacedName: types.NamespacedName{
+						Namespace: integration.Namespace,
+						Name:      integration.Name,
+					},
+				})
 			}
 		}
 	}
@@ -438,25 +441,29 @@ func watchCronJobResources(b *builder.Builder) {
 
 func watchKnativeResources(ctx context.Context, c client.Client, b *builder.Builder) error {
 	// Watch for the owned Knative Services conditionally
-	if ok, err := kubernetes.IsAPIResourceInstalled(c, servingv1.SchemeGroupVersion.String(), reflect.TypeOf(servingv1.Service{}).Name()); err != nil {
+	ok, err := kubernetes.IsAPIResourceInstalled(c, servingv1.SchemeGroupVersion.String(), reflect.TypeOf(servingv1.Service{}).Name())
+	if err != nil {
 		return err
-	} else if ok {
-		// Check for permission to watch the Knative Service resource
-		checkCtx, cancel := context.WithTimeout(ctx, time.Minute)
-		defer cancel()
-		if ok, err = kubernetes.CheckPermission(checkCtx, c, serving.GroupName, "services", platform.GetOperatorWatchNamespace(), "", "watch"); err != nil {
-			return err
-		} else if ok {
-			log.Info("KnativeService resources installed in the cluster. RBAC privileges assigned correctly, you can use Knative features.")
-			b.Owns(&servingv1.Service{}, builder.WithPredicates(StatusChangedPredicate{}))
-		} else {
-			log.Info(` KnativeService resources installed in the cluster. However Camel K operator has not the required RBAC privileges. You can't use Knative features.
-				Make sure to apply the required RBAC privileges and restart the Camel K Operator Pod to be able to watch for Camel K managed Knative Services.`)
-		}
-	} else {
+	}
+	if !ok {
 		log.Info(`KnativeService resources are not installed in the cluster. You can't use Knative features. If you install Knative Serving resources after the
 			Camel K operator, make sure to apply the required RBAC privileges and restart the Camel K Operator Pod to be able to watch for
 			Camel K managed Knative Services.`)
+
+		return nil
+	}
+
+	// Check for permission to watch the Knative Service resource
+	checkCtx, cancel := context.WithTimeout(ctx, time.Minute)
+	defer cancel()
+	if ok, err = kubernetes.CheckPermission(checkCtx, c, serving.GroupName, "services", platform.GetOperatorWatchNamespace(), "", "watch"); err != nil {
+		return err
+	} else if ok {
+		log.Info("KnativeService resources installed in the cluster. RBAC privileges assigned correctly, you can use Knative features.")
+		b.Owns(&servingv1.Service{}, builder.WithPredicates(StatusChangedPredicate{}))
+	} else {
+		log.Info(` KnativeService resources installed in the cluster. However Camel K operator has not the required RBAC privileges. You can't use Knative features.
+				Make sure to apply the required RBAC privileges and restart the Camel K Operator Pod to be able to watch for Camel K managed Knative Services.`)
 	}
 
 	return nil
@@ -529,31 +536,34 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile.
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Debugf("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
 
-			newTarget, err := a.Handle(ctx, target)
-			if err != nil {
-				camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
-				// Update the integration (mostly just to update its phase) if the new instance is returned
-				if newTarget != nil {
-					_ = r.update(ctx, &instance, newTarget, &targetLog)
-				}
-				return reconcile.Result{}, err
-			}
+		targetLog.Debugf("Invoking action %s", a.Name())
 
+		newTarget, err := a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
+			// Update the integration (mostly just to update its phase) if the new instance is returned
 			if newTarget != nil {
-				if err := r.update(ctx, &instance, newTarget, &targetLog); err != nil {
-					camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
-					return reconcile.Result{}, err
-				}
+				_ = r.update(ctx, &instance, newTarget, &targetLog)
 			}
+			return reconcile.Result{}, err
+		}
 
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyIntegrationUpdated(ctx, r.client, r.recorder, &instance, newTarget)
-			break
+		if newTarget != nil {
+			if err := r.update(ctx, &instance, newTarget, &targetLog); err != nil {
+				camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
+				return reconcile.Result{}, err
+			}
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyIntegrationUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+
+		break
 	}
 
 	return reconcile.Result{}, nil
diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go
index 063eedcb4..47bb9829a 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -501,6 +501,10 @@ func (action *monitorAction) probeReadiness(ctx context.Context, environment *tr
 		if container == nil {
 			return readyPods, false, fmt.Errorf("integration container not found in Pod %s/%s", pod.Namespace, pod.Name)
 		}
+
+		// TODO: this code must be moved to a dedicated function
+		//
+		//nolint:nestif
 		if probe := container.ReadinessProbe; probe != nil && probe.HTTPGet != nil {
 			body, err := proxyGetHTTPProbe(ctx, action.client, probe, pod, container)
 			// When invoking the HTTP probe, the kubernetes client exposes a very
diff --git a/pkg/controller/integration/monitor_cronjob.go b/pkg/controller/integration/monitor_cronjob.go
index caa0a67a7..3f798deb7 100644
--- a/pkg/controller/integration/monitor_cronjob.go
+++ b/pkg/controller/integration/monitor_cronjob.go
@@ -42,31 +42,35 @@ var _ controller = &cronJobController{}
 
 func (c *cronJobController) checkReadyCondition(ctx context.Context) (bool, error) {
 	// Check latest job result
-	if lastScheduleTime := c.obj.Status.LastScheduleTime; lastScheduleTime != nil && len(c.obj.Status.Active) == 0 {
-		jobs := batchv1.JobList{}
-		if err := c.client.List(ctx, &jobs,
-			ctrl.InNamespace(c.integration.Namespace),
-			ctrl.MatchingLabels{v1.IntegrationLabel: c.integration.Name},
-		); err != nil {
-			return true, err
-		}
-		t := lastScheduleTime.Time
-		for i, job := range jobs.Items {
-			if job.Status.Active == 0 && job.CreationTimestamp.Time.Before(t) {
-				continue
-			}
-			c.lastCompletedJob = &jobs.Items[i]
-			t = c.lastCompletedJob.CreationTimestamp.Time
+	lastScheduleTime := c.obj.Status.LastScheduleTime
+
+	if lastScheduleTime == nil || len(c.obj.Status.Active) != 0 {
+		return false, nil
+	}
+
+	jobs := batchv1.JobList{}
+	if err := c.client.List(ctx, &jobs,
+		ctrl.InNamespace(c.integration.Namespace),
+		ctrl.MatchingLabels{v1.IntegrationLabel: c.integration.Name},
+	); err != nil {
+		return true, err
+	}
+	t := lastScheduleTime.Time
+	for i, job := range jobs.Items {
+		if job.Status.Active == 0 && job.CreationTimestamp.Time.Before(t) {
+			continue
 		}
-		if c.lastCompletedJob != nil {
-			if failed := kubernetes.GetJobCondition(*c.lastCompletedJob, batchv1.JobFailed); failed != nil &&
-				failed.Status == corev1.ConditionTrue {
-				c.integration.SetReadyCondition(corev1.ConditionFalse,
-					v1.IntegrationConditionLastJobFailedReason,
-					fmt.Sprintf("last job %s failed: %s", c.lastCompletedJob.Name, failed.Message))
-				c.integration.Status.Phase = v1.IntegrationPhaseError
-				return true, nil
-			}
+		c.lastCompletedJob = &jobs.Items[i]
+		t = c.lastCompletedJob.CreationTimestamp.Time
+	}
+	if c.lastCompletedJob != nil {
+		if failed := kubernetes.GetJobCondition(*c.lastCompletedJob, batchv1.JobFailed); failed != nil &&
+			failed.Status == corev1.ConditionTrue {
+			c.integration.SetReadyCondition(corev1.ConditionFalse,
+				v1.IntegrationConditionLastJobFailedReason,
+				fmt.Sprintf("last job %s failed: %s", c.lastCompletedJob.Name, failed.Message))
+			c.integration.Status.Phase = v1.IntegrationPhaseError
+			return true, nil
 		}
 	}
 
diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go
index 84a175aea..9973c2043 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -82,114 +82,125 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
 		build.Status.Phase == v1.BuildPhaseInterrupted ||
 		build.Status.Phase == v1.BuildPhaseSucceeded {
 
-		env, err := trait.Apply(ctx, action.client, nil, kit)
+		b, err := action.createBuild(ctx, kit)
 		if err != nil {
 			return nil, err
 		}
 
-		if env.CamelCatalog == nil {
-			return nil, errors.New("undefined camel catalog")
-		}
+		build = b
+	}
 
-		labels := kubernetes.FilterCamelCreatorLabels(kit.Labels)
-		labels[v1.IntegrationKitLayoutLabel] = kit.Labels[v1.IntegrationKitLayoutLabel]
+	if build.Status.Phase == v1.BuildPhaseRunning {
+		kit.Status.Phase = v1.IntegrationKitPhaseBuildRunning
+		return kit, nil
+	}
 
-		annotations := make(map[string]string)
-		if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok {
-			annotations[v1.PlatformSelectorAnnotation] = v
-		}
+	return nil, nil
+}
 
-		if v, ok := kit.Annotations[v1.IntegrationProfileAnnotation]; ok {
-			annotations[v1.IntegrationProfileAnnotation] = v
+func (action *buildAction) createBuild(ctx context.Context, kit *v1.IntegrationKit) (*v1.Build, error) {
+	env, err := trait.Apply(ctx, action.client, nil, kit)
+	if err != nil {
+		return nil, err
+	}
 
-			if v, ok := kit.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok {
-				annotations[v1.IntegrationProfileNamespaceAnnotation] = v
-			}
-		}
+	if env.CamelCatalog == nil {
+		return nil, errors.New("undefined camel catalog")
+	}
 
-		operatorID := defaults.OperatorID()
-		if operatorID != "" {
-			annotations[v1.OperatorIDAnnotation] = operatorID
-		}
+	labels := kubernetes.FilterCamelCreatorLabels(kit.Labels)
+	labels[v1.IntegrationKitLayoutLabel] = kit.Labels[v1.IntegrationKitLayoutLabel]
 
-		timeout := env.Platform.Status.Build.GetTimeout()
-		if layout := labels[v1.IntegrationKitLayoutLabel]; env.Platform.Spec.Build.Timeout == nil && layout == v1.IntegrationKitLayoutNativeSources {
-			// Increase the timeout to a sensible default
-			timeout = metav1.Duration{
-				Duration: buildTimeout,
-			}
-		}
+	annotations := make(map[string]string)
+	if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok {
+		annotations[v1.PlatformSelectorAnnotation] = v
+	}
 
-		// We may need to change certain builder configuration values
-		operatorNamespace := platform.GetOperatorNamespace()
-		buildConfig := v1.ConfigurationTasksByName(env.Pipeline, "builder")
-		if buildConfig.IsEmpty() {
-			// default to IntegrationPlatform configuration
-			buildConfig = &env.Platform.Status.Build.BuildConfiguration
-		} else {
-			if buildConfig.Strategy == "" {
-				// we always need to define a strategy, so we default to platform if none
-				buildConfig.Strategy = env.Platform.Status.Build.BuildConfiguration.Strategy
-			}
+	if v, ok := kit.Annotations[v1.IntegrationProfileAnnotation]; ok {
+		annotations[v1.IntegrationProfileAnnotation] = v
 
-			if buildConfig.OrderStrategy == "" {
-				// we always need to define an order strategy, so we default to platform if none
-				buildConfig.OrderStrategy = env.Platform.Status.Build.BuildConfiguration.OrderStrategy
-			}
+		if v, ok := kit.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok {
+			annotations[v1.IntegrationProfileNamespaceAnnotation] = v
 		}
+	}
 
-		//nolint:contextcheck
-		if buildConfig.Strategy == v1.BuildStrategyPod {
-			err = platform.CreateBuilderServiceAccount(env.Ctx, env.Client, env.Platform)
-			if err != nil {
-				return nil, fmt.Errorf("error while creating Camel K Builder service account: %w", err)
-			}
-		}
-		// The build operation, when executed as a Pod, should be executed by a container image containing the
-		// `kamel builder` command. Likely the same image running the operator should be fine.
-		buildConfig.ToolImage = platform.OperatorImage
-		buildConfig.BuilderPodNamespace = operatorNamespace
-		v1.SetBuilderConfigurationTasks(env.Pipeline, buildConfig)
-
-		build = &v1.Build{
-			TypeMeta: metav1.TypeMeta{
-				APIVersion: v1.SchemeGroupVersion.String(),
-				Kind:       v1.BuildKind,
-			},
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace:   kit.Namespace,
-				Name:        kit.Name,
-				Labels:      labels,
-				Annotations: annotations,
-			},
-			Spec: v1.BuildSpec{
-				Tasks:   env.Pipeline,
-				Timeout: timeout,
-			},
+	operatorID := defaults.OperatorID()
+	if operatorID != "" {
+		annotations[v1.OperatorIDAnnotation] = operatorID
+	}
+
+	timeout := env.Platform.Status.Build.GetTimeout()
+	if layout := labels[v1.IntegrationKitLayoutLabel]; env.Platform.Spec.Build.Timeout == nil && layout == v1.IntegrationKitLayoutNativeSources {
+		// Increase the timeout to a sensible default
+		timeout = metav1.Duration{
+			Duration: buildTimeout,
 		}
+	}
 
-		// Set the integration kit instance as the owner and controller
-		if err := controllerutil.SetControllerReference(kit, build, action.client.GetScheme()); err != nil {
-			return nil, err
+	// We may need to change certain builder configuration values
+	operatorNamespace := platform.GetOperatorNamespace()
+	buildConfig := v1.ConfigurationTasksByName(env.Pipeline, "builder")
+	if buildConfig.IsEmpty() {
+		// default to IntegrationPlatform configuration
+		buildConfig = &env.Platform.Status.Build.BuildConfiguration
+	} else {
+		if buildConfig.Strategy == "" {
+			// we always need to define a strategy, so we default to platform if none
+			buildConfig.Strategy = env.Platform.Status.Build.BuildConfiguration.Strategy
 		}
 
-		err = action.client.Delete(ctx, build)
-		if err != nil && !k8serrors.IsNotFound(err) {
-			return nil, fmt.Errorf("cannot delete build: %w", err)
+		if buildConfig.OrderStrategy == "" {
+			// we always need to define an order strategy, so we default to platform if none
+			buildConfig.OrderStrategy = env.Platform.Status.Build.BuildConfiguration.OrderStrategy
 		}
+	}
 
-		err = action.client.Create(ctx, build)
+	//nolint:contextcheck
+	if buildConfig.Strategy == v1.BuildStrategyPod {
+		err = platform.CreateBuilderServiceAccount(env.Ctx, env.Client, env.Platform)
 		if err != nil {
-			return nil, fmt.Errorf("cannot create build: %w", err)
+			return nil, fmt.Errorf("error while creating Camel K Builder service account: %w", err)
 		}
 	}
+	// The build operation, when executed as a Pod, should be executed by a container image containing the
+	// `kamel builder` command. Likely the same image running the operator should be fine.
+	buildConfig.ToolImage = platform.OperatorImage
+	buildConfig.BuilderPodNamespace = operatorNamespace
+	v1.SetBuilderConfigurationTasks(env.Pipeline, buildConfig)
+
+	build := &v1.Build{
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: v1.SchemeGroupVersion.String(),
+			Kind:       v1.BuildKind,
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace:   kit.Namespace,
+			Name:        kit.Name,
+			Labels:      labels,
+			Annotations: annotations,
+		},
+		Spec: v1.BuildSpec{
+			Tasks:   env.Pipeline,
+			Timeout: timeout,
+		},
+	}
 
-	if build.Status.Phase == v1.BuildPhaseRunning {
-		kit.Status.Phase = v1.IntegrationKitPhaseBuildRunning
-		return kit, nil
+	// Set the integration kit instance as the owner and controller
+	if err := controllerutil.SetControllerReference(kit, build, action.client.GetScheme()); err != nil {
+		return nil, err
 	}
 
-	return nil, nil
+	err = action.client.Delete(ctx, build)
+	if err != nil && !k8serrors.IsNotFound(err) {
+		return nil, fmt.Errorf("cannot delete build: %w", err)
+	}
+
+	err = action.client.Create(ctx, build)
+	if err != nil {
+		return nil, fmt.Errorf("cannot create build: %w", err)
+	}
+
+	return build, nil
 }
 
 func (action *buildAction) handleBuildRunning(ctx context.Context, kit *v1.IntegrationKit) (*v1.IntegrationKit, error) {
diff --git a/pkg/controller/integrationkit/initialize.go b/pkg/controller/integrationkit/initialize.go
index f6ea9116c..75b23ac95 100644
--- a/pkg/controller/integrationkit/initialize.go
+++ b/pkg/controller/integrationkit/initialize.go
@@ -64,50 +64,66 @@ func (action *initializeAction) Handle(ctx context.Context, kit *v1.IntegrationK
 	if err != nil {
 		return nil, err
 	}
+
 	kit.Status.Version = defaults.Version
 
-	if kit.Spec.Image == "" {
-		// Wait for CamelCatalog to be ready
-		catalog, err := kubernetes.GetCamelCatalog(
-			ctx,
-			action.client,
-			fmt.Sprintf("camel-catalog-%s", strings.ToLower(env.RuntimeVersion)),
-			kit.Namespace,
-		)
+	if kit.Spec.Image != "" {
+		return kit, nil
+	}
 
-		if err != nil {
-			if k8serrors.IsNotFound(err) {
-				// If the catalog is not available, likely it was required to be created
-				// by Integration trait, so we'll need to wait for it the be available
-				kit.Status.Phase = v1.IntegrationKitPhaseWaitingForCatalog
-				return kit, nil
-			}
-			return nil, err
-		}
+	if err := action.image(ctx, env, kit); err != nil {
+		return nil, err
+	}
 
-		if catalog.Status.Phase == v1.CamelCatalogPhaseError {
-			errorReason := fmt.Sprintf("Camel Catalog %s error", catalog.Spec.Runtime.Version)
-			kit.Status.Phase = v1.IntegrationKitPhaseError
-			kit.Status.SetErrorCondition(
-				v1.IntegrationKitConditionCatalogAvailable,
-				errorReason,
-				fmt.Errorf("%s", catalog.Status.GetCondition(v1.CamelCatalogConditionReady).Reason),
-			)
-			// Adding the failure in order to include this info in the Integration as well
-			kit.Status.Failure = &v1.Failure{
-				Reason: errorReason,
-				Time:   metav1.Now(),
-			}
-			return kit, nil
-		}
+	return kit, nil
+}
+
+func (action *initializeAction) image(ctx context.Context, env *trait.Environment, kit *v1.IntegrationKit) error {
+	// Wait for CamelCatalog to be ready
+	catalog, err := kubernetes.GetCamelCatalog(
+		ctx,
+		action.client,
+		fmt.Sprintf("camel-catalog-%s", strings.ToLower(env.RuntimeVersion)),
+		kit.Namespace,
+	)
 
-		if catalog.Status.Phase != v1.CamelCatalogPhaseReady {
+	if err != nil {
+		if k8serrors.IsNotFound(err) {
+			// If the catalog is not available, likely it was required to be created
+			// by Integration trait, so we'll need to wait for it to be available
 			kit.Status.Phase = v1.IntegrationKitPhaseWaitingForCatalog
-			return kit, nil
+			return nil
 		}
-		// now the kit can be built
-		kit.Status.Phase = v1.IntegrationKitPhaseBuildSubmitted
+
+		return err
 	}
 
-	return kit, nil
+	if catalog.Status.Phase == v1.CamelCatalogPhaseError {
+		errorReason := fmt.Sprintf("Camel Catalog %s error", catalog.Spec.Runtime.Version)
+
+		kit.Status.Phase = v1.IntegrationKitPhaseError
+		kit.Status.SetErrorCondition(
+			v1.IntegrationKitConditionCatalogAvailable,
+			errorReason,
+			fmt.Errorf("%s", catalog.Status.GetCondition(v1.CamelCatalogConditionReady).Reason),
+		)
+
+		// Adding the failure in order to include this info in the Integration as well
+		kit.Status.Failure = &v1.Failure{
+			Reason: errorReason,
+			Time:   metav1.Now(),
+		}
+
+		return nil
+	}
+
+	if catalog.Status.Phase != v1.CamelCatalogPhaseReady {
+		kit.Status.Phase = v1.IntegrationKitPhaseWaitingForCatalog
+		return nil
+	}
+
+	// now the kit can be built
+	kit.Status.Phase = v1.IntegrationKitPhaseBuildSubmitted
+
+	return nil
 }
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index 135085233..4dde58bb4 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -239,6 +239,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci
 	target := instance.DeepCopy()
 	targetLog := rlog.ForIntegrationKit(target)
 
+	//nolint:nestif
 	if target.Status.Phase == v1.IntegrationKitPhaseNone || target.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform {
 		rlog.Debug("Preparing to shift integration kit phase")
 		if target.IsExternal() || target.IsSynthetic() {
@@ -283,38 +284,41 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Infof("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
 
-			newTarget, err := a.Handle(ctx, target)
+		targetLog.Infof("Invoking action %s", a.Name())
 
-			if err != nil {
+		newTarget, err := a.Handle(ctx, target)
+
+		if err != nil {
+			camelevent.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
+			return reconcile.Result{}, err
+		}
+
+		if newTarget != nil {
+			if res, err := r.update(ctx, &instance, newTarget); err != nil {
 				camelevent.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
-				return reconcile.Result{}, err
+				return res, err
 			}
 
-			if newTarget != nil {
-				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					camelevent.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
-					return res, err
-				}
+			targetPhase = newTarget.Status.Phase
 
-				targetPhase = newTarget.Status.Phase
-
-				if targetPhase != instance.Status.Phase {
-					targetLog.Info(
-						"State transition",
-						"phase-from", instance.Status.Phase,
-						"phase-to", targetPhase,
-					)
-				}
+			if targetPhase != instance.Status.Phase {
+				targetLog.Info(
+					"State transition",
+					"phase-from", instance.Status.Phase,
+					"phase-to", targetPhase,
+				)
 			}
-
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyIntegrationKitUpdated(ctx, r.client, r.recorder, &instance, newTarget)
-			break
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyIntegrationKitUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+
+		break
 	}
 
 	if targetPhase == v1.IntegrationKitPhaseWaitingForCatalog {
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 00ba04f03..99197df4a 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -174,41 +174,44 @@ func (r *reconcileIntegrationPlatform) Reconcile(ctx context.Context, request re
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Infof("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
+
+		targetLog.Infof("Invoking action %s", a.Name())
+
+		phaseFrom := target.Status.Phase
 
-			phaseFrom := target.Status.Phase
+		target, err = a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
+			return reconcile.Result{}, err
+		}
+
+		if target != nil {
+			target.Status.ObservedGeneration = instance.Generation
 
-			target, err = a.Handle(ctx, target)
-			if err != nil {
+			if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil {
 				camelevent.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
 				return reconcile.Result{}, err
 			}
 
-			if target != nil {
-				target.Status.ObservedGeneration = instance.Generation
-
-				if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil {
-					camelevent.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
-					return reconcile.Result{}, err
-				}
-
-				targetPhase = target.Status.Phase
+			targetPhase = target.Status.Phase
 
-				if targetPhase != phaseFrom {
-					targetLog.Info(
-						"State transition",
-						"phase-from", phaseFrom,
-						"phase-to", target.Status.Phase,
-					)
-				}
+			if targetPhase != phaseFrom {
+				targetLog.Info(
+					"State transition",
+					"phase-from", phaseFrom,
+					"phase-to", target.Status.Phase,
+				)
 			}
-
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyIntegrationPlatformUpdated(ctx, r.client, r.recorder, &instance, target)
-			break
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyIntegrationPlatformUpdated(ctx, r.client, r.recorder, &instance, target)
+
+		break
 	}
 
 	if targetPhase == v1.IntegrationPlatformPhaseReady {
diff --git a/pkg/controller/integrationplatform/monitor.go b/pkg/controller/integrationplatform/monitor.go
index a231cbf2e..1156a80f9 100644
--- a/pkg/controller/integrationplatform/monitor.go
+++ b/pkg/controller/integrationplatform/monitor.go
@@ -46,6 +46,7 @@ func (action *monitorAction) CanHandle(platform *v1.IntegrationPlatform) bool {
 	return platform.Status.Phase == v1.IntegrationPlatformPhaseReady || platform.Status.Phase == v1.IntegrationPlatformPhaseError
 }
 
+//nolint:nestif
 func (action *monitorAction) Handle(ctx context.Context, platform *v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
 	// Just track the version of the operator in the platform resource
 	if platform.Status.Version != defaults.Version {
@@ -53,6 +54,7 @@ func (action *monitorAction) Handle(ctx context.Context, platform *v1.Integratio
 		action.L.Info("IntegrationPlatform version updated", "version", platform.Status.Version)
 	}
 
+	// TODO: refactor the phase transition as it is hard to reason
 	platformPhase := v1.IntegrationPlatformPhaseReady
 
 	// Refresh applied configuration
diff --git a/pkg/controller/integrationprofile/integrationprofile_controller.go b/pkg/controller/integrationprofile/integrationprofile_controller.go
index 68569230e..578f2095c 100644
--- a/pkg/controller/integrationprofile/integrationprofile_controller.go
+++ b/pkg/controller/integrationprofile/integrationprofile_controller.go
@@ -172,41 +172,43 @@ func (r *reconcileIntegrationProfile) Reconcile(ctx context.Context, request rec
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Infof("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
+
+		targetLog.Infof("Invoking action %s", a.Name())
+
+		phaseFrom := target.Status.Phase
 
-			phaseFrom := target.Status.Phase
+		target, err = a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyIntegrationProfileError(ctx, r.client, r.recorder, &instance, target, err)
+			return reconcile.Result{}, err
+		}
+
+		if target != nil {
+			target.Status.ObservedGeneration = instance.Generation
 
-			target, err = a.Handle(ctx, target)
-			if err != nil {
+			if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil {
 				camelevent.NotifyIntegrationProfileError(ctx, r.client, r.recorder, &instance, target, err)
 				return reconcile.Result{}, err
 			}
 
-			if target != nil {
-				target.Status.ObservedGeneration = instance.Generation
+			targetPhase = target.Status.Phase
 
-				if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil {
-					camelevent.NotifyIntegrationProfileError(ctx, r.client, r.recorder, &instance, target, err)
-					return reconcile.Result{}, err
-				}
-
-				targetPhase = target.Status.Phase
-
-				if targetPhase != phaseFrom {
-					targetLog.Info(
-						"State transition",
-						"phase-from", phaseFrom,
-						"phase-to", target.Status.Phase,
-					)
-				}
+			if targetPhase != phaseFrom {
+				targetLog.Info(
+					"State transition",
+					"phase-from", phaseFrom,
+					"phase-to", target.Status.Phase,
+				)
 			}
-
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyIntegrationProfileUpdated(ctx, r.client, r.recorder, &instance, target)
-			break
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyIntegrationProfileUpdated(ctx, r.client, r.recorder, &instance, target)
+		break
 	}
 
 	if targetPhase == v1.IntegrationProfilePhaseReady {
diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go
index ad8aced4d..cd3f1990d 100644
--- a/pkg/controller/kameletbinding/error_handler.go
+++ b/pkg/controller/kameletbinding/error_handler.go
@@ -27,33 +27,37 @@ import (
 )
 
 func maybeErrorHandler(errHandlConf *v1alpha1.ErrorHandlerSpec, bindingContext bindings.V1alpha1BindingContext) (*bindings.Binding, error) {
+
+	if errHandlConf == nil {
+		return nil, nil
+	}
+
 	var errorHandlerBinding *bindings.Binding
-	if errHandlConf != nil {
-		errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
-		if err != nil {
-			return nil, fmt.Errorf("could not parse error handler: %w", err)
-		}
-		// We need to get the translated URI from any referenced resource (ie, kamelets)
-		if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeSink {
-			errorHandlerBinding, err = bindings.TranslateV1alpha1(bindingContext, bindings.V1alpha1EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
-			if err != nil {
-				return nil, fmt.Errorf("could not determine error handler URI: %w", err)
-			}
-		} else {
-			// Create a new binding otherwise in order to store error handler application properties
-			errorHandlerBinding = &bindings.Binding{
-				ApplicationProperties: make(map[string]string),
-			}
-		}
 
-		err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
+	errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
+	if err != nil {
+		return nil, fmt.Errorf("could not parse error handler: %w", err)
+	}
+
+	// We need to get the translated URI from any referenced resource (ie, kamelets)
+	if errorHandlerSpec.Type() == v1alpha1.ErrorHandlerTypeSink {
+		errorHandlerBinding, err = bindings.TranslateV1alpha1(bindingContext, bindings.V1alpha1EndpointContext{Type: v1alpha1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
 		if err != nil {
-			return nil, fmt.Errorf("could not set integration error handler: %w", err)
+			return nil, fmt.Errorf("could not determine error handler URI: %w", err)
+		}
+	} else {
+		// Create a new binding otherwise in order to store error handler application properties
+		errorHandlerBinding = &bindings.Binding{
+			ApplicationProperties: make(map[string]string),
 		}
+	}
 
-		return errorHandlerBinding, nil
+	err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
+	if err != nil {
+		return nil, fmt.Errorf("could not set integration error handler: %w", err)
 	}
-	return nil, nil
+
+	return errorHandlerBinding, nil
 }
 
 func parseErrorHandler(rawMessage v1alpha1.RawMessage) (v1alpha1.ErrorHandler, error) {
diff --git a/pkg/controller/kameletbinding/kameletbinding_controller.go b/pkg/controller/kameletbinding/kameletbinding_controller.go
index 7f9776297..2c6313a19 100644
--- a/pkg/controller/kameletbinding/kameletbinding_controller.go
+++ b/pkg/controller/kameletbinding/kameletbinding_controller.go
@@ -193,31 +193,34 @@ func (r *ReconcileKameletBinding) Reconcile(ctx context.Context, request reconci
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Debugf("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
 
-			target, err = a.Handle(ctx, target)
-			if err != nil {
-				camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
-				// Update the binding (mostly just to update its phase) if the new instance is returned
-				if target != nil {
-					_ = r.update(ctx, &instance, target, &targetLog)
-				}
-				return reconcile.Result{}, err
-			}
+		targetLog.Debugf("Invoking action %s", a.Name())
 
+		target, err = a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
+			// Update the binding (mostly just to update its phase) if the new instance is returned
 			if target != nil {
-				if err := r.update(ctx, &instance, target, &targetLog); err != nil {
-					camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
-					return reconcile.Result{}, err
-				}
+				_ = r.update(ctx, &instance, target, &targetLog)
 			}
+			return reconcile.Result{}, err
+		}
 
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyKameletBindingUpdated(ctx, r.client, r.recorder, &instance, target)
-			break
+		if target != nil {
+			if err := r.update(ctx, &instance, target, &targetLog); err != nil {
+				camelevent.NotifyKameletBindingError(ctx, r.client, r.recorder, &instance, target, err)
+				return reconcile.Result{}, err
+			}
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyKameletBindingUpdated(ctx, r.client, r.recorder, &instance, target)
+
+		break
 	}
 
 	return reconcile.Result{}, nil
diff --git a/pkg/controller/pipe/error_handler.go b/pkg/controller/pipe/error_handler.go
index 13e89ea50..cdec5aea8 100644
--- a/pkg/controller/pipe/error_handler.go
+++ b/pkg/controller/pipe/error_handler.go
@@ -27,33 +27,35 @@ import (
 )
 
 func maybeErrorHandler(errHandlConf *v1.ErrorHandlerSpec, bindingContext bindings.BindingContext) (*bindings.Binding, error) {
+	if errHandlConf == nil {
+		return nil, nil
+	}
+
 	var errorHandlerBinding *bindings.Binding
-	if errHandlConf != nil {
-		errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
-		if err != nil {
-			return nil, fmt.Errorf("could not parse error handler: %w", err)
-		}
-		// We need to get the translated URI from any referenced resource (ie, kamelets)
-		if errorHandlerSpec.Type() == v1.ErrorHandlerTypeSink {
-			errorHandlerBinding, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
-			if err != nil {
-				return nil, fmt.Errorf("could not determine error handler URI: %w", err)
-			}
-		} else {
-			// Create a new binding otherwise in order to store error handler application properties
-			errorHandlerBinding = &bindings.Binding{
-				ApplicationProperties: make(map[string]string),
-			}
-		}
 
-		err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
+	errorHandlerSpec, err := parseErrorHandler(errHandlConf.RawMessage)
+	if err != nil {
+		return nil, fmt.Errorf("could not parse error handler: %w", err)
+	}
+	// We need to get the translated URI from any referenced resource (ie, kamelets)
+	if errorHandlerSpec.Type() == v1.ErrorHandlerTypeSink {
+		errorHandlerBinding, err = bindings.Translate(bindingContext, bindings.EndpointContext{Type: v1.EndpointTypeErrorHandler}, *errorHandlerSpec.Endpoint())
 		if err != nil {
-			return nil, fmt.Errorf("could not set integration error handler: %w", err)
+			return nil, fmt.Errorf("could not determine error handler URI: %w", err)
+		}
+	} else {
+		// Create a new binding otherwise in order to store error handler application properties
+		errorHandlerBinding = &bindings.Binding{
+			ApplicationProperties: make(map[string]string),
 		}
+	}
 
-		return errorHandlerBinding, nil
+	err = setErrorHandlerConfiguration(errorHandlerBinding, errorHandlerSpec)
+	if err != nil {
+		return nil, fmt.Errorf("could not set integration error handler: %w", err)
 	}
-	return nil, nil
+
+	return errorHandlerBinding, nil
 }
 
 func parseErrorHandler(rawMessage v1.RawMessage) (v1.ErrorHandler, error) {
diff --git a/pkg/controller/pipe/pipe_controller.go b/pkg/controller/pipe/pipe_controller.go
index 5b174e435..8689a1836 100644
--- a/pkg/controller/pipe/pipe_controller.go
+++ b/pkg/controller/pipe/pipe_controller.go
@@ -193,31 +193,34 @@ func (r *ReconcilePipe) Reconcile(ctx context.Context, request reconcile.Request
 		a.InjectClient(r.client)
 		a.InjectLogger(targetLog)
 
-		if a.CanHandle(target) {
-			targetLog.Debugf("Invoking action %s", a.Name())
+		if !a.CanHandle(target) {
+			continue
+		}
 
-			target, err = a.Handle(ctx, target)
-			if err != nil {
-				camelevent.NotifyPipeError(ctx, r.client, r.recorder, &instance, target, err)
-				// Update the binding (mostly just to update its phase) if the new instance is returned
-				if target != nil {
-					_ = r.update(ctx, &instance, target, &targetLog)
-				}
-				return reconcile.Result{}, err
-			}
+		targetLog.Debugf("Invoking action %s", a.Name())
 
+		target, err = a.Handle(ctx, target)
+		if err != nil {
+			camelevent.NotifyPipeError(ctx, r.client, r.recorder, &instance, target, err)
+			// Update the binding (mostly just to update its phase) if the new instance is returned
 			if target != nil {
-				if err := r.update(ctx, &instance, target, &targetLog); err != nil {
-					camelevent.NotifyPipeError(ctx, r.client, r.recorder, &instance, target, err)
-					return reconcile.Result{}, err
-				}
+				_ = r.update(ctx, &instance, target, &targetLog)
 			}
+			return reconcile.Result{}, err
+		}
 
-			// handle one action at time so the resource
-			// is always at its latest state
-			camelevent.NotifyPipeUpdated(ctx, r.client, r.recorder, &instance, target)
-			break
+		if target != nil {
+			if err := r.update(ctx, &instance, target, &targetLog); err != nil {
+				camelevent.NotifyPipeError(ctx, r.client, r.recorder, &instance, target, err)
+				return reconcile.Result{}, err
+			}
 		}
+
+		// handle one action at time so the resource
+		// is always at its latest state
+		camelevent.NotifyPipeUpdated(ctx, r.client, r.recorder, &instance, target)
+
+		break
 	}
 
 	return reconcile.Result{}, nil
diff --git a/pkg/controller/synthetic/synthetic.go b/pkg/controller/synthetic/synthetic.go
index 8e66f30d9..286eea16a 100644
--- a/pkg/controller/synthetic/synthetic.go
+++ b/pkg/controller/synthetic/synthetic.go
@@ -61,41 +61,23 @@ func ManageSyntheticIntegrations(ctx context.Context, c client.Client, cache cac
 					log.Error(fmt.Errorf("type assertion failed: %v", obj), "Failed to retrieve Object on add event")
 					return
 				}
-				if !isManagedObject(ctrlObj) {
-					integrationName := ctrlObj.GetLabels()[v1.IntegrationLabel]
-					it, err := getSyntheticIntegration(ctx, c, ctrlObj.GetNamespace(), integrationName)
-					if err != nil {
-						if k8serrors.IsNotFound(err) {
-							adapter, err := nonManagedCamelApplicationFactory(ctrlObj)
-							if err != nil {
-								log.Errorf(err, "Some error happened while creating a Camel application adapter for %s", integrationName)
-							}
-							if err = createSyntheticIntegration(ctx, c, adapter.Integration()); err != nil {
-								log.Errorf(err, "Some error happened while creating a synthetic Integration %s", integrationName)
-							}
-							log.Infof("Created a synthetic Integration %s after %s resource object", it.GetName(), ctrlObj.GetName())
-						} else {
-							log.Errorf(err, "Some error happened while loading a synthetic Integration %s", integrationName)
-						}
-					} else {
-						log.Infof("Synthetic Integration %s is in phase %s. Skipping.", integrationName, it.Status.Phase)
-					}
+				if isManagedObject(ctrlObj) {
+					return
 				}
+
+				onAdd(ctx, c, ctrlObj)
 			},
 			DeleteFunc: func(obj interface{}) {
 				ctrlObj, ok := obj.(ctrl.Object)
 				if !ok {
-					log.Error(fmt.Errorf("type assertion failed: %v", obj), "Failed to retrieve Object on delete event")
+					log.Errorf(fmt.Errorf("type assertion failed: %v", obj), "Failed to retrieve Object on delete event")
 					return
 				}
-				if !isManagedObject(ctrlObj) {
-					integrationName := ctrlObj.GetLabels()[v1.IntegrationLabel]
-					// Importing label removed
-					if err = deleteSyntheticIntegration(ctx, c, ctrlObj.GetNamespace(), integrationName); err != nil {
-						log.Errorf(err, "Some error happened while deleting a synthetic Integration %s", integrationName)
-					}
-					log.Infof("Deleted synthetic Integration %s", integrationName)
+				if isManagedObject(ctrlObj) {
+					return
 				}
+
+				onDelete(ctx, c, ctrlObj)
 			},
 		})
 		if err != nil {
@@ -106,6 +88,43 @@ func ManageSyntheticIntegrations(ctx context.Context, c client.Client, cache cac
 	return nil
 }
 
+// TODO: refactor this code and remove lint exclusion
+//
+//nolint:nestif
+func onAdd(ctx context.Context, c client.Client, ctrlObj ctrl.Object) {
+	integrationName := ctrlObj.GetLabels()[v1.IntegrationLabel]
+	it, err := getSyntheticIntegration(ctx, c, ctrlObj.GetNamespace(), integrationName)
+	if err != nil {
+		if k8serrors.IsNotFound(err) {
+			adapter, err := nonManagedCamelApplicationFactory(ctrlObj)
+			if err != nil {
+				log.Errorf(err, "Some error happened while creating a Camel application adapter for %s", integrationName)
+			}
+
+			// TODO: looking at the code, nonManagedCamelApplicationFactory may return nil but the
+			//       previous error handler does not return/break so the code below may panic when
+			//       invoking adapter.Integration()
+			if err = createSyntheticIntegration(ctx, c, adapter.Integration()); err != nil {
+				log.Errorf(err, "Some error happened while creating a synthetic Integration %s", integrationName)
+			}
+			log.Infof("Created a synthetic Integration %s after %s resource object", it.GetName(), ctrlObj.GetName())
+		} else {
+			log.Errorf(err, "Some error happened while loading a synthetic Integration %s", integrationName)
+		}
+	} else {
+		log.Infof("Synthetic Integration %s is in phase %s. Skipping.", integrationName, it.Status.Phase)
+	}
+}
+
+func onDelete(ctx context.Context, c client.Client, ctrlObj ctrl.Object) {
+	integrationName := ctrlObj.GetLabels()[v1.IntegrationLabel]
+	// Importing label removed
+	if err := deleteSyntheticIntegration(ctx, c, ctrlObj.GetNamespace(), integrationName); err != nil {
+		log.Errorf(err, "Some error happened while deleting a synthetic Integration %s", integrationName)
+	}
+	log.Infof("Deleted synthetic Integration %s", integrationName)
+}
+
 func getInformers(ctx context.Context, cl client.Client, c cache.Cache) ([]cache.Informer, error) {
 	deploy, err := c.GetInformer(ctx, &appsv1.Deployment{})
 	if err != nil {
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index 2e4222adf..f4e7cd218 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -141,41 +141,11 @@ func configureRegistry(ctx context.Context, c client.Client, p *v1.IntegrationPl
 	if p.Status.Cluster == v1.IntegrationPlatformClusterOpenShift &&
 		p.Status.Build.PublishStrategy != v1.IntegrationPlatformBuildPublishStrategyS2I &&
 		p.Status.Build.Registry.Address == "" {
-		log.Debugf("Integration Platform %s [%s]: setting registry address", p.Name, p.Namespace)
-		// Default to using OpenShift internal container images registry when using a strategy other than S2I
-		p.Status.Build.Registry.Address = defaults.OpenShiftRegistryAddress
 
-		// OpenShift automatically injects the service CA certificate into the service-ca.crt key on the ConfigMap
-		cm, err := createServiceCaBundleConfigMap(ctx, c, p)
+		err := configureForOpenShiftS2i(ctx, c, p)
 		if err != nil {
 			return err
 		}
-		log.Debugf("Integration Platform %s [%s]: setting registry certificate authority", p.Name, p.Namespace)
-		p.Status.Build.Registry.CA = cm.Name
-
-		// Default to using the registry secret that's configured for the builder service account
-		if p.Status.Build.Registry.Secret == "" {
-			log.Debugf("Integration Platform %s [%s]: setting registry secret", p.Name, p.Namespace)
-			// Bind the required role to push images to the registry
-			err := createBuilderRegistryRoleBinding(ctx, c, p)
-			if err != nil {
-				return err
-			}
-
-			sa := corev1.ServiceAccount{}
-			err = c.Get(ctx, types.NamespacedName{Namespace: p.Namespace, Name: BuilderServiceAccount}, &sa)
-			if err != nil {
-				return err
-			}
-			// We may want to read the secret keys instead of relying on the secret name scheme
-			for _, secret := range sa.Secrets {
-				if strings.Contains(secret.Name, "camel-k-builder-dockercfg") {
-					p.Status.Build.Registry.Secret = secret.Name
-
-					break
-				}
-			}
-		}
 	}
 	if p.Status.Build.Registry.Address == "" {
 		// try KEP-1755
@@ -191,6 +161,47 @@ func configureRegistry(ctx context.Context, c client.Client, p *v1.IntegrationPl
 	return nil
 }
 
+func configureForOpenShiftS2i(ctx context.Context, c client.Client, p *v1.IntegrationPlatform) error {
+	log.Debugf("Integration Platform %s [%s]: setting registry address", p.Name, p.Namespace)
+	// Default to using OpenShift internal container images registry when using a strategy other than S2I
+	p.Status.Build.Registry.Address = defaults.OpenShiftRegistryAddress
+
+	// OpenShift automatically injects the service CA certificate into the service-ca.crt key on the ConfigMap
+	cm, err := createServiceCaBundleConfigMap(ctx, c, p)
+	if err != nil {
+		return err
+	}
+
+	log.Debugf("Integration Platform %s [%s]: setting registry certificate authority", p.Name, p.Namespace)
+	p.Status.Build.Registry.CA = cm.Name
+
+	// Default to using the registry secret that's configured for the builder service account
+	if p.Status.Build.Registry.Secret == "" {
+		log.Debugf("Integration Platform %s [%s]: setting registry secret", p.Name, p.Namespace)
+		// Bind the required role to push images to the registry
+		err := createBuilderRegistryRoleBinding(ctx, c, p)
+		if err != nil {
+			return err
+		}
+
+		sa := corev1.ServiceAccount{}
+		err = c.Get(ctx, types.NamespacedName{Namespace: p.Namespace, Name: BuilderServiceAccount}, &sa)
+		if err != nil {
+			return err
+		}
+		// We may want to read the secret keys instead of relying on the secret name scheme
+		for _, secret := range sa.Secrets {
+			if strings.Contains(secret.Name, "camel-k-builder-dockercfg") {
+				p.Status.Build.Registry.Secret = secret.Name
+
+				break
+			}
+		}
+	}
+
+	return nil
+}
+
 func applyGlobalPlatformDefaults(ctx context.Context, c client.Client, p *v1.IntegrationPlatform) error {
 	operatorNamespace := GetOperatorNamespace()
 	if operatorNamespace != "" {
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index c9ba4ea64..470e2aec3 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -66,13 +66,14 @@ func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object)
 	}
 
 	if ip == nil {
-		if it, ok := o.(*v1.Integration); ok {
-			ip, err = getOrFindAny(ctx, c, it.Namespace, it.Status.Platform)
+		switch t := o.(type) {
+		case *v1.Integration:
+			ip, err = getOrFindAny(ctx, c, t.Namespace, t.Status.Platform)
 			if err != nil {
 				return nil, err
 			}
-		} else if ik, ok := o.(*v1.IntegrationKit); ok {
-			ip, err = getOrFindAny(ctx, c, ik.Namespace, ik.Status.Platform)
+		case *v1.IntegrationKit:
+			ip, err = getOrFindAny(ctx, c, t.Namespace, t.Status.Platform)
 			if err != nil {
 				return nil, err
 			}
@@ -88,7 +89,6 @@ func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object)
 
 	return ip, nil
 }
-
 func GetForName(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) {
 	return getOrFindAny(ctx, c, namespace, name)
 }
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index b84dceb35..6ba5d7f7f 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -103,42 +103,58 @@ func (t *builderTrait) Configure(e *Environment) (bool, *TraitCondition, error)
 
 	t.setPlatform(e)
 
-	if e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted) {
-		if trait := e.Catalog.GetTrait(quarkusTraitID); trait != nil {
-			quarkus, ok := trait.(*quarkusTrait)
-			isNativeIntegration := quarkus.isNativeIntegration(e)
-			isNativeKit, err := quarkus.isNativeKit(e)
-			if err != nil {
-				return false, condition, err
-			}
-			if ok && (isNativeIntegration || isNativeKit) {
-				// TODO expect maven repository in local repo (need to change builder pod accordingly!)
-				command := builder.QuarkusRuntimeSupport(e.CamelCatalog.GetCamelQuarkusVersion()).BuildCommands()
-				nativeBuilderImage := quarkus.NativeBuilderImage
-				if nativeBuilderImage == "" {
-					// default from the catalog
-					nativeBuilderImage = e.CamelCatalog.GetQuarkusToolingImage()
-				}
-				// it should be performed as the last custom task
-				t.Tasks = append(t.Tasks, fmt.Sprintf(`quarkus-native;%s;/bin/bash -c "%s"`, nativeBuilderImage, command))
-				// Force the build to run in a separate Pod and strictly sequential
-				m := "This is a Quarkus native build: setting build configuration with build Pod strategy and native container sensible resources (if not specified by the user). Make sure your cluster can handle it."
-				t.L.Info(m)
-				condition = newOrAppend(condition, m)
-				t.Strategy = string(v1.BuildStrategyPod)
-				t.OrderStrategy = string(v1.BuildOrderStrategySequential)
-				if !existsTaskRequest(t.TasksRequestCPU, "quarkus-native") {
-					t.TasksRequestCPU = append(t.TasksRequestCPU, "quarkus-native:1000m")
-				}
-				if !existsTaskRequest(t.TasksRequestMemory, "quarkus-native") {
-					t.TasksRequestMemory = append(t.TasksRequestMemory, "quarkus-native:4Gi")
-				}
-			}
+	if !e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted) {
+		return false, condition, nil
+	}
+
+	trait := e.Catalog.GetTrait(quarkusTraitID)
+	if trait != nil {
+		condition, err := t.configureForQuarkus(trait, e, condition)
+		if err != nil {
+			return false, condition, err
 		}
-		return true, condition, nil
 	}
 
-	return false, condition, nil
+	return true, condition, nil
+}
+
+func (t *builderTrait) configureForQuarkus(trait Trait, e *Environment, condition *TraitCondition) (*TraitCondition, error) {
+	quarkus, ok := trait.(*quarkusTrait)
+	isNativeIntegration := quarkus.isNativeIntegration(e)
+
+	isNativeKit, err := quarkus.isNativeKit(e)
+	if err != nil {
+		return condition, err
+	}
+
+	if ok && (isNativeIntegration || isNativeKit) {
+		// TODO expect maven repository in local repo (need to change builder pod accordingly!)
+		command := builder.QuarkusRuntimeSupport(e.CamelCatalog.GetCamelQuarkusVersion()).BuildCommands()
+		nativeBuilderImage := quarkus.NativeBuilderImage
+		if nativeBuilderImage == "" {
+			// default from the catalog
+			nativeBuilderImage = e.CamelCatalog.GetQuarkusToolingImage()
+		}
+
+		// it should be performed as the last custom task
+		t.Tasks = append(t.Tasks, fmt.Sprintf(`quarkus-native;%s;/bin/bash -c "%s"`, nativeBuilderImage, command))
+		// Force the build to run in a separate Pod and strictly sequential
+		m := "This is a Quarkus native build: setting build configuration with build Pod strategy and native container sensible resources (if not specified by the user). Make sure your cluster can handle it."
+		t.L.Info(m)
+
+		condition = newOrAppend(condition, m)
+		t.Strategy = string(v1.BuildStrategyPod)
+		t.OrderStrategy = string(v1.BuildOrderStrategySequential)
+
+		if !existsTaskRequest(t.TasksRequestCPU, "quarkus-native") {
+			t.TasksRequestCPU = append(t.TasksRequestCPU, "quarkus-native:1000m")
+		}
+		if !existsTaskRequest(t.TasksRequestMemory, "quarkus-native") {
+			t.TasksRequestMemory = append(t.TasksRequestMemory, "quarkus-native:4Gi")
+		}
+	}
+
+	return condition, nil
 }
 
 func existsTaskRequest(tasks []string, taskName string) bool {
@@ -225,31 +241,15 @@ func (t *builderTrait) Apply(e *Environment) error {
 
 	// Custom tasks
 	if t.Tasks != nil {
-		realBuildStrategy := builderTask.Configuration.Strategy
-		if realBuildStrategy == "" {
-			realBuildStrategy = e.Platform.Status.Build.BuildConfiguration.Strategy
-		}
-		if len(t.Tasks) > 0 && realBuildStrategy != v1.BuildStrategyPod {
-			if err := failIntegrationKit(
-				e,
-				"IntegrationKitTasksValid",
-				corev1.ConditionFalse,
-				"IntegrationKitTasksValid",
-				fmt.Sprintf("Pipeline tasks unavailable when using `%s` platform build strategy: use `%s` instead.",
-					realBuildStrategy,
-					v1.BuildStrategyPod),
-			); err != nil {
-				return err
-			}
-			return nil
-		}
-
-		customTasks, err := t.customTasks(tasksConf, imageName)
+		ct, err := t.determineCustomTasks(e, builderTask, tasksConf)
 		if err != nil {
 			return err
 		}
+		if ct == nil {
+			return nil
+		}
 
-		pipelineTasks = append(pipelineTasks, customTasks...)
+		pipelineTasks = append(pipelineTasks, ct...)
 	}
 
 	// Packaging task
@@ -474,6 +474,35 @@ func (t *builderTrait) getBaseImage(e *Environment) string {
 	return baseImage
 }
 
+func (t *builderTrait) determineCustomTasks(e *Environment, builderTask *v1.BuilderTask, tasksConf map[string]*v1.BuildConfiguration) ([]v1.Task, error) {
+	imageName := getImageName(e)
+
+	realBuildStrategy := builderTask.Configuration.Strategy
+	if realBuildStrategy == "" {
+		realBuildStrategy = e.Platform.Status.Build.BuildConfiguration.Strategy
+	}
+
+	if len(t.Tasks) > 0 && realBuildStrategy != v1.BuildStrategyPod {
+		err := failIntegrationKit(
+			e,
+			"IntegrationKitTasksValid",
+			corev1.ConditionFalse,
+			"IntegrationKitTasksValid",
+			fmt.Sprintf("Pipeline tasks unavailable when using `%s` platform build strategy: use `%s` instead.",
+				realBuildStrategy,
+				v1.BuildStrategyPod),
+		)
+
+		if err != nil {
+			return nil, err
+		}
+
+		return nil, nil
+	}
+
+	return t.customTasks(tasksConf, imageName)
+}
+
 // the format expected is "<task-name>;<task-image>;<task-container-command>[;<task-container-user-id>]".
 func (t *builderTrait) customTasks(tasksConf map[string]*v1.BuildConfiguration, imageName string) ([]v1.Task, error) {
 	customTasks := make([]v1.Task, len(t.Tasks))
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index 296f8993a..8a6c5a04e 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -80,6 +80,7 @@ func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) {
 	return true, nil, nil
 }
 
+//nolint:nestif
 func (t *camelTrait) Apply(e *Environment) error {
 	if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() {
 		// Synthetic Integration Kit
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index 1a217ef06..9a5d78f69 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -133,51 +133,54 @@ func (t *containerTrait) Apply(e *Environment) error {
 }
 
 func (t *containerTrait) configureImageIntegrationKit(e *Environment) error {
-	if t.Image != "" {
-		if e.Integration.Spec.IntegrationKit != nil {
-			return fmt.Errorf(
-				"unsupported configuration: a container image has been set in conjunction with an IntegrationKit %v",
-				e.Integration.Spec.IntegrationKit)
-		}
+	if t.Image == "" {
+		return nil
+	}
 
-		kitName := fmt.Sprintf("kit-%s", e.Integration.Name)
-		kit := v1.NewIntegrationKit(e.Integration.Namespace, kitName)
-		kit.Spec.Image = t.Image
-
-		// Add some information for post-processing, this may need to be refactored
-		// to a proper data structure
-		kit.Labels = map[string]string{
-			v1.IntegrationKitTypeLabel:            v1.IntegrationKitTypeSynthetic,
-			kubernetes.CamelCreatorLabelKind:      v1.IntegrationKind,
-			kubernetes.CamelCreatorLabelName:      e.Integration.Name,
-			kubernetes.CamelCreatorLabelNamespace: e.Integration.Namespace,
-			kubernetes.CamelCreatorLabelVersion:   e.Integration.ResourceVersion,
-		}
+	if e.Integration.Spec.IntegrationKit != nil {
+		return fmt.Errorf(
+			"unsupported configuration: a container image has been set in conjunction with an IntegrationKit %v",
+			e.Integration.Spec.IntegrationKit)
+	}
 
-		if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
-			v1.SetAnnotation(&kit.ObjectMeta, v1.PlatformSelectorAnnotation, v)
-		}
+	kitName := fmt.Sprintf("kit-%s", e.Integration.Name)
+	kit := v1.NewIntegrationKit(e.Integration.Namespace, kitName)
+	kit.Spec.Image = t.Image
+
+	// Add some information for post-processing, this may need to be refactored
+	// to a proper data structure
+	kit.Labels = map[string]string{
+		v1.IntegrationKitTypeLabel:            v1.IntegrationKitTypeSynthetic,
+		kubernetes.CamelCreatorLabelKind:      v1.IntegrationKind,
+		kubernetes.CamelCreatorLabelName:      e.Integration.Name,
+		kubernetes.CamelCreatorLabelNamespace: e.Integration.Namespace,
+		kubernetes.CamelCreatorLabelVersion:   e.Integration.ResourceVersion,
+	}
 
-		if v, ok := e.Integration.Annotations[v1.IntegrationProfileAnnotation]; ok {
-			v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileAnnotation, v)
+	if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok {
+		v1.SetAnnotation(&kit.ObjectMeta, v1.PlatformSelectorAnnotation, v)
+	}
 
-			if v, ok := e.Integration.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok {
-				v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, v)
-			} else {
-				// set integration profile namespace to the integration namespace.
-				// this is because the kit may live in another namespace and needs to resolve the integration profile from the integration namespace.
-				v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, e.Integration.Namespace)
-			}
-		}
+	if v, ok := e.Integration.Annotations[v1.IntegrationProfileAnnotation]; ok {
+		v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileAnnotation, v)
 
-		operatorID := defaults.OperatorID()
-		if operatorID != "" {
-			kit.SetOperatorID(operatorID)
+		if v, ok := e.Integration.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok {
+			v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, v)
+		} else {
+			// set integration profile namespace to the integration namespace.
+			// this is because the kit may live in another namespace and needs to resolve the integration profile from the integration namespace.
+			v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, e.Integration.Namespace)
 		}
+	}
 
-		e.Resources.Add(kit)
-		e.Integration.SetIntegrationKit(kit)
+	operatorID := defaults.OperatorID()
+	if operatorID != "" {
+		kit.SetOperatorID(operatorID)
 	}
+
+	e.Resources.Add(kit)
+	e.Integration.SetIntegrationKit(kit)
+
 	return nil
 }
 
@@ -355,24 +358,38 @@ func (t *containerTrait) setSecurityContext(e *Environment, container *corev1.Co
 		AllowPrivilegeEscalation: t.AllowPrivilegeEscalation,
 		Capabilities:             &corev1.Capabilities{Drop: t.CapabilitiesDrop, Add: t.CapabilitiesAdd},
 	}
-	if t.RunAsUser == nil {
-		// get security context UID from Openshift when non configured by the user
-		isOpenShift, err := openshift.IsOpenShift(e.Client)
-		if err != nil {
-			return err
-		}
-		if isOpenShift {
-			runAsUser, err := openshift.GetOpenshiftUser(e.Ctx, e.Client, e.Integration.Namespace)
-			if err != nil {
-				return err
-			}
-			if runAsUser != nil {
-				t.RunAsUser = runAsUser
-			}
-		}
+
+	runAsUser, err := t.getUser(e)
+	if err != nil {
+		return err
 	}
+
+	t.RunAsUser = runAsUser
+
 	sc.RunAsUser = t.RunAsUser
 	container.SecurityContext = &sc
 
 	return nil
 }
+
+func (t *containerTrait) getUser(e *Environment) (*int64, error) {
+	if t.RunAsUser != nil {
+		return t.RunAsUser, nil
+	}
+
+	// get security context UID from Openshift when non.configured by the user
+	isOpenShift, err := openshift.IsOpenShift(e.Client)
+	if err != nil {
+		return nil, err
+	}
+	if !isOpenShift {
+		return nil, nil
+	}
+
+	runAsUser, err := openshift.GetOpenshiftUser(e.Ctx, e.Client, e.Integration.Namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	return runAsUser, nil
+}
diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go
index 4eee0a46c..ef954d79a 100644
--- a/pkg/trait/cron.go
+++ b/pkg/trait/cron.go
@@ -101,46 +101,19 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) {
 			"the runtime provider %s does not declare 'cron' capability",
 		), nil
 	}
+
 	if pointer.BoolDeref(t.Auto, true) {
-		globalCron, err := t.getGlobalCron(e)
+		err := t.autoConfigure(e)
 		if err != nil {
-			return false, NewIntegrationCondition(
-				"Cron",
-				v1.IntegrationConditionCronJobAvailable,
-				corev1.ConditionFalse,
-				v1.IntegrationConditionCronJobNotAvailableReason,
-				err.Error(),
-			), err
-		}
-
-		if t.Schedule == "" && globalCron != nil {
-			t.Schedule = globalCron.schedule
-		}
-
-		if globalCron != nil {
-			configuredComponents := strings.FieldsFunc(t.Components, func(c rune) bool { return c == ',' })
-			for _, c := range globalCron.components {
-				util.StringSliceUniqueAdd(&configuredComponents, c)
-			}
-			t.Components = strings.Join(configuredComponents, ",")
-		}
-
-		if t.ConcurrencyPolicy == "" {
-			t.ConcurrencyPolicy = string(batchv1.ForbidConcurrent)
-		}
-
-		if (t.Schedule == "" && t.Components == "") && t.Fallback == nil {
-			// If there's at least a `cron` endpoint, add a fallback implementation
-			fromURIs, err := t.getSourcesFromURIs(e)
-			if err != nil {
-				return false, nil, err
-			}
-			for _, fromURI := range fromURIs {
-				if uri.GetComponent(fromURI) == genericCronComponent {
-					t.Fallback = pointer.Bool(true)
-					break
-				}
-			}
+			return false,
+				NewIntegrationCondition(
+					"Cron",
+					v1.IntegrationConditionCronJobAvailable,
+					corev1.ConditionFalse,
+					v1.IntegrationConditionCronJobNotAvailableReason,
+					err.Error(),
+				),
+				err
 		}
 	}
 
@@ -177,6 +150,45 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) {
 	return t.Schedule != "", nil, nil
 }
 
+func (t *cronTrait) autoConfigure(e *Environment) error {
+	globalCron, err := t.getGlobalCron(e)
+	if err != nil {
+		return err
+	}
+
+	if t.Schedule == "" && globalCron != nil {
+		t.Schedule = globalCron.schedule
+	}
+
+	if globalCron != nil {
+		configuredComponents := strings.FieldsFunc(t.Components, func(c rune) bool { return c == ',' })
+		for _, c := range globalCron.components {
+			util.StringSliceUniqueAdd(&configuredComponents, c)
+		}
+		t.Components = strings.Join(configuredComponents, ",")
+	}
+
+	if t.ConcurrencyPolicy == "" {
+		t.ConcurrencyPolicy = string(batchv1.ForbidConcurrent)
+	}
+
+	if (t.Schedule == "" && t.Components == "") && t.Fallback == nil {
+		// If there's at least a `cron` endpoint, add a fallback implementation
+		fromURIs, err := t.getSourcesFromURIs(e)
+		if err != nil {
+			return err
+		}
+		for _, fromURI := range fromURIs {
+			if uri.GetComponent(fromURI) == genericCronComponent {
+				t.Fallback = pointer.Bool(true)
+				break
+			}
+		}
+	}
+
+	return nil
+}
+
 func (t *cronTrait) Apply(e *Environment) error {
 	if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
 		util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityCron)
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index 5e5fe7e13..f79e03b83 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -227,7 +227,7 @@ func (t *jvmTrait) prepareClasspathItems(container *corev1.Container) []string {
 func (t *jvmTrait) prepareHTTPProxy(container *corev1.Container) ([]string, error) {
 	var args []string
 
-	//nolint:dupl
+	//nolint:dupl,nestif
 	if HTTPProxy := envvar.Get(container.Env, "HTTP_PROXY"); HTTPProxy != nil {
 		u, err := url.Parse(HTTPProxy.Value)
 		if err != nil {
@@ -247,7 +247,7 @@ func (t *jvmTrait) prepareHTTPProxy(container *corev1.Container) ([]string, erro
 		}
 	}
 
-	//nolint:dupl
+	//nolint:dupl,nestif
 	if HTTPSProxy := envvar.Get(container.Env, "HTTPS_PROXY"); HTTPSProxy != nil {
 		u, err := url.Parse(HTTPSProxy.Value)
 		if err != nil {
diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go
index cbe57786b..8f59d547b 100644
--- a/pkg/trait/kamelets.go
+++ b/pkg/trait/kamelets.go
@@ -171,44 +171,47 @@ func (t *kameletsTrait) collectKamelets(e *Environment) (map[string]*v1.Kamelet,
 }
 
 func (t *kameletsTrait) addKamelets(e *Environment) error {
-	if len(t.getKameletKeys()) > 0 {
-		kamelets, err := t.collectKamelets(e)
-		if err != nil {
-			return err
-		}
-		kb := newKameletBundle()
-		for _, key := range t.getKameletKeys() {
-			kamelet := kamelets[key]
-			if err := t.addKameletAsSource(e, kamelet); err != nil {
-				return err
-			}
-			// Adding dependencies from Kamelets
-			util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
-			// Add to Kamelet bundle configmap
-			kb.add(kamelet)
-		}
-		bundleConfigmaps, err := kb.toConfigmaps(e.Integration.Name, e.Integration.Namespace)
-		if err != nil {
+	if len(t.getKameletKeys()) == 0 {
+		return nil
+	}
+
+	kamelets, err := t.collectKamelets(e)
+	if err != nil {
+		return err
+	}
+	kb := newKameletBundle()
+	for _, key := range t.getKameletKeys() {
+		kamelet := kamelets[key]
+		if err := t.addKameletAsSource(e, kamelet); err != nil {
 			return err
 		}
-		// set kamelets runtime location
-		if e.ApplicationProperties == nil {
-			e.ApplicationProperties = map[string]string{}
-		}
-		for _, cm := range bundleConfigmaps {
-			kameletMountPoint := fmt.Sprintf("%s/%s", t.MountPoint, cm.Name)
-			cm.Annotations[kameletMountPointAnnotation] = kameletMountPoint
-			e.Resources.Add(cm)
-			if e.ApplicationProperties[KameletLocationProperty] == "" {
-				e.ApplicationProperties[KameletLocationProperty] = fmt.Sprintf("file:%s", kameletMountPoint)
-			} else {
-				e.ApplicationProperties[KameletLocationProperty] += fmt.Sprintf(",file:%s", kameletMountPoint)
-			}
+		// Adding dependencies from Kamelets
+		util.StringSliceUniqueConcat(&e.Integration.Status.Dependencies, kamelet.Spec.Dependencies)
+		// Add to Kamelet bundle configmap
+		kb.add(kamelet)
+	}
+	bundleConfigmaps, err := kb.toConfigmaps(e.Integration.Name, e.Integration.Namespace)
+	if err != nil {
+		return err
+	}
+	// set kamelets runtime location
+	if e.ApplicationProperties == nil {
+		e.ApplicationProperties = map[string]string{}
+	}
+	for _, cm := range bundleConfigmaps {
+		kameletMountPoint := fmt.Sprintf("%s/%s", t.MountPoint, cm.Name)
+		cm.Annotations[kameletMountPointAnnotation] = kameletMountPoint
+		e.Resources.Add(cm)
+		if e.ApplicationProperties[KameletLocationProperty] == "" {
+			e.ApplicationProperties[KameletLocationProperty] = fmt.Sprintf("file:%s", kameletMountPoint)
+		} else {
+			e.ApplicationProperties[KameletLocationProperty] += fmt.Sprintf(",file:%s", kameletMountPoint)
 		}
-		e.ApplicationProperties[KameletLocationProperty] += ",classpath:/kamelets"
-		// resort dependencies
-		sort.Strings(e.Integration.Status.Dependencies)
 	}
+	e.ApplicationProperties[KameletLocationProperty] += ",classpath:/kamelets"
+	// resort dependencies
+	sort.Strings(e.Integration.Status.Dependencies)
+
 	return nil
 }
 
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index a50950f0e..db87ad504 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -89,66 +89,68 @@ func (t *knativeTrait) Configure(e *Environment) (bool, *TraitCondition, error)
 	if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() {
 		return false, nil, nil
 	}
-	if pointer.BoolDeref(t.Auto, true) {
-		sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, e.Client, e.Integration, e.Resources)
+	if !pointer.BoolDeref(t.Auto, true) {
+		return true, nil, nil
+	}
+
+	sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, e.Client, e.Integration, e.Resources)
+	if err != nil {
+		return false, nil, err
+	}
+	if len(t.ChannelSources) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeChannel, "from")
 		if err != nil {
 			return false, nil, err
 		}
-		if len(t.ChannelSources) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeChannel, "from")
-			if err != nil {
-				return false, nil, err
-			}
-			t.ChannelSources = items
-		}
-		if len(t.ChannelSinks) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeChannel, "to")
-			if err != nil {
-				return false, nil, err
-			}
-			t.ChannelSinks = items
-		}
-		if len(t.EndpointSources) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEndpoint, "from")
-			if err != nil {
-				return false, nil, err
-			}
-			t.EndpointSources = items
-		}
-		if len(t.EndpointSinks) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEndpoint, "to")
-			if err != nil {
-				return false, nil, err
-			}
-			t.EndpointSinks = items
-		}
-		if len(t.EventSources) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEvent, "from")
-			if err != nil {
-				return false, nil, err
-			}
-			t.EventSources = items
+		t.ChannelSources = items
+	}
+	if len(t.ChannelSinks) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeChannel, "to")
+		if err != nil {
+			return false, nil, err
 		}
-		if len(t.EventSinks) == 0 {
-			items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEvent, "to")
-			if err != nil {
-				return false, nil, err
-			}
-			t.EventSinks = items
+		t.ChannelSinks = items
+	}
+	if len(t.EndpointSources) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEndpoint, "from")
+		if err != nil {
+			return false, nil, err
 		}
-		hasKnativeEndpoint := len(t.ChannelSources) > 0 || len(t.ChannelSinks) > 0 || len(t.EndpointSources) > 0 || len(t.EndpointSinks) > 0 || len(t.EventSources) > 0 || len(t.EventSinks) > 0
-		t.Enabled = &hasKnativeEndpoint
-		if !hasKnativeEndpoint {
-			return false, nil, nil
+		t.EndpointSources = items
+	}
+	if len(t.EndpointSinks) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEndpoint, "to")
+		if err != nil {
+			return false, nil, err
 		}
-		if t.FilterSourceChannels == nil {
-			// Filtering is no longer used by default
-			t.FilterSourceChannels = pointer.Bool(false)
+		t.EndpointSinks = items
+	}
+	if len(t.EventSources) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEvent, "from")
+		if err != nil {
+			return false, nil, err
 		}
-		if t.SinkBinding == nil {
-			allowed := t.isSinkBindingAllowed(e)
-			t.SinkBinding = &allowed
+		t.EventSources = items
+	}
+	if len(t.EventSinks) == 0 {
+		items, err := filterMetaItems(e.CamelCatalog, sources, knativeapi.CamelServiceTypeEvent, "to")
+		if err != nil {
+			return false, nil, err
 		}
+		t.EventSinks = items
+	}
+	hasKnativeEndpoint := len(t.ChannelSources) > 0 || len(t.ChannelSinks) > 0 || len(t.EndpointSources) > 0 || len(t.EndpointSinks) > 0 || len(t.EventSources) > 0 || len(t.EventSinks) > 0
+	t.Enabled = &hasKnativeEndpoint
+	if !hasKnativeEndpoint {
+		return false, nil, nil
+	}
+	if t.FilterSourceChannels == nil {
+		// Filtering is no longer used by default
+		t.FilterSourceChannels = pointer.Bool(false)
+	}
+	if t.SinkBinding == nil {
+		allowed := t.isSinkBindingAllowed(e)
+		t.SinkBinding = &allowed
 	}
 
 	return true, nil, nil
@@ -190,31 +192,33 @@ func (t *knativeTrait) Apply(e *Environment) error {
 		util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityPlatformHTTP)
 	}
 
-	if e.IntegrationInRunningPhases() {
-		env := knativeapi.NewCamelEnvironment()
-		if t.Configuration != "" {
-			if err := env.Deserialize(t.Configuration); err != nil {
-				return err
-			}
-		}
-		if err := t.configureChannels(e, &env); err != nil {
-			return err
-		}
-		if err := t.configureEndpoints(e, &env); err != nil {
-			return err
-		}
-		if err := t.configureEvents(e, &env); err != nil {
-			return err
-		}
-		if err := t.configureSinkBinding(e, &env); err != nil {
+	if !e.IntegrationInRunningPhases() {
+		return nil
+	}
+
+	env := knativeapi.NewCamelEnvironment()
+	if t.Configuration != "" {
+		if err := env.Deserialize(t.Configuration); err != nil {
 			return err
 		}
-		if e.ApplicationProperties == nil {
-			e.ApplicationProperties = make(map[string]string)
-		}
-		for k, v := range env.ToCamelProperties() {
-			e.ApplicationProperties[k] = v
-		}
+	}
+	if err := t.configureChannels(e, &env); err != nil {
+		return err
+	}
+	if err := t.configureEndpoints(e, &env); err != nil {
+		return err
+	}
+	if err := t.configureEvents(e, &env); err != nil {
+		return err
+	}
+	if err := t.configureSinkBinding(e, &env); err != nil {
+		return err
+	}
+	if e.ApplicationProperties == nil {
+		e.ApplicationProperties = make(map[string]string)
+	}
+	for k, v := range env.ToCamelProperties() {
+		e.ApplicationProperties[k] = v
 	}
 
 	return nil
@@ -436,56 +440,60 @@ func (t *knativeTrait) configureSinkBinding(e *Environment, env *knativeapi.Came
 	err := t.withServiceDo(false, e, env, services, serviceType, knativeapi.CamelEndpointKindSink, func(ref *corev1.ObjectReference, serviceURI string, _ func() (*url.URL, error)) error {
 		// Mark the service which will be used as SinkBinding
 		env.SetSinkBinding(ref.Name, knativeapi.CamelEndpointKindSink, serviceType, ref.APIVersion, ref.Kind)
-		if e.IntegrationInPhase(v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) {
-			e.PostStepProcessors = append(e.PostStepProcessors, func(e *Environment) error {
-				sinkBindingInjected := false
-				e.Resources.Visit(func(object runtime.Object) {
-					gvk := object.GetObjectKind().GroupVersionKind()
-					if gvk.Kind == "SinkBinding" && strings.Contains(gvk.Group, "knative") {
-						sinkBindingInjected = true
-					}
-				})
-				if sinkBindingInjected {
-					return nil
-				}
-
-				controller := e.Resources.GetController(func(object ctrl.Object) bool {
-					return true
-				})
-				if controller != nil && !reflect.ValueOf(controller).IsNil() {
-					gvk := controller.GetObjectKind().GroupVersionKind()
-					av, k := gvk.ToAPIVersionAndKind()
-					source := corev1.ObjectReference{
-						Kind:       k,
-						Namespace:  e.Integration.Namespace,
-						Name:       e.Integration.Name,
-						APIVersion: av,
-					}
-					target := corev1.ObjectReference{
-						Kind:       ref.Kind,
-						Namespace:  e.Integration.Namespace,
-						Name:       ref.Name,
-						APIVersion: ref.APIVersion,
-					}
 
-					if pointer.BoolDeref(t.NamespaceLabel, true) {
-						// set the namespace label to allow automatic sinkbinding injection
-						enabled, err := knativeutil.EnableKnativeBindInNamespace(e.Ctx, e.Client, e.Integration.Namespace)
-						if err != nil {
-							t.L.Errorf(err, "Error setting label 'bindings.knative.dev/include=true' in namespace: %s", e.Integration.Namespace)
-						} else if enabled {
-							t.L.Infof("Label 'bindings.knative.dev/include=true' set in namespace: %s", e.Integration.Namespace)
-						}
-					}
+		if !e.IntegrationInPhase(v1.IntegrationPhaseDeploying, v1.IntegrationPhaseRunning) {
+			return nil
+		}
 
-					// Add the SinkBinding in first position, to make sure it is created
-					// before the reference source, so that the SinkBinding webhook has
-					// all the information to perform injection.
-					e.Resources.AddFirst(knativeutil.CreateSinkBinding(source, target))
+		e.PostStepProcessors = append(e.PostStepProcessors, func(e *Environment) error {
+			sinkBindingInjected := false
+			e.Resources.Visit(func(object runtime.Object) {
+				gvk := object.GetObjectKind().GroupVersionKind()
+				if gvk.Kind == "SinkBinding" && strings.Contains(gvk.Group, "knative") {
+					sinkBindingInjected = true
 				}
+			})
+			if sinkBindingInjected {
 				return nil
+			}
+
+			controller := e.Resources.GetController(func(object ctrl.Object) bool {
+				return true
 			})
-		}
+			if controller != nil && !reflect.ValueOf(controller).IsNil() {
+				gvk := controller.GetObjectKind().GroupVersionKind()
+				av, k := gvk.ToAPIVersionAndKind()
+				source := corev1.ObjectReference{
+					Kind:       k,
+					Namespace:  e.Integration.Namespace,
+					Name:       e.Integration.Name,
+					APIVersion: av,
+				}
+				target := corev1.ObjectReference{
+					Kind:       ref.Kind,
+					Namespace:  e.Integration.Namespace,
+					Name:       ref.Name,
+					APIVersion: ref.APIVersion,
+				}
+
+				if pointer.BoolDeref(t.NamespaceLabel, true) {
+					// set the namespace label to allow automatic sinkbinding injection
+					enabled, err := knativeutil.EnableKnativeBindInNamespace(e.Ctx, e.Client, e.Integration.Namespace)
+					if err != nil {
+						t.L.Errorf(err, "Error setting label 'bindings.knative.dev/include=true' in namespace: %s", e.Integration.Namespace)
+					} else if enabled {
+						t.L.Infof("Label 'bindings.knative.dev/include=true' set in namespace: %s", e.Integration.Namespace)
+					}
+				}
+
+				// Add the SinkBinding in first position, to make sure it is created
+				// before the reference source, so that the SinkBinding webhook has
+				// all the information to perform injection.
+				e.Resources.AddFirst(knativeutil.CreateSinkBinding(source, target))
+			}
+			return nil
+		})
+
 		return nil
 	})
 
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 5a9358d01..65c93b8b2 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -315,6 +315,7 @@ func (t *knativeServiceTrait) getServiceFor(e *Environment) (*serving.Service, e
 		isUpdateRequired = true
 	}
 
+	//nolint:nestif
 	if isUpdateRequired {
 		if replicas == nil {
 			if t.MinScale != nil && *t.MinScale > 0 {
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index 60c752dff..f46623bf8 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -18,14 +18,12 @@ limitations under the License.
 package trait
 
 import (
-	"fmt"
-
+	"github.com/apache/camel-k/v2/pkg/install"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/utils/pointer"
 
 	v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
 	traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
-	"github.com/apache/camel-k/v2/pkg/install"
 	"github.com/apache/camel-k/v2/pkg/platform"
 	"github.com/apache/camel-k/v2/pkg/util/boolean"
 	"github.com/apache/camel-k/v2/pkg/util/defaults"
@@ -116,47 +114,64 @@ func (t *platformTrait) Apply(e *Environment) error {
 
 func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1.IntegrationPlatform, error) {
 	pl, err := platform.GetForResource(e.Ctx, t.Client, e.Integration)
-	if err != nil && apierrors.IsNotFound(err) && pointer.BoolDeref(t.CreateDefault, false) {
-		platformName := e.Integration.Status.Platform
-		if platformName == "" {
-			platformName = defaults.OperatorID()
-		}
-
-		if platformName == "" {
-			platformName = platform.DefaultPlatformName
-		}
-		namespace := e.Integration.Namespace
-		if pointer.BoolDeref(t.Global, false) {
-			operatorNamespace := platform.GetOperatorNamespace()
-			if operatorNamespace != "" {
-				namespace = operatorNamespace
-			}
-		}
-		defaultPlatform := v1.NewIntegrationPlatform(namespace, platformName)
-		if defaultPlatform.Labels == nil {
-			defaultPlatform.Labels = make(map[string]string)
-		}
-		defaultPlatform.Labels["app"] = "camel-k"
-		defaultPlatform.Labels["camel.apache.org/platform.generated"] = boolean.TrueString
-		// Cascade the operator id in charge to reconcile the Integration
-		if v1.GetOperatorIDAnnotation(e.Integration) != "" {
-			defaultPlatform.SetOperatorID(v1.GetOperatorIDAnnotation(e.Integration))
-		}
-		pl = &defaultPlatform
+	if err != nil && !apierrors.IsNotFound(err) {
+		return nil, err
+	}
+	if apierrors.IsNotFound(err) && pointer.BoolDeref(t.CreateDefault, false) {
+		pl = t.createDefaultPlatform(e)
 		e.Resources.Add(pl)
 
-		// Make sure that IntegrationPlatform installed in operator namespace can be seen by others
-		if err := install.IntegrationPlatformViewerRole(e.Ctx, t.Client, namespace); err != nil && !apierrors.IsAlreadyExists(err) {
-			t.L.Info(fmt.Sprintf("Cannot install global IntegrationPlatform viewer role in namespace '%s': skipping.", namespace))
-		}
+		t.installViewerRole(e, pl)
+	}
 
-		return pl, nil
+	if err != nil {
+		return nil, err
 	}
 
-	return pl, err
+	return pl, nil
 }
 
 // RequiresIntegrationPlatform overrides base class method.
 func (t *platformTrait) RequiresIntegrationPlatform() bool {
 	return false
 }
+
+func (t *platformTrait) createDefaultPlatform(e *Environment) *v1.IntegrationPlatform {
+	platformName := e.Integration.Status.Platform
+	if platformName == "" {
+		platformName = defaults.OperatorID()
+	}
+
+	if platformName == "" {
+		platformName = platform.DefaultPlatformName
+	}
+	namespace := e.Integration.Namespace
+	if pointer.BoolDeref(t.Global, false) {
+		operatorNamespace := platform.GetOperatorNamespace()
+		if operatorNamespace != "" {
+			namespace = operatorNamespace
+		}
+	}
+
+	defaultPlatform := v1.NewIntegrationPlatform(namespace, platformName)
+	if defaultPlatform.Labels == nil {
+		defaultPlatform.Labels = make(map[string]string)
+	}
+	defaultPlatform.Labels["app"] = "camel-k"
+	defaultPlatform.Labels["camel.apache.org/platform.generated"] = boolean.TrueString
+
+	// Cascade the operator id in charge to reconcile the Integration
+	if v1.GetOperatorIDAnnotation(e.Integration) != "" {
+		defaultPlatform.SetOperatorID(v1.GetOperatorIDAnnotation(e.Integration))
+	}
+
+	return &defaultPlatform
+}
+
+func (t *platformTrait) installViewerRole(e *Environment, itp *v1.IntegrationPlatform) {
+	// Make sure that IntegrationPlatform installed in operator namespace can be seen by others
+	err := install.IntegrationPlatformViewerRole(e.Ctx, t.Client, itp.Namespace)
+	if err != nil && !apierrors.IsAlreadyExists(err) {
+		t.L.Infof("Cannot install global IntegrationPlatform viewer role in namespace '%s': skipping.", itp.Namespace)
+	}
+}
diff --git a/pkg/trait/pull_secret.go b/pkg/trait/pull_secret.go
index e04e81019..a0dc5549f 100644
--- a/pkg/trait/pull_secret.go
+++ b/pkg/trait/pull_secret.go
@@ -61,36 +61,40 @@ func (t *pullSecretTrait) Configure(e *Environment) (bool, *TraitCondition, erro
 	}
 
 	if pointer.BoolDeref(t.Auto, true) {
-		if t.SecretName == "" {
-			secret := e.Platform.Status.Build.Registry.Secret
-			if secret != "" {
-				key := ctrl.ObjectKey{Namespace: e.Platform.Namespace, Name: secret}
-				obj := corev1.Secret{}
-				if err := t.Client.Get(e.Ctx, key, &obj); err != nil {
-					return false, nil, err
-				}
-				if obj.Type == corev1.SecretTypeDockerConfigJson {
-					t.SecretName = secret
-				}
-			}
+		err := t.autoConfigure(e)
+		if err != nil {
+			return false, nil, err
+		}
+	}
+
+	return t.SecretName != "" || pointer.BoolDeref(t.ImagePullerDelegation, false), nil, nil
+}
+func (t *pullSecretTrait) autoConfigure(e *Environment) error {
+	if t.SecretName == "" {
+		s, err := t.resolveSecret(e)
+		if err != nil {
+			return err
 		}
-		if t.ImagePullerDelegation == nil {
-			var isOpenShift bool
-			if t.Client != nil {
-				var err error
-				isOpenShift, err = openshift.IsOpenShift(t.Client)
-				if err != nil {
-					return false, nil, err
-				}
+
+		t.SecretName = s
+	}
+
+	if t.ImagePullerDelegation == nil {
+		var isOpenShift bool
+		if t.Client != nil {
+			var err error
+			isOpenShift, err = openshift.IsOpenShift(t.Client)
+			if err != nil {
+				return err
 			}
-			isOperatorGlobal := platform.IsCurrentOperatorGlobal()
-			isKitExternal := e.Integration.GetIntegrationKitNamespace(e.Platform) != e.Integration.Namespace
-			needsDelegation := isOpenShift && isOperatorGlobal && isKitExternal
-			t.ImagePullerDelegation = &needsDelegation
 		}
+		isOperatorGlobal := platform.IsCurrentOperatorGlobal()
+		isKitExternal := e.Integration.GetIntegrationKitNamespace(e.Platform) != e.Integration.Namespace
+		needsDelegation := isOpenShift && isOperatorGlobal && isKitExternal
+		t.ImagePullerDelegation = &needsDelegation
 	}
 
-	return t.SecretName != "" || pointer.BoolDeref(t.ImagePullerDelegation, false), nil, nil
+	return nil
 }
 
 func (t *pullSecretTrait) Apply(e *Environment) error {
@@ -164,3 +168,22 @@ func (t *pullSecretTrait) newImagePullerRoleBinding(e *Environment) *rbacv1.Role
 		},
 	}
 }
+
+func (t *pullSecretTrait) resolveSecret(e *Environment) (string, error) {
+	secret := e.Platform.Status.Build.Registry.Secret
+	if secret == "" {
+		return "", nil
+	}
+
+	key := ctrl.ObjectKey{Namespace: e.Platform.Namespace, Name: secret}
+	obj := corev1.Secret{}
+	if err := t.Client.Get(e.Ctx, key, &obj); err != nil {
+		return "", err
+	}
+
+	if obj.Type != corev1.SecretTypeDockerConfigJson {
+		return "", nil
+	}
+
+	return secret, nil
+}
diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go
index ec1823901..08dd0aafa 100644
--- a/pkg/trait/quarkus.go
+++ b/pkg/trait/quarkus.go
@@ -376,6 +376,7 @@ func (t *quarkusTrait) applyWhenBuildSubmitted(e *Environment) error {
 	// The LoadCamelQuarkusCatalog is required to have catalog information available by the builder
 	packageSteps = append(packageSteps, builder.Quarkus.LoadCamelQuarkusCatalog)
 
+	//nolint:nestif
 	if native {
 		if nativePackageType := builder.QuarkusRuntimeSupport(e.CamelCatalog.GetCamelQuarkusVersion()).NativeMavenProperty(); nativePackageType != "" {
 			buildTask.Maven.Properties["quarkus.package.type"] = nativePackageType
diff --git a/pkg/trait/registry.go b/pkg/trait/registry.go
index cfb59dfdb..3ef00ea1d 100644
--- a/pkg/trait/registry.go
+++ b/pkg/trait/registry.go
@@ -87,24 +87,12 @@ func (t *registryTrait) Apply(e *Environment) error {
 		return errors.New("could not figure out Image Registry URL, please set it manually")
 	}
 	build := getBuilderTask(e.Pipeline)
-	registryCa := e.Platform.Status.Build.Registry.CA
-	registrySecret := e.Platform.Status.Build.Registry.Secret
-	if e.Platform.Status.Cluster == v1.IntegrationPlatformClusterOpenShift {
-		if registryCa == "" {
-			ca, err := getOpenShiftImageRegistryCA(e)
-			if err != nil {
-				return err
-			}
-			registryCa = ca
-		}
-		if registrySecret == "" {
-			secret, err := getOpenShiftRegistrySecret(e)
-			if err != nil {
-				return err
-			}
-			registrySecret = secret
-		}
+
+	registryCa, registrySecret, err := t.getRegistryCaAndSecret(e)
+	if err != nil {
+		return err
 	}
+
 	if registryCa != "" {
 		err := addImageRegistryCaToMavenBuild(registryCa, build)
 		if err != nil {
@@ -122,6 +110,32 @@ func (t *registryTrait) Apply(e *Environment) error {
 	return nil
 }
 
+func (t *registryTrait) getRegistryCaAndSecret(e *Environment) (string, string, error) {
+	registryCa := e.Platform.Status.Build.Registry.CA
+	registrySecret := e.Platform.Status.Build.Registry.Secret
+
+	if e.Platform.Status.Cluster != v1.IntegrationPlatformClusterOpenShift {
+		return registryCa, registrySecret, nil
+	}
+
+	if registryCa == "" {
+		ca, err := getOpenShiftImageRegistryCA(e)
+		if err != nil {
+			return "", "", err
+		}
+		registryCa = ca
+	}
+	if registrySecret == "" {
+		secret, err := getOpenShiftRegistrySecret(e)
+		if err != nil {
+			return "", "", err
+		}
+		registrySecret = secret
+	}
+
+	return registryCa, registrySecret, nil
+}
+
 func addRegistryAndExtensionToMaven(registryAddress string, build *v1.BuilderTask, platform *v1.IntegrationPlatform) {
 	organization := platform.Status.Build.Registry.Organization
 	if organization == "" {
diff --git a/pkg/trait/security_context.go b/pkg/trait/security_context.go
index 6e60fb070..d1dfa1b26 100644
--- a/pkg/trait/security_context.go
+++ b/pkg/trait/security_context.go
@@ -88,24 +88,38 @@ func (t *securityContextTrait) setSecurityContext(e *Environment, podSpec *corev
 			Type: t.SeccompProfileType,
 		},
 	}
-	if t.RunAsUser == nil {
-		// get security context UID from Openshift when non configured by the user
-		isOpenShift, err := openshift.IsOpenShift(e.Client)
-		if err != nil {
-			return err
-		}
-		if isOpenShift {
-			runAsUser, err := openshift.GetOpenshiftUser(e.Ctx, e.Client, e.Integration.Namespace)
-			if err != nil {
-				return err
-			}
-			if runAsUser != nil {
-				t.RunAsUser = runAsUser
-			}
-		}
+
+	runAsUser, err := t.getUser(e)
+	if err != nil {
+		return err
 	}
+
+	t.RunAsUser = runAsUser
+
 	sc.RunAsUser = t.RunAsUser
 	podSpec.SecurityContext = &sc
 
 	return nil
 }
+
+func (t *securityContextTrait) getUser(e *Environment) (*int64, error) {
+	if t.RunAsUser != nil {
+		return t.RunAsUser, nil
+	}
+
+	// get security context UID from Openshift when non.configured by the user
+	isOpenShift, err := openshift.IsOpenShift(e.Client)
+	if err != nil {
+		return nil, err
+	}
+	if !isOpenShift {
+		return nil, nil
+	}
+
+	runAsUser, err := openshift.GetOpenshiftUser(e.Ctx, e.Client, e.Integration.Namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	return runAsUser, nil
+}
diff --git a/pkg/trait/trait_configure.go b/pkg/trait/trait_configure.go
index c1c19706d..8efb45a1c 100644
--- a/pkg/trait/trait_configure.go
+++ b/pkg/trait/trait_configure.go
@@ -120,35 +120,36 @@ func decodeTrait(in map[string]interface{}, target Trait) error {
 func (c *Catalog) configureTraitsFromAnnotations(annotations map[string]string) error {
 	options := make(map[string]map[string]interface{}, len(annotations))
 	for k, v := range annotations {
-		if strings.HasPrefix(k, v1.TraitAnnotationPrefix) {
-			configKey := strings.TrimPrefix(k, v1.TraitAnnotationPrefix)
-			if strings.Contains(configKey, ".") {
-				parts := strings.SplitN(configKey, ".", 2)
-				id := parts[0]
-				prop := parts[1]
-				if _, ok := options[id]; !ok {
-					options[id] = make(map[string]interface{})
-				}
+		if !strings.HasPrefix(k, v1.TraitAnnotationPrefix) {
+			continue
+		}
 
-				propParts := util.ConfigTreePropertySplit(prop)
-				var current = options[id]
-				if len(propParts) > 1 {
-					c, err := util.NavigateConfigTree(current, propParts[0:len(propParts)-1])
-					if err != nil {
-						return err
-					}
-					if cc, ok := c.(map[string]interface{}); ok {
-						current = cc
-					} else {
-						return errors.New(`invalid array specification: to set an array value use the ["v1", "v2"] format`)
-					}
-				}
-				current[prop] = v
+		configKey := strings.TrimPrefix(k, v1.TraitAnnotationPrefix)
+		if !strings.Contains(configKey, ".") {
+			return fmt.Errorf("wrong format for trait annotation %q: missing trait ID", k)
+		}
 
+		parts := strings.SplitN(configKey, ".", 2)
+		id := parts[0]
+		prop := parts[1]
+		if _, ok := options[id]; !ok {
+			options[id] = make(map[string]interface{})
+		}
+
+		propParts := util.ConfigTreePropertySplit(prop)
+		var current = options[id]
+		if len(propParts) > 1 {
+			c, err := util.NavigateConfigTree(current, propParts[0:len(propParts)-1])
+			if err != nil {
+				return err
+			}
+			if cc, ok := c.(map[string]interface{}); ok {
+				current = cc
 			} else {
-				return fmt.Errorf("wrong format for trait annotation %q: missing trait ID", k)
+				return errors.New(`invalid array specification: to set an array value use the ["v1", "v2"] format`)
 			}
 		}
+		current[prop] = v
 	}
 	return c.configureFromOptions(options)
 }
diff --git a/pkg/util/bindings/kamelet.go b/pkg/util/bindings/kamelet.go
index 0bfee4f95..300207bad 100644
--- a/pkg/util/bindings/kamelet.go
+++ b/pkg/util/bindings/kamelet.go
@@ -52,93 +52,95 @@ func (k BindingConverter) Translate(ctx BindingContext, endpointCtx EndpointCont
 	if err != nil {
 		return nil, err
 	}
+
 	// it translates only Kamelet refs
-	if e.Ref.Kind == v1.KameletKind && gv.Group == v1.SchemeGroupVersion.Group {
-		kameletName := url.PathEscape(e.Ref.Name)
+	if e.Ref.Kind != v1.KameletKind || gv.Group != v1.SchemeGroupVersion.Group {
+		return nil, nil
+	}
 
-		props, err := e.Properties.GetPropertyMap()
-		if err != nil {
-			return nil, err
-		}
+	kameletName := url.PathEscape(e.Ref.Name)
 
-		id, idPresent := props[v1.KameletIDProperty]
-		if idPresent {
-			delete(props, v1.KameletIDProperty)
-		} else {
-			id = endpointCtx.GenerateID()
-		}
+	props, err := e.Properties.GetPropertyMap()
+	if err != nil {
+		return nil, err
+	}
 
-		binding := Binding{}
-		binding.ApplicationProperties = make(map[string]string)
-		for k, v := range props {
-			propKey := fmt.Sprintf("camel.kamelet.%s.%s.%s", kameletName, id, k)
-			binding.ApplicationProperties[propKey] = v
-		}
+	id, idPresent := props[v1.KameletIDProperty]
+	if idPresent {
+		delete(props, v1.KameletIDProperty)
+	} else {
+		id = endpointCtx.GenerateID()
+	}
 
-		dataTypeActionKamelet := ctx.Metadata[v1.KameletDataTypeLabel]
-		if dataTypeActionKamelet == "" {
-			dataTypeActionKamelet = defaultDataTypeActionKamelet
-		}
+	binding := Binding{}
+	binding.ApplicationProperties = make(map[string]string)
+	for k, v := range props {
+		propKey := fmt.Sprintf("camel.kamelet.%s.%s.%s", kameletName, id, k)
+		binding.ApplicationProperties[propKey] = v
+	}
 
-		switch endpointCtx.Type {
-		case v1.EndpointTypeAction:
-			steps := make([]map[string]interface{}, 0)
+	dataTypeActionKamelet := ctx.Metadata[v1.KameletDataTypeLabel]
+	if dataTypeActionKamelet == "" {
+		dataTypeActionKamelet = defaultDataTypeActionKamelet
+	}
 
-			if in, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotIn, dataTypeActionKamelet); in != nil {
-				steps = append(steps, in)
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+	switch endpointCtx.Type {
+	case v1.EndpointTypeAction:
+		steps := make([]map[string]interface{}, 0)
+
+		if in, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotIn, dataTypeActionKamelet); in != nil {
+			steps = append(steps, in)
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			steps = append(steps, map[string]interface{}{
-				"kamelet": map[string]interface{}{
-					"name": fmt.Sprintf("%s/%s", kameletName, url.PathEscape(id)),
-				},
-			})
+		steps = append(steps, map[string]interface{}{
+			"kamelet": map[string]interface{}{
+				"name": fmt.Sprintf("%s/%s", kameletName, url.PathEscape(id)),
+			},
+		})
 
-			if out, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotOut, dataTypeActionKamelet); out != nil {
-				steps = append(steps, out)
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		if out, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotOut, dataTypeActionKamelet); out != nil {
+			steps = append(steps, out)
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			if len(steps) > 1 {
-				binding.Step = map[string]interface{}{
-					"pipeline": map[string]interface{}{
-						"id":    fmt.Sprintf("%s-pipeline", id),
-						"steps": steps,
-					},
-				}
-			} else if len(steps) == 1 {
-				binding.Step = steps[0]
+		if len(steps) > 1 {
+			binding.Step = map[string]interface{}{
+				"pipeline": map[string]interface{}{
+					"id":    fmt.Sprintf("%s-pipeline", id),
+					"steps": steps,
+				},
 			}
-		case v1.EndpointTypeSource:
-			if out, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotOut, dataTypeActionKamelet); out != nil {
-				binding.Step = out
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		} else if len(steps) == 1 {
+			binding.Step = steps[0]
+		}
+	case v1.EndpointTypeSource:
+		if out, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotOut, dataTypeActionKamelet); out != nil {
+			binding.Step = out
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
-		case v1.EndpointTypeSink:
-			if in, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotIn, dataTypeActionKamelet); in != nil {
-				binding.Step = in
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
+	case v1.EndpointTypeSink:
+		if in, applicationProperties := k.DataTypeStep(e, id, v1.TypeSlotIn, dataTypeActionKamelet); in != nil {
+			binding.Step = in
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
-
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
-		default:
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
 		}
 
-		return &binding, nil
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
+	default:
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
 	}
-	return nil, nil
+
+	return &binding, nil
 }
 
 // DataTypeStep --.
@@ -203,92 +205,93 @@ func (k V1alpha1BindingConverter) Translate(ctx V1alpha1BindingContext, endpoint
 		return nil, err
 	}
 	// it translates only Kamelet refs
-	if e.Ref.Kind == v1.KameletKind && gv.Group == v1.SchemeGroupVersion.Group {
-		kameletName := url.PathEscape(e.Ref.Name)
+	if e.Ref.Kind != v1.KameletKind || gv.Group != v1.SchemeGroupVersion.Group {
+		return nil, nil
+	}
 
-		props, err := e.Properties.GetPropertyMap()
-		if err != nil {
-			return nil, err
-		}
+	kameletName := url.PathEscape(e.Ref.Name)
 
-		id, idPresent := props[v1.KameletIDProperty]
-		if idPresent {
-			delete(props, v1.KameletIDProperty)
-		} else {
-			id = endpointCtx.GenerateID()
-		}
+	props, err := e.Properties.GetPropertyMap()
+	if err != nil {
+		return nil, err
+	}
 
-		binding := Binding{}
-		binding.ApplicationProperties = make(map[string]string)
-		for k, v := range props {
-			propKey := fmt.Sprintf("camel.kamelet.%s.%s.%s", kameletName, id, k)
-			binding.ApplicationProperties[propKey] = v
-		}
+	id, idPresent := props[v1.KameletIDProperty]
+	if idPresent {
+		delete(props, v1.KameletIDProperty)
+	} else {
+		id = endpointCtx.GenerateID()
+	}
 
-		dataTypeActionKamelet := ctx.Metadata[v1.KameletDataTypeLabel]
-		if dataTypeActionKamelet == "" {
-			dataTypeActionKamelet = defaultDataTypeActionKamelet
-		}
+	binding := Binding{}
+	binding.ApplicationProperties = make(map[string]string)
+	for k, v := range props {
+		propKey := fmt.Sprintf("camel.kamelet.%s.%s.%s", kameletName, id, k)
+		binding.ApplicationProperties[propKey] = v
+	}
+
+	dataTypeActionKamelet := ctx.Metadata[v1.KameletDataTypeLabel]
+	if dataTypeActionKamelet == "" {
+		dataTypeActionKamelet = defaultDataTypeActionKamelet
+	}
 
-		switch endpointCtx.Type {
-		case v1alpha1.EndpointTypeAction:
-			steps := make([]map[string]interface{}, 0)
+	switch endpointCtx.Type {
+	case v1alpha1.EndpointTypeAction:
+		steps := make([]map[string]interface{}, 0)
 
-			if in, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotIn, dataTypeActionKamelet); in != nil {
-				steps = append(steps, in)
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		if in, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotIn, dataTypeActionKamelet); in != nil {
+			steps = append(steps, in)
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			steps = append(steps, map[string]interface{}{
-				"kamelet": map[string]interface{}{
-					"name": fmt.Sprintf("%s/%s", kameletName, url.PathEscape(id)),
-				},
-			})
+		steps = append(steps, map[string]interface{}{
+			"kamelet": map[string]interface{}{
+				"name": fmt.Sprintf("%s/%s", kameletName, url.PathEscape(id)),
+			},
+		})
 
-			if out, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotOut, dataTypeActionKamelet); out != nil {
-				steps = append(steps, out)
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		if out, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotOut, dataTypeActionKamelet); out != nil {
+			steps = append(steps, out)
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			if len(steps) > 1 {
-				binding.Step = map[string]interface{}{
-					"pipeline": map[string]interface{}{
-						"id":    fmt.Sprintf("%s-pipeline", id),
-						"steps": steps,
-					},
-				}
-			} else if len(steps) == 1 {
-				binding.Step = steps[0]
+		if len(steps) > 1 {
+			binding.Step = map[string]interface{}{
+				"pipeline": map[string]interface{}{
+					"id":    fmt.Sprintf("%s-pipeline", id),
+					"steps": steps,
+				},
 			}
-		case v1alpha1.EndpointTypeSource:
-			if out, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotOut, dataTypeActionKamelet); out != nil {
-				binding.Step = out
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		} else if len(steps) == 1 {
+			binding.Step = steps[0]
+		}
+	case v1alpha1.EndpointTypeSource:
+		if out, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotOut, dataTypeActionKamelet); out != nil {
+			binding.Step = out
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
+		}
 
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
-		case v1alpha1.EndpointTypeSink:
-			if in, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotIn, dataTypeActionKamelet); in != nil {
-				binding.Step = in
-				for k, v := range applicationProperties {
-					binding.ApplicationProperties[k] = v
-				}
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
+	case v1alpha1.EndpointTypeSink:
+		if in, applicationProperties := k.DataTypeStep(e, id, v1alpha1.TypeSlotIn, dataTypeActionKamelet); in != nil {
+			binding.Step = in
+			for k, v := range applicationProperties {
+				binding.ApplicationProperties[k] = v
 			}
-
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
-		default:
-			binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
 		}
 
-		return &binding, nil
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
+	default:
+		binding.URI = fmt.Sprintf("kamelet:%s/%s", kameletName, url.PathEscape(id))
 	}
-	return nil, nil
+
+	return &binding, nil
 }
 
 // DataTypeStep -- .
diff --git a/pkg/util/bindings/knative_ref.go b/pkg/util/bindings/knative_ref.go
index e8208302d..301e62099 100644
--- a/pkg/util/bindings/knative_ref.go
+++ b/pkg/util/bindings/knative_ref.go
@@ -86,6 +86,9 @@ func (k KnativeRefBindingProvider) Translate(ctx BindingContext, endpointCtx End
 	}
 
 	var serviceURI string
+
+	// TODO: refactor
+	//nolint:nestif
 	if *serviceType == knativeapis.CamelServiceTypeEvent {
 		if props["name"] == "" {
 			props["name"] = e.Ref.Name
@@ -190,6 +193,8 @@ func (k V1alpha1KnativeRefBindingProvider) Translate(ctx V1alpha1BindingContext,
 	}
 
 	var serviceURI string
+
+	//nolint:nestif
 	if *serviceType == knativeapis.CamelServiceTypeEvent {
 		if props["name"] == "" {
 			props["name"] = e.Ref.Name
diff --git a/pkg/util/camel/camel_runtime_catalog.go b/pkg/util/camel/camel_runtime_catalog.go
index 37255f971..2681e4918 100644
--- a/pkg/util/camel/camel_runtime_catalog.go
+++ b/pkg/util/camel/camel_runtime_catalog.go
@@ -187,20 +187,19 @@ func (c *RuntimeCatalog) DecodeComponent(uri string) (*v1.CamelArtifact, *v1.Cam
 	var uriSplit []string
 
 	// Decode URI using formats http://my-site/test?param=value or log:info
-	if strings.Contains(uri, ":") {
+	switch {
+	case strings.Contains(uri, ":"):
 		uriSplit = strings.SplitN(uri, ":", 2)
 		if len(uriSplit) < 2 {
 			return nil, nil
 		}
-	} else {
-		if strings.Contains(uri, "?") {
-			uriSplit = strings.SplitN(uri, "?", 2)
-			if len(uriSplit) < 2 {
-				return nil, nil
-			}
-		} else {
-			uriSplit = append(uriSplit, uri)
+	case strings.Contains(uri, "?"):
+		uriSplit = strings.SplitN(uri, "?", 2)
+		if len(uriSplit) < 2 {
+			return nil, nil
 		}
+	default:
+		uriSplit = append(uriSplit, uri)
 	}
 
 	uriStart := uriSplit[0]
diff --git a/pkg/util/digest/digest.go b/pkg/util/digest/digest.go
index 50978725a..946b399f1 100644
--- a/pkg/util/digest/digest.go
+++ b/pkg/util/digest/digest.go
@@ -150,6 +150,7 @@ func ComputeForIntegration(integration *v1.Integration, configmapVersions []stri
 	return digest, nil
 }
 
+//nolint:nestif
 func computeForTraits(hash hash.Hash, traits v1.Traits) error {
 	specTraitsMap, err := toMap(traits)
 	if err != nil {
diff --git a/pkg/util/kubernetes/log/pod_scraper.go b/pkg/util/kubernetes/log/pod_scraper.go
index c52a771db..9cc3aee32 100644
--- a/pkg/util/kubernetes/log/pod_scraper.go
+++ b/pkg/util/kubernetes/log/pod_scraper.go
@@ -146,6 +146,8 @@ func (s *PodScraper) handleAndRestart(ctx context.Context, err error, wait time.
 
 // waitForPodRunning waits for a given pod to reach the running state.
 // It may return the internal container to watch if present.
+//
+//nolint:nestif
 func (s *PodScraper) waitForPodRunning(ctx context.Context, namespace string, podName string, defaultContainerName string) (string, error) {
 	pod := corev1.Pod{
 		TypeMeta: metav1.TypeMeta{
diff --git a/pkg/util/kubernetes/replace.go b/pkg/util/kubernetes/replace.go
index 2f0ee67bb..19b9883d9 100644
--- a/pkg/util/kubernetes/replace.go
+++ b/pkg/util/kubernetes/replace.go
@@ -82,15 +82,21 @@ func mapRequiredRouteData(from runtime.Object, to runtime.Object) {
 }
 
 func mapRequiredKnativeServiceV1Data(from runtime.Object, to runtime.Object) {
-	if fromC, ok := from.(*serving.Service); ok {
-		if toC, ok := to.(*serving.Service); ok {
-			if v, present := fromC.ObjectMeta.Annotations["serving.knative.dev/creator"]; present {
-				v1.SetAnnotation(&toC.ObjectMeta, "serving.knative.dev/creator", v)
-			}
-			if v, present := fromC.ObjectMeta.Annotations["serving.knative.dev/lastModifier"]; present {
-				v1.SetAnnotation(&toC.ObjectMeta, "serving.knative.dev/lastModifier", v)
-			}
-		}
+	fromC, fromOk := from.(*serving.Service)
+	if !fromOk {
+		return
+	}
+
+	toC, toOk := to.(*serving.Service)
+	if !toOk {
+		return
+	}
+
+	if v, present := fromC.ObjectMeta.Annotations["serving.knative.dev/creator"]; present {
+		v1.SetAnnotation(&toC.ObjectMeta, "serving.knative.dev/creator", v)
+	}
+	if v, present := fromC.ObjectMeta.Annotations["serving.knative.dev/lastModifier"]; present {
+		v1.SetAnnotation(&toC.ObjectMeta, "serving.knative.dev/lastModifier", v)
 	}
 }
 
diff --git a/pkg/util/maven/maven_command.go b/pkg/util/maven/maven_command.go
index dd579aa74..a236d6f0b 100644
--- a/pkg/util/maven/maven_command.go
+++ b/pkg/util/maven/maven_command.go
@@ -91,59 +91,67 @@ func (c *Command) Do(ctx context.Context) error {
 		args = append(args, "-Dsettings.security="+settingsSecurityPath)
 	}
 
+	mavenOptions, env := c.optionsFromEnv()
+
 	cmd := exec.CommandContext(ctx, mvnCmd, args...)
 	cmd.Dir = c.context.Path
+	cmd.Env = env
+
+	Log.WithValues("MAVEN_OPTS", mavenOptions).Infof("executing: %s", strings.Join(cmd.Args, " "))
+
+	// generate maven file
+	if err := generateMavenContext(c.context.Path, args, mavenOptions); err != nil {
+		return err
+	}
+
+	return util.RunAndLog(ctx, cmd, LogHandler, LogHandler)
+}
+
+func (c *Command) optionsFromEnv() (string, []string) {
+	if len(c.context.ExtraMavenOpts) == 0 {
+		return "", nil
+	}
 
 	var mavenOptions string
-	if len(c.context.ExtraMavenOpts) > 0 {
-		// Inherit the parent process environment
-		env := os.Environ()
-
-		mavenOpts, ok := os.LookupEnv("MAVEN_OPTS")
-		if !ok {
-			mavenOptions = strings.Join(c.context.ExtraMavenOpts, " ")
-			env = append(env, "MAVEN_OPTS="+mavenOptions)
-		} else {
-			var extraOptions []string
-			options := strings.Fields(mavenOpts)
-			for _, extraOption := range c.context.ExtraMavenOpts {
-				// Basic duplicated key detection, that should be improved
-				// to support a wider range of JVM options
-				key := strings.SplitN(extraOption, "=", 2)[0]
-				exists := false
-				for _, opt := range options {
-					if strings.HasPrefix(opt, key) {
-						exists = true
-
-						break
-					}
-				}
-				if !exists {
-					extraOptions = append(extraOptions, extraOption)
-				}
-			}
 
-			options = append(options, extraOptions...)
-			mavenOptions = strings.Join(options, " ")
-			for i, e := range env {
-				if strings.HasPrefix(e, "MAVEN_OPTS=") {
-					env[i] = "MAVEN_OPTS=" + mavenOptions
+	// Inherit the parent process environment
+	env := os.Environ()
+
+	mavenOpts, ok := os.LookupEnv("MAVEN_OPTS")
+	if !ok {
+		mavenOptions = strings.Join(c.context.ExtraMavenOpts, " ")
+		env = append(env, "MAVEN_OPTS="+mavenOptions)
+	} else {
+		var extraOptions []string
+		options := strings.Fields(mavenOpts)
+		for _, extraOption := range c.context.ExtraMavenOpts {
+			// Basic duplicated key detection, that should be improved
+			// to support a wider range of JVM options
+			key := strings.SplitN(extraOption, "=", 2)[0]
+			exists := false
+			for _, opt := range options {
+				if strings.HasPrefix(opt, key) {
+					exists = true
+
 					break
 				}
 			}
+			if !exists {
+				extraOptions = append(extraOptions, extraOption)
+			}
 		}
 
-		cmd.Env = env
-	}
-
-	Log.WithValues("MAVEN_OPTS", mavenOptions).Infof("executing: %s", strings.Join(cmd.Args, " "))
-
-	// generate maven file
-	if err := generateMavenContext(c.context.Path, args, mavenOptions); err != nil {
-		return err
+		options = append(options, extraOptions...)
+		mavenOptions = strings.Join(options, " ")
+		for i, e := range env {
+			if strings.HasPrefix(e, "MAVEN_OPTS=") {
+				env[i] = "MAVEN_OPTS=" + mavenOptions
+				break
+			}
+		}
 	}
 
-	return util.RunAndLog(ctx, cmd, LogHandler, LogHandler)
+	return mavenOptions, env
 }
 
 func NewContext(buildDir string) Context {
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index f5c862b65..3f484ba50 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -31,7 +31,7 @@ type XMLInspector struct {
 
 // Extract --.
 //
-//nolint:goconst
+//nolint:goconst,nestif
 func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 	content := strings.NewReader(source.Content)
 	decoder := xml.NewDecoder(content)
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index 63ff184e2..1e208c0d2 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -62,6 +62,7 @@ func (i YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 	return nil
 }
 
+//nolint:nestif
 func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata) error {
 	switch key {
 	case "rest":
diff --git a/pkg/util/watch/watch.go b/pkg/util/watch/watch.go
index 32ee72788..fd88b9fee 100644
--- a/pkg/util/watch/watch.go
+++ b/pkg/util/watch/watch.go
@@ -174,6 +174,8 @@ func HandlePlatformStateChanges(ctx context.Context, c client.Client, platform *
 
 // HandleIntegrationPlatformEvents watches all events related to the given integration platform.
 // This function blocks until the handler function returns true or either the events channel or the context is closed.
+//
+//nolint:nestif
 func HandleIntegrationPlatformEvents(ctx context.Context, c client.Client, p *v1.IntegrationPlatform,
 	handler func(event *corev1.Event) bool) error {
 	watcher, err := c.CoreV1().Events(p.Namespace).
@@ -199,6 +201,7 @@ func HandleIntegrationPlatformEvents(ctx context.Context, c client.Client, p *v1
 			if !ok {
 				return nil
 			}
+
 			if e.Object != nil {
 				if evt, ok := e.Object.(*corev1.Event); ok {
 					if isAllowed(lastEvent, evt, p.CreationTimestamp.UnixNano()) {