You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2021/03/03 12:56:33 UTC

[camel-k] 01/08: Fix #1799: implement a global build strategy

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

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

commit 3526c961eff404fc5139ad9911897a31b41df5f1
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Thu Feb 18 17:27:50 2021 +0100

    Fix #1799: implement a global build strategy
---
 .../crd/bases/camel.apache.org_integrations.yaml   |  2 +
 .../camel.apache.org_integrations.yaml             |  2 +
 deploy/traits.yaml                                 |  3 ++
 docs/modules/traits/pages/platform.adoc            |  4 ++
 helm/camel-k/crds/crd-integration.yaml             |  2 +
 pkg/apis/camel/v1/integration_types.go             |  1 +
 pkg/apis/camel/v1/integration_types_support.go     | 13 +++++-
 pkg/builder/spectrum/publisher.go                  |  2 +-
 pkg/cmd/install.go                                 | 12 ++---
 pkg/controller/build/build_controller.go           |  2 +-
 pkg/controller/integration/build_kit.go            | 15 ++++---
 pkg/controller/integration/deploy.go               |  2 +-
 pkg/controller/integration/initialize.go           |  2 +-
 .../integration/integration_controller.go          |  9 +++-
 pkg/controller/integration/platform_setup.go       |  2 +-
 pkg/controller/integration/util.go                 |  6 +--
 .../integrationkit/integrationkit_controller.go    |  3 +-
 pkg/controller/kameletbinding/common.go            |  2 +-
 pkg/platform/operator.go                           |  5 +++
 pkg/platform/platform.go                           | 51 +++++++++++++++-------
 pkg/trait/camel.go                                 |  2 +-
 pkg/trait/openapi.go                               |  2 +-
 pkg/trait/platform.go                              | 31 +++++++++----
 pkg/trait/trait.go                                 |  2 +-
 pkg/trait/util.go                                  |  4 +-
 25 files changed, 124 insertions(+), 57 deletions(-)

diff --git a/config/crd/bases/camel.apache.org_integrations.yaml b/config/crd/bases/camel.apache.org_integrations.yaml
index 147f9fa..c28a5a8 100644
--- a/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/config/crd/bases/camel.apache.org_integrations.yaml
@@ -367,6 +367,8 @@ spec:
                 type: string
               platform:
                 type: string
+              platformNamespace:
+                type: string
               profile:
                 description: TraitProfile represents lists of traits that are enabled
                   for the specific installation/integration
diff --git a/deploy/olm-catalog/camel-k-dev/1.4.0-snapshot/camel.apache.org_integrations.yaml b/deploy/olm-catalog/camel-k-dev/1.4.0-snapshot/camel.apache.org_integrations.yaml
index 147f9fa..c28a5a8 100644
--- a/deploy/olm-catalog/camel-k-dev/1.4.0-snapshot/camel.apache.org_integrations.yaml
+++ b/deploy/olm-catalog/camel-k-dev/1.4.0-snapshot/camel.apache.org_integrations.yaml
@@ -367,6 +367,8 @@ spec:
                 type: string
               platform:
                 type: string
+              platformNamespace:
+                type: string
               profile:
                 description: TraitProfile represents lists of traits that are enabled
                   for the specific installation/integration
diff --git a/deploy/traits.yaml b/deploy/traits.yaml
index ebe104d..afde044 100755
--- a/deploy/traits.yaml
+++ b/deploy/traits.yaml
@@ -493,6 +493,9 @@ traits:
   - name: create-default
     type: bool
     description: To create a default (empty) platform when the platform is missing.
+  - name: global
+    type: bool
+    description: Indicates if the platform should be created globally in the case of global operator (default true).
   - name: auto
     type: bool
     description: To automatically detect from the environment if a default platform can be created (it will be created on OpenShift only).
diff --git a/docs/modules/traits/pages/platform.adoc b/docs/modules/traits/pages/platform.adoc
index 319fb03..20cbf44 100755
--- a/docs/modules/traits/pages/platform.adoc
+++ b/docs/modules/traits/pages/platform.adoc
@@ -35,6 +35,10 @@ The following configuration options are available:
 | bool
 | To create a default (empty) platform when the platform is missing.
 
+| platform.global
+| bool
+| Indicates if the platform should be created globally in the case of global operator (default true).
+
 | platform.auto
 | bool
 | To automatically detect from the environment if a default platform can be created (it will be created on OpenShift only).
diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml
index 147f9fa..c28a5a8 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -367,6 +367,8 @@ spec:
                 type: string
               platform:
                 type: string
+              platformNamespace:
+                type: string
               profile:
                 description: TraitProfile represents lists of traits that are enabled
                   for the specific installation/integration
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index 678d0e6..fc3689c 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -48,6 +48,7 @@ type IntegrationStatus struct {
 	Dependencies       []string               `json:"dependencies,omitempty"`
 	Profile            TraitProfile           `json:"profile,omitempty"`
 	Kit                string                 `json:"kit,omitempty"`
+	PlatformNamespace  string                 `json:"platformNamespace,omitempty"`
 	Platform           string                 `json:"platform,omitempty"`
 	GeneratedSources   []SourceSpec           `json:"generatedSources,omitempty"`
 	GeneratedResources []ResourceSpec         `json:"generatedResources,omitempty"`
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 12479ae..6384720 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -258,7 +258,8 @@ func (in *Integration) SetIntegrationPlatform(platform *IntegrationPlatform) {
 		cs = corev1.ConditionFalse
 	}
 
-	in.Status.SetCondition(IntegrationConditionPlatformAvailable, cs, IntegrationConditionPlatformAvailableReason, platform.Name)
+	in.Status.SetCondition(IntegrationConditionPlatformAvailable, cs, IntegrationConditionPlatformAvailableReason, platform.Namespace+"/"+platform.Name)
+	in.Status.PlatformNamespace = platform.Namespace
 	in.Status.Platform = platform.Name
 }
 
@@ -271,7 +272,7 @@ func (in *Integration) SetIntegrationKit(kit *IntegrationKit) {
 		if kit.Status.Phase == IntegrationKitPhaseNone {
 			message = fmt.Sprintf("creating a new integration kit")
 		} else {
-			message = fmt.Sprintf("integration kit %s is in state %q", kit.Name, kit.Status.Phase)
+			message = fmt.Sprintf("integration kit %s/%s is in state %q", kit.Namespace, kit.Name, kit.Status.Phase)
 		}
 	}
 
@@ -280,6 +281,14 @@ func (in *Integration) SetIntegrationKit(kit *IntegrationKit) {
 	in.Status.Image = kit.Status.Image
 }
 
+// SetIntegrationKit --
+func (in *Integration) GetIntegrationKitNamespace() string {
+	if in.Status.PlatformNamespace != "" {
+		return in.Status.PlatformNamespace
+	}
+	return in.Namespace
+}
+
 // GetCondition returns the condition with the provided type.
 func (in *IntegrationStatus) GetCondition(condType IntegrationConditionType) *IntegrationCondition {
 	for i := range in.Conditions {
diff --git a/pkg/builder/spectrum/publisher.go b/pkg/builder/spectrum/publisher.go
index ab36774..d47f955 100644
--- a/pkg/builder/spectrum/publisher.go
+++ b/pkg/builder/spectrum/publisher.go
@@ -44,7 +44,7 @@ func publisher(ctx *builder.Context) error {
 		return err
 	}
 
-	pl, err := platform.GetCurrentPlatform(ctx.C, ctx, ctx.Namespace)
+	pl, err := platform.GetCurrent(ctx.C, ctx, ctx.Namespace)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index 8f39642..4252c75 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -369,14 +369,10 @@ func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
 			platform.Spec.Build.KanikoBuildCache = &o.KanikoBuildCache
 		}
 
-		// Do not create an integration platform in global mode as platforms are expected
-		// to be created in other namespaces.
-		// In OLM mode, the operator is installed in an external namespace, so it's ok to install the platform locally.
-		if !o.Global || installViaOLM {
-			err = install.RuntimeObjectOrCollect(o.Context, c, namespace, collection, o.Force, platform)
-			if err != nil {
-				return err
-			}
+		// Always create a platform in the namespace where the operator is located
+		err = install.RuntimeObjectOrCollect(o.Context, c, namespace, collection, o.Force, platform)
+		if err != nil {
+			return err
 		}
 
 		if o.ExampleSetup {
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 2e09188..b77e23c 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -172,7 +172,7 @@ func (r *reconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 	target := instance.DeepCopy()
 	targetLog := rlog.ForBuild(target)
 
-	pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
+	pl, err := platform.GetOrFind(ctx, r.client, target.Namespace, target.Status.Platform, true)
 	if target.Status.Phase == v1.BuildPhaseNone || target.Status.Phase == v1.BuildPhaseWaitingForPlatform {
 		if err != nil || pl.Status.Phase != v1.IntegrationPlatformPhaseReady {
 			target.Status.Phase = v1.BuildPhaseWaitingForPlatform
diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go
index a3e4fe6..1cc7827 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -102,17 +102,18 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integr
 	}
 
 	platformKitName := fmt.Sprintf("kit-%s", xid.New())
-	platformKit := v1.NewIntegrationKit(integration.Namespace, platformKitName)
+	platformKit := v1.NewIntegrationKit(integration.GetIntegrationKitNamespace(), platformKitName)
 
 	// Add some information for post-processing, this may need to be refactored
 	// to a proper data structure
 	platformKit.Labels = map[string]string{
-		"camel.apache.org/kit.type":           v1.IntegrationKitTypePlatform,
-		"camel.apache.org/created.by.kind":    v1.IntegrationKind,
-		"camel.apache.org/created.by.name":    integration.Name,
-		"camel.apache.org/created.by.version": integration.ResourceVersion,
-		"camel.apache.org/runtime.version":    integration.Status.RuntimeVersion,
-		"camel.apache.org/runtime.provider":   string(integration.Status.RuntimeProvider),
+		"camel.apache.org/kit.type":             v1.IntegrationKitTypePlatform,
+		"camel.apache.org/created.by.kind":      v1.IntegrationKind,
+		"camel.apache.org/created.by.name":      integration.Name,
+		"camel.apache.org/created.by.namespace": integration.Namespace,
+		"camel.apache.org/created.by.version":   integration.ResourceVersion,
+		"camel.apache.org/runtime.version":      integration.Status.RuntimeVersion,
+		"camel.apache.org/runtime.provider":     string(integration.Status.RuntimeProvider),
 	}
 
 	// Set the kit to have the same characteristics as the integrations
diff --git a/pkg/controller/integration/deploy.go b/pkg/controller/integration/deploy.go
index b398126..efa82ad 100644
--- a/pkg/controller/integration/deploy.go
+++ b/pkg/controller/integration/deploy.go
@@ -48,7 +48,7 @@ func (action *deployAction) Handle(ctx context.Context, integration *v1.Integrat
 		return nil, errors.Errorf("no kit set on integration %s", integration.Name)
 	}
 
-	kit, err := kubernetes.GetIntegrationKit(ctx, action.client, integration.Status.Kit, integration.Namespace)
+	kit, err := kubernetes.GetIntegrationKit(ctx, action.client, integration.Status.Kit, integration.GetIntegrationKitNamespace())
 	if err != nil {
 		return nil, errors.Wrapf(err, "unable to find integration kit %s, %s", integration.Status.Kit, err)
 	}
diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go
index 4698b71..d33d816 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -52,7 +52,7 @@ func (action *initializeAction) Handle(ctx context.Context, integration *v1.Inte
 		return nil, err
 	}
 
-	kit := v1.NewIntegrationKit(integration.Namespace, integration.Spec.Kit)
+	kit := v1.NewIntegrationKit(integration.GetIntegrationKitNamespace(), integration.Spec.Kit)
 
 	integration.Status.Phase = v1.IntegrationPhaseBuildingKit
 	integration.SetIntegrationKit(&kit)
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 516c029..2e1362b 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -114,7 +114,13 @@ func add(mgr manager.Manager, r reconcile.Reconciler, c client.Client) error {
 			if kit.Status.Phase == v1.IntegrationKitPhaseReady || kit.Status.Phase == v1.IntegrationKitPhaseError {
 				list := &v1.IntegrationList{}
 
-				if err := mgr.GetClient().List(context.TODO(), list, k8sclient.InNamespace(kit.Namespace)); err != nil {
+				// Do global search in case of global operator (it may be using a global platform)
+				var opts []k8sclient.ListOption
+				if !platform.IsCurrentOperatorGlobal() {
+					opts = append(opts, k8sclient.InNamespace(kit.Namespace))
+				}
+
+				if err := mgr.GetClient().List(context.TODO(), list, opts...); err != nil {
 					log.Error(err, "Failed to retrieve integration list")
 					return requests
 				}
@@ -130,6 +136,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler, c client.Client) error {
 						})
 					}
 				}
+
 			}
 
 			return requests
diff --git a/pkg/controller/integration/platform_setup.go b/pkg/controller/integration/platform_setup.go
index 51c5a5b..97cd3bb 100644
--- a/pkg/controller/integration/platform_setup.go
+++ b/pkg/controller/integration/platform_setup.go
@@ -55,7 +55,7 @@ func (action *platformSetupAction) Handle(ctx context.Context, integration *v1.I
 		return nil, err
 	}
 
-	pl, err := platform.GetCurrentPlatform(ctx, action.client, integration.Namespace)
+	pl, err := platform.GetCurrent(ctx, action.client, integration.Namespace)
 	if err != nil && !k8serrors.IsNotFound(err) {
 		return nil, err
 	} else if pl != nil {
diff --git a/pkg/controller/integration/util.go b/pkg/controller/integration/util.go
index 16cc94e..f0fc97b 100644
--- a/pkg/controller/integration/util.go
+++ b/pkg/controller/integration/util.go
@@ -35,16 +35,16 @@ import (
 // LookupKitForIntegration --
 func LookupKitForIntegration(ctx context.Context, c k8sclient.Reader, integration *v1.Integration) (*v1.IntegrationKit, error) {
 	if integration.Status.Kit != "" {
-		kit, err := kubernetes.GetIntegrationKit(ctx, c, integration.Status.Kit, integration.Namespace)
+		kit, err := kubernetes.GetIntegrationKit(ctx, c, integration.Status.Kit, integration.GetIntegrationKitNamespace())
 		if err != nil {
-			return nil, errors.Wrapf(err, "unable to find integration kit %s, %s", integration.Status.Kit, err)
+			return nil, errors.Wrapf(err, "unable to find integration kit %s/%s, %s", integration.GetIntegrationKitNamespace(), integration.Status.Kit, err)
 		}
 
 		return kit, nil
 	}
 
 	options := []k8sclient.ListOption{
-		k8sclient.InNamespace(integration.Namespace),
+		k8sclient.InNamespace(integration.GetIntegrationKitNamespace()),
 		k8sclient.MatchingLabels{
 			"camel.apache.org/runtime.version":  integration.Status.RuntimeVersion,
 			"camel.apache.org/runtime.provider": string(integration.Status.RuntimeProvider),
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index a525725..cc4993d 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -204,7 +204,8 @@ func (r *reconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 	targetLog := rlog.ForIntegrationKit(target)
 
 	if target.Status.Phase == v1.IntegrationKitPhaseNone || target.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform {
-		pl, err := platform.GetOrLookupCurrent(ctx, r.client, target.Namespace, target.Status.Platform)
+		// TODO.... here local...
+		pl, err := platform.GetOrFindLocal(ctx, r.client, target.Namespace, target.Status.Platform, true)
 		if err != nil || pl.Status.Phase != v1.IntegrationPlatformPhaseReady {
 			target.Status.Phase = v1.IntegrationKitPhaseWaitingForPlatform
 		} else {
diff --git a/pkg/controller/kameletbinding/common.go b/pkg/controller/kameletbinding/common.go
index e51bf1a..411bde8 100644
--- a/pkg/controller/kameletbinding/common.go
+++ b/pkg/controller/kameletbinding/common.go
@@ -148,7 +148,7 @@ func determineProfile(ctx context.Context, c client.Client, binding *v1alpha1.Ka
 	if binding.Spec.Integration != nil && binding.Spec.Integration.Profile != "" {
 		return binding.Spec.Integration.Profile, nil
 	}
-	pl, err := platform.GetCurrentPlatform(ctx, c, binding.Namespace)
+	pl, err := platform.GetCurrent(ctx, c, binding.Namespace)
 	if err != nil && !k8serrors.IsNotFound(err) {
 		return "", errors.Wrap(err, "error while retrieving the integration platform")
 	}
diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go
index 05538a9..c4310df 100644
--- a/pkg/platform/operator.go
+++ b/pkg/platform/operator.go
@@ -115,6 +115,11 @@ func IsOperatorAllowedOnNamespace(ctx context.Context, c client.Client, namespac
 	if !IsCurrentOperatorGlobal() {
 		return true, nil
 	}
+	operatorNamespace := GetOperatorNamespace()
+	if operatorNamespace == namespace {
+		// Global operator is allowed on its own namespace
+		return true, nil
+	}
 	alreadyOwned, err := IsNamespaceLocked(ctx, c, namespace)
 	if err != nil {
 		return false, err
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index a025088..d566b5e 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -31,36 +31,55 @@ const (
 	DefaultPlatformName = "camel-k"
 )
 
-// GetOrLookupCurrent --
-func GetOrLookupCurrent(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) {
+// GetCurrent returns the currently installed platform (local or global)
+func GetCurrent(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) {
+	return find(ctx, c, namespace, true)
+}
+
+// GetOrFind returns the named platform or any other platform in the local namespace or the global one
+func GetOrFind(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
 	if name != "" {
-		return Get(ctx, c, namespace, name)
+		return get(ctx, c, namespace, name)
 	}
 
-	return GetCurrentPlatform(ctx, c, namespace)
+	return find(ctx, c, namespace, active)
 }
 
-// GetOrLookupAny returns the named platform or any other platform in the namespace
-func GetOrLookupAny(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) {
+// GetOrFindLocal returns the named platform or any other platform in the local namespace
+func GetOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) {
 	if name != "" {
-		return Get(ctx, c, namespace, name)
+		return kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
 	}
 
-	return getAnyPlatform(ctx, c, namespace, false)
+	return findLocal(ctx, c, namespace, active)
 }
 
-// Get returns the currently installed platform
-func Get(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) {
-	return kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
+// get returns the given platform in the given namespace or the global one
+func get(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) {
+	p, err := kubernetes.GetIntegrationPlatform(ctx, c, name, namespace)
+	if err != nil && k8serrors.IsNotFound(err) {
+		operatorNamespace := GetOperatorNamespace()
+		if operatorNamespace != "" && operatorNamespace != namespace {
+			p, err = kubernetes.GetIntegrationPlatform(ctx, c, name, operatorNamespace)
+		}
+	}
+	return p, err
 }
 
-// GetCurrentPlatform returns the currently installed platform
-func GetCurrentPlatform(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) {
-	return getAnyPlatform(ctx, c, namespace, true)
+// find returns the currently installed platform or any platform existing in local or operator namespace
+func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
+	p, err := findLocal(ctx, c, namespace, active)
+	if err != nil && k8serrors.IsNotFound(err) {
+		operatorNamespace := GetOperatorNamespace()
+		if operatorNamespace != "" && operatorNamespace != namespace {
+			p, err = findLocal(ctx, c, operatorNamespace, active)
+		}
+	}
+	return p, err
 }
 
-// getAnyPlatform returns the currently installed platform or any platform existing in the namespace
-func getAnyPlatform(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
+// findLocal returns the currently installed platform or any platform existing in local namespace
+func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) {
 	lst, err := ListPlatforms(ctx, c, namespace)
 	if err != nil {
 		return nil, err
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index 1230f15..fc8fba2 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -96,7 +96,7 @@ func (t *camelTrait) loadOrCreateCatalog(e *Environment, runtimeVersion string)
 		// the required versions (camel and runtime) are not expressed as
 		// semver constraints
 		if exactVersionRegexp.MatchString(runtimeVersion) {
-			catalog, err = camel.GenerateCatalog(e.C, e.Client, ns, e.Platform.Status.Build.Maven, runtime, []maven.Dependency{})
+			catalog, err = camel.GenerateCatalog(e.C, e.Client, e.Platform.Namespace, e.Platform.Status.Build.Maven, runtime, []maven.Dependency{})
 			if err != nil {
 				return err
 			}
diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go
index ba23835..197eb92 100644
--- a/pkg/trait/openapi.go
+++ b/pkg/trait/openapi.go
@@ -213,7 +213,7 @@ func (t *openAPITrait) createNewOpenAPIConfigMap(e *Environment, resource v1.Res
 	mc.AddArgument("-Dopenapi.spec=" + in)
 	mc.AddArgument("-Ddsl.out=" + out)
 
-	settings, err := kubernetes.ResolveValueSource(e.C, e.Client, e.Integration.Namespace, &e.Platform.Status.Build.Maven.Settings)
+	settings, err := kubernetes.ResolveValueSource(e.C, e.Client, e.Platform.Namespace, &e.Platform.Status.Build.Maven.Settings)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go
index 6e55d91..854bd46 100644
--- a/pkg/trait/platform.go
+++ b/pkg/trait/platform.go
@@ -35,6 +35,8 @@ type platformTrait struct {
 	BaseTrait `property:",squash"`
 	// To create a default (empty) platform when the platform is missing.
 	CreateDefault *bool `property:"create-default" json:"createDefault,omitempty"`
+	// Indicates if the platform should be created globally in the case of global operator (default true).
+	Global *bool `property:"global" json:"global,omitempty"`
 	// To automatically detect from the environment if a default platform can be created (it will be created on OpenShift only).
 	Auto *bool `property:"auto" json:"auto,omitempty"`
 }
@@ -55,12 +57,18 @@ func (t *platformTrait) Configure(e *Environment) (bool, error) {
 	}
 
 	if t.Auto == nil || !*t.Auto {
-		if e.Platform == nil && t.CreateDefault == nil {
-			// Calculate if the platform should be automatically created when missing.
-			if ocp, err := openshift.IsOpenShift(t.Client); err != nil {
-				return false, err
-			} else if ocp {
-				t.CreateDefault = &ocp
+		if e.Platform == nil {
+			if t.CreateDefault == nil {
+				// Calculate if the platform should be automatically created when missing.
+				if ocp, err := openshift.IsOpenShift(t.Client); err != nil {
+					return false, err
+				} else if ocp {
+					t.CreateDefault = &ocp
+				}
+			}
+			if t.Global == nil {
+				globalOperator := platform.IsCurrentOperatorGlobal()
+				t.Global = &globalOperator
 			}
 		}
 	}
@@ -92,14 +100,21 @@ func (t *platformTrait) Apply(e *Environment) error {
 }
 
 func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1.IntegrationPlatform, error) {
-	pl, err := platform.GetOrLookupAny(t.Ctx, t.Client, e.Integration.Namespace, e.Integration.Status.Platform)
+	pl, err := platform.GetOrFind(t.Ctx, t.Client, e.Integration.Namespace, e.Integration.Status.Platform, false)
 	if err != nil && k8serrors.IsNotFound(err) {
 		if t.CreateDefault != nil && *t.CreateDefault {
 			platformName := e.Integration.Status.Platform
 			if platformName == "" {
 				platformName = platform.DefaultPlatformName
 			}
-			defaultPlatform := v1.NewIntegrationPlatform(e.Integration.Namespace, platformName)
+			namespace := e.Integration.Namespace
+			if t.Global != nil && *t.Global {
+				operatorNamespace := platform.GetOperatorNamespace()
+				if operatorNamespace != "" {
+					namespace = operatorNamespace
+				}
+			}
+			defaultPlatform := v1.NewIntegrationPlatform(namespace, platformName)
 			if defaultPlatform.Labels == nil {
 				defaultPlatform.Labels = make(map[string]string)
 			}
diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go
index 55f87b8..28c388e 100644
--- a/pkg/trait/trait.go
+++ b/pkg/trait/trait.go
@@ -71,7 +71,7 @@ func newEnvironment(ctx context.Context, c client.Client, integration *v1.Integr
 		namespace = kit.Namespace
 	}
 
-	pl, err := platform.GetCurrentPlatform(ctx, c, namespace)
+	pl, err := platform.GetCurrent(ctx, c, namespace)
 	if err != nil && !k8serrors.IsNotFound(err) {
 		return nil, err
 	}
diff --git a/pkg/trait/util.go b/pkg/trait/util.go
index 9806c0f..97376f9 100644
--- a/pkg/trait/util.go
+++ b/pkg/trait/util.go
@@ -46,9 +46,9 @@ func GetIntegrationKit(ctx context.Context, c client.Client, integration *v1.Int
 	}
 
 	name := integration.Status.Kit
-	kit := v1.NewIntegrationKit(integration.Namespace, name)
+	kit := v1.NewIntegrationKit(integration.GetIntegrationKitNamespace(), name)
 	key := k8sclient.ObjectKey{
-		Namespace: integration.Namespace,
+		Namespace: integration.GetIntegrationKitNamespace(),
 		Name:      name,
 	}
 	err := c.Get(ctx, key, &kit)