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 2018/09/27 07:39:29 UTC

[camel-k] branch master updated (c3307f8 -> d802b6f)

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

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


    from c3307f8  Polish and make go-report happy
     new 1e09ec6  Fix some documentation
     new 21caae8  Add IntegrationPlatform CRD
     new 182aa0b  Fix typo
     new d802b6f  Aggregate platform phase from contexts

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 cmd/camel-k-operator/camel_k_operator.go           |   1 +
 ...-context.yaml => crd-integration-platform.yaml} |  12 +--
 deploy/platform-cr.yaml                            |   6 ++
 deploy/resources.go                                |  31 ++++++
 docs/cluster-setup.adoc                            |   4 +-
 docs/developers.adoc                               |   8 +-
 pkg/apis/camel/v1alpha1/register.go                |   2 +
 pkg/apis/camel/v1alpha1/types.go                   |  76 ++++++++++++++
 pkg/apis/camel/v1alpha1/types_support.go           |  10 ++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   | 110 ++++++++++++++++++++
 pkg/client/cmd/install.go                          |   4 +-
 pkg/install/cluster.go                             |   5 +
 pkg/install/{operator.go => common.go}             |  39 ++-----
 pkg/install/operator.go                            |  56 +----------
 pkg/platform/build.go                              |  91 +++++++++++++++++
 pkg/{apis/camel/v1alpha1 => platform}/doc.go       |   6 +-
 pkg/platform/get.go                                |  53 ++++++++++
 pkg/stub/action/context/action.go                  |   6 +-
 pkg/stub/action/context/build.go                   |  73 ++++----------
 pkg/stub/action/context/initialize.go              |  25 +++--
 pkg/stub/action/context/monitor.go                 |  17 ++--
 pkg/stub/action/integration/action.go              |   6 +-
 pkg/stub/action/integration/build.go               |   6 +-
 pkg/stub/action/integration/deploy.go              |  16 +--
 pkg/stub/action/integration/initialize.go          |  13 ++-
 pkg/stub/action/integration/monitor.go             |   5 +-
 pkg/stub/action/integration/util.go                |  19 +++-
 pkg/stub/action/{context => platform}/action.go    |  11 +-
 pkg/stub/action/platform/create.go                 |  54 ++++++++++
 pkg/stub/action/platform/initialize.go             | 112 +++++++++++++++++++++
 pkg/stub/action/platform/start.go                  |  81 +++++++++++++++
 pkg/stub/handler.go                                |  53 ++++++----
 pkg/util/openshift/register.go                     |   2 +-
 runtime/examples/routes-rest.js                    |   2 +-
 34 files changed, 802 insertions(+), 213 deletions(-)
 copy deploy/{crd-integration-context.yaml => crd-integration-platform.yaml} (52%)
 create mode 100644 deploy/platform-cr.yaml
 copy pkg/install/{operator.go => common.go} (66%)
 create mode 100644 pkg/platform/build.go
 copy pkg/{apis/camel/v1alpha1 => platform}/doc.go (87%)
 create mode 100644 pkg/platform/get.go
 copy pkg/stub/action/{context => platform}/action.go (82%)
 create mode 100644 pkg/stub/action/platform/create.go
 create mode 100644 pkg/stub/action/platform/initialize.go
 create mode 100644 pkg/stub/action/platform/start.go


[camel-k] 03/04: Fix typo

Posted by lb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 182aa0b44b90b44ef78f69fdd22af062822a7c2c
Author: nferraro <ni...@gmail.com>
AuthorDate: Tue Sep 25 12:34:26 2018 +0200

    Fix typo
---
 runtime/examples/routes-rest.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/examples/routes-rest.js b/runtime/examples/routes-rest.js
index 47b9c24..e888019 100644
--- a/runtime/examples/routes-rest.js
+++ b/runtime/examples/routes-rest.js
@@ -1,7 +1,7 @@
 //
 // To run this integrations use:
 //
-//     kamel run --name=withrest --dependency=camel:undertow runtime/examples/routes-rest.js
+//     kamel run --name=withrest --dependency=camel-undertow runtime/examples/routes-rest.js
 //
 
 // ****************


[camel-k] 01/04: Fix some documentation

Posted by lb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1e09ec60beebc47d9157d9b298f99d118619dce0
Author: nferraro <ni...@gmail.com>
AuthorDate: Tue Sep 25 12:26:58 2018 +0200

    Fix some documentation
---
 docs/cluster-setup.adoc | 4 +++-
 docs/developers.adoc    | 8 ++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/docs/cluster-setup.adoc b/docs/cluster-setup.adoc
index 2564b78..7e52648 100644
--- a/docs/cluster-setup.adoc
+++ b/docs/cluster-setup.adoc
@@ -7,7 +7,7 @@ There are various options for creating a development cluster:
 [[minishift]]
 == Minishift
 
-You can run Camel K integrations on Openshift using the Minishift cluster creation tool.
+You can run Camel K integrations on OpenShift using the Minishift cluster creation tool.
 Follow the instructions in the https://github.com/minishift/minishift#getting-started[getting started guide] for the installation.
 
 After installing the `minishift` binary, you need to enable the `admin-user` addon:
@@ -16,6 +16,8 @@ After installing the `minishift` binary, you need to enable the `admin-user` add
 minishift addons enable admin-user
 ```
 
+NOTE: the admin user addon should be enabled before starting the cluster for the first time
+
 Then you can start the cluster with:
 
 ```
diff --git a/docs/developers.adoc b/docs/developers.adoc
index 983f15a..06bb10a 100644
--- a/docs/developers.adoc
+++ b/docs/developers.adoc
@@ -45,7 +45,7 @@ This is a high level overview of the project structure:
 | link:/docs[/docs]			| Contains this documentation.
 | link:/pkg[/pkg]			| This is where the code resides. The code is divided in multiple subpackages.
 | link:/runtime[/runtime]	| The Java runtime code that is used inside the integration Docker containers.
-| link:/test[/test]			| Include integration tests to ensure that the software interacts correctly with Kubernetes and Openshift.
+| link:/test[/test]			| Include integration tests to ensure that the software interacts correctly with Kubernetes and OpenShift.
 | link:/tmp[/tmp]			| Scripts and Docker configuration files used by the operator-sdk.
 | /vendor					| Project dependencies (not staged in git).
 | link:/version[/version]	| Contains the global version of the project.
@@ -88,7 +88,7 @@ make images
 
 Unit tests are executed automatically as part of the build. They use the standard go testing framework.
 
-Integration tests (aimed at ensuring that the code integrates correctly with Kubernetes and Openshift), need special care.
+Integration tests (aimed at ensuring that the code integrates correctly with Kubernetes and OpenShift), need special care.
 
 The **convention** used in this repo is to name unit tests `xxx_test.go`, and name integration tests `yyy_integration_test.go`.
 Integration tests are all in the link:/test[/test] dir.
@@ -102,7 +102,7 @@ integration tests. A integration test should start with the following line:
 
 Look into the link:/test[/test] directory for examples of integration tests.
 
-Before running a integration test, you need to be connected to a Kubernetes/Openshift namespace.
+Before running a integration test, you need to be connected to a Kubernetes/OpenShift namespace.
 After you log in into your cluster, you can run the following command to execute **all** integration tests:
 
 ```
@@ -144,7 +144,7 @@ It should be straightforward: just execute the link:/cmd/kamel/kamel.go[/cmd/kam
 
 It is a bit more complex (but not so much).
 
-You are going to run the operator code **outside** Openshift in your IDE so, first of all, you need to **stop the operator running inside**:
+You are going to run the operator code **outside** OpenShift in your IDE so, first of all, you need to **stop the operator running inside**:
 
 ```
 // use kubectl in plain Kubernetes


[camel-k] 04/04: Aggregate platform phase from contexts

Posted by lb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d802b6f4680cc29f58ff7a81830f0c1051ddd859
Author: nferraro <ni...@gmail.com>
AuthorDate: Tue Sep 25 13:52:50 2018 +0200

    Aggregate platform phase from contexts
---
 pkg/stub/action/platform/start.go | 50 ++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/pkg/stub/action/platform/start.go b/pkg/stub/action/platform/start.go
index e56ba09..df205db 100644
--- a/pkg/stub/action/platform/start.go
+++ b/pkg/stub/action/platform/start.go
@@ -21,6 +21,7 @@ import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
 	"github.com/sirupsen/logrus"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 // NewStartAction returns a action that waits for all required platform resources to start
@@ -40,40 +41,41 @@ func (action *startAction) CanHandle(platform *v1alpha1.IntegrationPlatform) boo
 }
 
 func (action *startAction) Handle(platform *v1alpha1.IntegrationPlatform) error {
-
-	coreStatus, err := action.getContextReady(platform.Namespace, "core")
-	if err != nil {
-		return err
-	}
-
-	groovyStatus, err := action.getContextReady(platform.Namespace, "groovy")
+	aggregatePhase, err := action.aggregatePlatformPhaseFromContexts(platform.Namespace)
 	if err != nil {
 		return err
 	}
-
-	if coreStatus == v1alpha1.IntegrationContextPhaseError || groovyStatus == v1alpha1.IntegrationContextPhaseError {
-		if platform.Status.Phase != v1alpha1.IntegrationPlatformPhaseError {
-			target := platform.DeepCopy()
-			logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseError)
-			target.Status.Phase = v1alpha1.IntegrationPlatformPhaseError
-			return sdk.Update(target)
-		}
-		return nil
-	} else if coreStatus == v1alpha1.IntegrationContextPhaseReady && groovyStatus == v1alpha1.IntegrationContextPhaseReady {
+	if platform.Status.Phase != aggregatePhase {
 		target := platform.DeepCopy()
-		logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseReady)
-		target.Status.Phase = v1alpha1.IntegrationPlatformPhaseReady
+		logrus.Info("Platform ", target.Name, " transitioning to state ", aggregatePhase)
+		target.Status.Phase = aggregatePhase
 		return sdk.Update(target)
 	}
-
 	// wait
 	return nil
 }
 
-func (action *startAction) getContextReady(namespace string, name string) (v1alpha1.IntegrationContextPhase, error) {
-	ctx := v1alpha1.NewIntegrationContext(namespace, name)
-	if err := sdk.Get(&ctx); err != nil {
+func (action *startAction) aggregatePlatformPhaseFromContexts(namespace string) (v1alpha1.IntegrationPlatformPhase, error) {
+	ctxs := v1alpha1.NewIntegrationContextList()
+	options := metav1.ListOptions{
+		LabelSelector: "camel.apache.org/context.type=platform",
+	}
+	if err := sdk.List(namespace, &ctxs, sdk.WithListOptions(&options)); err != nil {
 		return "", err
 	}
-	return ctx.Status.Phase, nil
+
+	countReady := 0
+	for _, ctx := range ctxs.Items {
+		if ctx.Status.Phase == v1alpha1.IntegrationContextPhaseError {
+			return v1alpha1.IntegrationPlatformPhaseError, nil
+		} else if ctx.Status.Phase == v1alpha1.IntegrationContextPhaseReady {
+			countReady++
+		}
+	}
+
+	if countReady < len(ctxs.Items) {
+		return v1alpha1.IntegrationPlatformPhaseStarting, nil
+	}
+
+	return v1alpha1.IntegrationPlatformPhaseReady, nil
 }


[camel-k] 02/04: Add IntegrationPlatform CRD

Posted by lb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 21caae8ff53055dff840f3d6f19ff562fbfff148
Author: nferraro <ni...@gmail.com>
AuthorDate: Tue Sep 25 12:30:22 2018 +0200

    Add IntegrationPlatform CRD
---
 cmd/camel-k-operator/camel_k_operator.go           |   1 +
 deploy/crd-integration-platform.yaml               |  17 ++++
 deploy/platform-cr.yaml                            |   6 ++
 deploy/resources.go                                |  31 ++++++
 pkg/apis/camel/v1alpha1/register.go                |   2 +
 pkg/apis/camel/v1alpha1/types.go                   |  76 ++++++++++++++
 pkg/apis/camel/v1alpha1/types_support.go           |  10 ++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   | 110 ++++++++++++++++++++
 pkg/client/cmd/install.go                          |   4 +-
 pkg/install/cluster.go                             |   5 +
 pkg/install/{operator.go => common.go}             |  39 ++-----
 pkg/install/operator.go                            |  56 +----------
 pkg/platform/build.go                              |  91 +++++++++++++++++
 .../integration/action.go => platform/doc.go}      |  20 +---
 pkg/platform/get.go                                |  53 ++++++++++
 pkg/stub/action/context/action.go                  |   6 +-
 pkg/stub/action/context/build.go                   |  73 ++++----------
 pkg/stub/action/context/initialize.go              |  25 +++--
 pkg/stub/action/context/monitor.go                 |  17 ++--
 pkg/stub/action/integration/action.go              |   6 +-
 pkg/stub/action/integration/build.go               |   6 +-
 pkg/stub/action/integration/deploy.go              |  16 +--
 pkg/stub/action/integration/initialize.go          |  13 ++-
 pkg/stub/action/integration/monitor.go             |   5 +-
 pkg/stub/action/integration/util.go                |  19 +++-
 pkg/stub/action/{context => platform}/action.go    |  11 +-
 pkg/stub/action/platform/create.go                 |  54 ++++++++++
 pkg/stub/action/platform/initialize.go             | 112 +++++++++++++++++++++
 pkg/stub/action/platform/start.go                  |  79 +++++++++++++++
 pkg/stub/handler.go                                |  53 ++++++----
 pkg/util/openshift/register.go                     |   2 +-
 31 files changed, 803 insertions(+), 215 deletions(-)

diff --git a/cmd/camel-k-operator/camel_k_operator.go b/cmd/camel-k-operator/camel_k_operator.go
index 32ee754..79ae793 100644
--- a/cmd/camel-k-operator/camel_k_operator.go
+++ b/cmd/camel-k-operator/camel_k_operator.go
@@ -62,6 +62,7 @@ func main() {
 
 	watch(resource, "Integration", namespace, resyncPeriod)
 	watch(resource, "IntegrationContext", namespace, resyncPeriod)
+	watch(resource, "IntegrationPlatform", namespace, resyncPeriod)
 
 	sdk.Handle(stub.NewHandler(ctx, namespace))
 	sdk.Run(ctx)
diff --git a/deploy/crd-integration-platform.yaml b/deploy/crd-integration-platform.yaml
new file mode 100644
index 0000000..ccba19c
--- /dev/null
+++ b/deploy/crd-integration-platform.yaml
@@ -0,0 +1,17 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: integrationplatforms.camel.apache.org
+  labels:
+    app: "camel-k"
+spec:
+  group: camel.apache.org
+  names:
+    kind: IntegrationPlatform
+    listKind: IntegrationPlatformList
+    plural: integrationplatforms
+    singular: integrationplatform
+    shortNames:
+    - ip
+  scope: Namespaced
+  version: v1alpha1
diff --git a/deploy/platform-cr.yaml b/deploy/platform-cr.yaml
new file mode 100644
index 0000000..cdf13ff
--- /dev/null
+++ b/deploy/platform-cr.yaml
@@ -0,0 +1,6 @@
+apiVersion: camel.apache.org/v1alpha1
+kind: IntegrationPlatform
+metadata:
+  name: camel-k
+  labels:
+    app: "camel-k"
diff --git a/deploy/resources.go b/deploy/resources.go
index 7a9888f..7749be3 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -2123,6 +2123,27 @@ spec:
   version: v1alpha1
 
 `
+	Resources["crd-integration-platform.yaml"] =
+		`
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: integrationplatforms.camel.apache.org
+  labels:
+    app: "camel-k"
+spec:
+  group: camel.apache.org
+  names:
+    kind: IntegrationPlatform
+    listKind: IntegrationPlatformList
+    plural: integrationplatforms
+    singular: integrationplatform
+    shortNames:
+    - ip
+  scope: Namespaced
+  version: v1alpha1
+
+`
 	Resources["crd-integration.yaml"] =
 		`
 apiVersion: apiextensions.k8s.io/v1beta1
@@ -2436,6 +2457,16 @@ status:
   loadBalancer: {}
 
 `
+	Resources["platform-cr.yaml"] =
+		`
+apiVersion: camel.apache.org/v1alpha1
+kind: IntegrationPlatform
+metadata:
+  name: camel-k
+  labels:
+    app: "camel-k"
+
+`
 	Resources["platform-integration-context-core.yaml"] =
 		`
 apiVersion: camel.apache.org/v1alpha1
diff --git a/pkg/apis/camel/v1alpha1/register.go b/pkg/apis/camel/v1alpha1/register.go
index 460dd4c..7ef6212 100644
--- a/pkg/apis/camel/v1alpha1/register.go
+++ b/pkg/apis/camel/v1alpha1/register.go
@@ -49,6 +49,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 		&IntegrationList{},
 		&IntegrationContext{},
 		&IntegrationContextList{},
+		&IntegrationPlatform{},
+		&IntegrationPlatformList{},
 	)
 	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 	return nil
diff --git a/pkg/apis/camel/v1alpha1/types.go b/pkg/apis/camel/v1alpha1/types.go
index 80ebe59..fa27617 100644
--- a/pkg/apis/camel/v1alpha1/types.go
+++ b/pkg/apis/camel/v1alpha1/types.go
@@ -150,3 +150,79 @@ const (
 	// IntegrationContextPhaseError --
 	IntegrationContextPhaseError IntegrationContextPhase = "Error"
 )
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// IntegrationPlatformList --
+type IntegrationPlatformList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata"`
+	Items           []IntegrationPlatform `json:"items"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// IntegrationPlatform --
+type IntegrationPlatform struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata"`
+	Spec              IntegrationPlatformSpec   `json:"spec"`
+	Status            IntegrationPlatformStatus `json:"status,omitempty"`
+}
+
+// IntegrationPlatformSpec --
+type IntegrationPlatformSpec struct {
+	Cluster IntegrationPlatformCluster   `json:"cluster,omitempty"`
+	Build   IntegrationPlatformBuildSpec `json:"build,omitempty"`
+}
+
+// IntegrationPlatformCluster is the kind of orchestration cluster the platform is installed into
+type IntegrationPlatformCluster string
+
+const (
+	// IntegrationPlatformClusterOpenShift is used when targeting a OpenShift cluster
+	IntegrationPlatformClusterOpenShift = "OpenShift"
+	// IntegrationPlatformClusterKubernetes is used when targeting a Kubernetes cluster
+	IntegrationPlatformClusterKubernetes = "Kubernetes"
+)
+
+// IntegrationPlatformBuildSpec contains platform related build information
+type IntegrationPlatformBuildSpec struct {
+	PublishStrategy IntegrationPlatformBuildPublishStrategy `json:"publishStrategy,omitempty"`
+	Registry        string                                  `json:"registry,omitempty"`
+}
+
+// IntegrationPlatformBuildPublishStrategy enumerates all implemented build strategies
+type IntegrationPlatformBuildPublishStrategy string
+
+const (
+	// IntegrationPlatformBuildPublishStrategyS2I performs a OpenShift binary S2I build
+	IntegrationPlatformBuildPublishStrategyS2I = "S2I"
+
+	// IntegrationPlatformBuildPublishStrategyKaniko performs
+	IntegrationPlatformBuildPublishStrategyKaniko = "Kaniko"
+)
+
+// IntegrationPlatformStatus --
+type IntegrationPlatformStatus struct {
+	Phase IntegrationPlatformPhase `json:"phase,omitempty"`
+}
+
+// IntegrationPlatformPhase --
+type IntegrationPlatformPhase string
+
+const (
+	// IntegrationPlatformKind --
+	IntegrationPlatformKind string = "IntegrationPlatform"
+
+	// IntegrationPlatformPhaseCreating --
+	IntegrationPlatformPhaseCreating IntegrationPlatformPhase = "Creating"
+	// IntegrationPlatformPhaseStarting --
+	IntegrationPlatformPhaseStarting IntegrationPlatformPhase = "Starting"
+	// IntegrationPlatformPhaseReady --
+	IntegrationPlatformPhaseReady IntegrationPlatformPhase = "Ready"
+	// IntegrationPlatformPhaseError --
+	IntegrationPlatformPhaseError IntegrationPlatformPhase = "Error"
+	// IntegrationPlatformPhaseDuplicate --
+	IntegrationPlatformPhaseDuplicate IntegrationPlatformPhase = "Duplicate"
+)
diff --git a/pkg/apis/camel/v1alpha1/types_support.go b/pkg/apis/camel/v1alpha1/types_support.go
index 39eb11d..fa4cceb 100644
--- a/pkg/apis/camel/v1alpha1/types_support.go
+++ b/pkg/apis/camel/v1alpha1/types_support.go
@@ -39,6 +39,16 @@ func (spec ConfigurationSpec) String() string {
 //
 // **********************************
 
+// NewIntegrationPlatformList --
+func NewIntegrationPlatformList() IntegrationPlatformList {
+	return IntegrationPlatformList{
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: SchemeGroupVersion.String(),
+			Kind:       IntegrationPlatformKind,
+		},
+	}
+}
+
 // NewIntegrationList --
 func NewIntegrationList() IntegrationList {
 	return IntegrationList{
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index 0784edc..57ff452 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -211,6 +211,116 @@ func (in *IntegrationList) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatform) DeepCopyInto(out *IntegrationPlatform) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	out.Spec = in.Spec
+	out.Status = in.Status
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatform.
+func (in *IntegrationPlatform) DeepCopy() *IntegrationPlatform {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatform)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IntegrationPlatform) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatformBuildSpec) DeepCopyInto(out *IntegrationPlatformBuildSpec) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatformBuildSpec.
+func (in *IntegrationPlatformBuildSpec) DeepCopy() *IntegrationPlatformBuildSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatformBuildSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatformList) DeepCopyInto(out *IntegrationPlatformList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	out.ListMeta = in.ListMeta
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]IntegrationPlatform, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatformList.
+func (in *IntegrationPlatformList) DeepCopy() *IntegrationPlatformList {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatformList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IntegrationPlatformList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatformSpec) DeepCopyInto(out *IntegrationPlatformSpec) {
+	*out = *in
+	out.Build = in.Build
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatformSpec.
+func (in *IntegrationPlatformSpec) DeepCopy() *IntegrationPlatformSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatformSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatformStatus) DeepCopyInto(out *IntegrationPlatformStatus) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatformStatus.
+func (in *IntegrationPlatformStatus) DeepCopy() *IntegrationPlatformStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatformStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *IntegrationSpec) DeepCopyInto(out *IntegrationSpec) {
 	*out = *in
 	if in.Replicas != nil {
diff --git a/pkg/client/cmd/install.go b/pkg/client/cmd/install.go
index 2ca05ba..0d20021 100644
--- a/pkg/client/cmd/install.go
+++ b/pkg/client/cmd/install.go
@@ -35,7 +35,7 @@ func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command {
 	cmd := cobra.Command{
 		Use:   "install",
 		Short: "Install Camel K on a Kubernetes cluster",
-		Long:  `Installs Camel K on a Kubernetes or Openshift cluster.`,
+		Long:  `Installs Camel K on a Kubernetes or OpenShift cluster.`,
 		RunE:  options.install,
 	}
 
@@ -69,7 +69,7 @@ func (o *installCmdOptions) install(cmd *cobra.Command, args []string) error {
 			return err
 		}
 
-		err = install.PlatformContexts(namespace)
+		err = install.Platform(namespace)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go
index 855d8f6..dea1dee 100644
--- a/pkg/install/cluster.go
+++ b/pkg/install/cluster.go
@@ -32,6 +32,11 @@ import (
 // SetupClusterwideResources --
 func SetupClusterwideResources() error {
 
+	// Install CRD for Integration Platform (if needed)
+	if err := installCRD("IntegrationPlatform", "crd-integration-platform.yaml"); err != nil {
+		return err
+	}
+
 	// Install CRD for Integration Context (if needed)
 	if err := installCRD("IntegrationContext", "crd-integration-context.yaml"); err != nil {
 		return err
diff --git a/pkg/install/operator.go b/pkg/install/common.go
similarity index 66%
copy from pkg/install/operator.go
copy to pkg/install/common.go
index 58aed65..bef7f6f 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/common.go
@@ -26,42 +26,18 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-// Operator --
-func Operator(namespace string) error {
-	return installResources(namespace,
-		"operator-service-account.yaml",
-		"operator-role-openshift.yaml", // TODO distinguish between Openshift and Kubernetes
-		"operator-role-binding.yaml",
-		"operator-deployment.yaml",
-		"operator-service.yaml",
-	)
-}
-
-// PlatformContexts --
-func PlatformContexts(namespace string) error {
-	return installResources(namespace,
-		"platform-integration-context-core.yaml",
-		"platform-integration-context-groovy.yaml",
-	)
-}
-
-// Example --
-func Example(namespace string) error {
-	return installResources(namespace,
-		"cr-example.yaml",
-	)
-}
-
-func installResources(namespace string, names ...string) error {
+// Resources installs named resources from the project resource directory
+func Resources(namespace string, names ...string) error {
 	for _, name := range names {
-		if err := installResource(namespace, name); err != nil {
+		if err := Resource(namespace, name); err != nil {
 			return err
 		}
 	}
 	return nil
 }
 
-func installResource(namespace string, name string) error {
+// Resource installs a single named resource from the project resource directory
+func Resource(namespace string, name string) error {
 	obj, err := kubernetes.LoadResourceFromYaml(deploy.Resources[name])
 	if err != nil {
 		return err
@@ -77,10 +53,13 @@ func installResource(namespace string, name string) error {
 		if obj.GetObjectKind().GroupVersionKind().Kind == "Service" {
 			return nil
 		}
-		// Don't recreate integration contexts
+		// Don't recreate integration contexts or platforms
 		if obj.GetObjectKind().GroupVersionKind().Kind == v1alpha1.IntegrationContextKind {
 			return nil
 		}
+		if obj.GetObjectKind().GroupVersionKind().Kind == v1alpha1.IntegrationPlatformKind {
+			return nil
+		}
 		return sdk.Update(obj)
 	}
 	return err
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 58aed65..0f6039c 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -17,18 +17,9 @@ limitations under the License.
 
 package install
 
-import (
-	"github.com/apache/camel-k/deploy"
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-	"github.com/operator-framework/operator-sdk/pkg/sdk"
-	"k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
 // Operator --
 func Operator(namespace string) error {
-	return installResources(namespace,
+	return Resources(namespace,
 		"operator-service-account.yaml",
 		"operator-role-openshift.yaml", // TODO distinguish between Openshift and Kubernetes
 		"operator-role-binding.yaml",
@@ -37,51 +28,14 @@ func Operator(namespace string) error {
 	)
 }
 
-// PlatformContexts --
-func PlatformContexts(namespace string) error {
-	return installResources(namespace,
-		"platform-integration-context-core.yaml",
-		"platform-integration-context-groovy.yaml",
-	)
+// Platform installs the platform custom resource
+func Platform(namespace string) error {
+	return Resource(namespace,"platform-cr.yaml")
 }
 
 // Example --
 func Example(namespace string) error {
-	return installResources(namespace,
+	return Resources(namespace,
 		"cr-example.yaml",
 	)
 }
-
-func installResources(namespace string, names ...string) error {
-	for _, name := range names {
-		if err := installResource(namespace, name); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func installResource(namespace string, name string) error {
-	obj, err := kubernetes.LoadResourceFromYaml(deploy.Resources[name])
-	if err != nil {
-		return err
-	}
-
-	if metaObject, ok := obj.(metav1.Object); ok {
-		metaObject.SetNamespace(namespace)
-	}
-
-	err = sdk.Create(obj)
-	if err != nil && errors.IsAlreadyExists(err) {
-		// Don't recreate Service object
-		if obj.GetObjectKind().GroupVersionKind().Kind == "Service" {
-			return nil
-		}
-		// Don't recreate integration contexts
-		if obj.GetObjectKind().GroupVersionKind().Kind == v1alpha1.IntegrationContextKind {
-			return nil
-		}
-		return sdk.Update(obj)
-	}
-	return err
-}
diff --git a/pkg/platform/build.go b/pkg/platform/build.go
new file mode 100644
index 0000000..994ced6
--- /dev/null
+++ b/pkg/platform/build.go
@@ -0,0 +1,91 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package platform
+
+import (
+	"context"
+	"errors"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/build"
+	"github.com/apache/camel-k/pkg/build/assemble"
+	"github.com/apache/camel-k/pkg/build/publish"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// buildManager is the current build manager
+// Note: it cannot be changed at runtime, needs a operator restart
+var buildManager *build.Manager
+
+// GetPlatformBuildManager returns a suitable build manager for the current platform
+func GetPlatformBuildManager(ctx context.Context, namespace string) (*build.Manager, error) {
+	if buildManager != nil {
+		return buildManager, nil
+	}
+	pl, err := GetCurrentPlatform(namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	assembler := assemble.NewMavenAssembler(ctx)
+	if pl.Spec.Build.PublishStrategy == v1alpha1.IntegrationPlatformBuildPublishStrategyS2I {
+		publisher := publish.NewS2IIncrementalPublisher(ctx, namespace, newContextLister(namespace))
+		buildManager = build.NewManager(ctx, assembler, publisher)
+	}
+
+	if buildManager == nil {
+		return nil, errors.New("unsupported platform configuration")
+	}
+	return buildManager, nil
+}
+
+// =================================================================
+
+type contextLister struct {
+	namespace string
+}
+
+func newContextLister(namespace string) contextLister {
+	return contextLister{
+		namespace: namespace,
+	}
+}
+
+func (l contextLister) ListPublishedImages() ([]publish.PublishedImage, error) {
+	list := v1alpha1.NewIntegrationContextList()
+
+	err := sdk.List(l.namespace, &list, sdk.WithListOptions(&metav1.ListOptions{}))
+	if err != nil {
+		return nil, err
+	}
+	images := make([]publish.PublishedImage, 0)
+	for _, ctx := range list.Items {
+		if ctx.Status.Phase != v1alpha1.IntegrationContextPhaseReady || ctx.Labels == nil {
+			continue
+		}
+		if ctxType, present := ctx.Labels["camel.apache.org/context.type"]; !present || ctxType != "platform" {
+			continue
+		}
+
+		images = append(images, publish.PublishedImage{
+			Image:     ctx.Status.Image,
+			Classpath: ctx.Status.Classpath,
+		})
+	}
+	return images, nil
+}
diff --git a/pkg/stub/action/integration/action.go b/pkg/platform/doc.go
similarity index 65%
copy from pkg/stub/action/integration/action.go
copy to pkg/platform/doc.go
index 9e4a69c..74e5c18 100644
--- a/pkg/stub/action/integration/action.go
+++ b/pkg/platform/doc.go
@@ -15,21 +15,5 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
-
-import (
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-)
-
-// IntegrationAction --
-type IntegrationAction interface {
-
-	// a user friendly name for the action
-	Name() string
-
-	// returns true if the action can handle the integration
-	CanHandle(integration *v1alpha1.Integration) bool
-
-	// executes the handling function
-	Handle(integration *v1alpha1.Integration) error
-}
+// Package platform allows to retrieve information about the current installed platform
+package platform
diff --git a/pkg/platform/get.go b/pkg/platform/get.go
new file mode 100644
index 0000000..0da7163
--- /dev/null
+++ b/pkg/platform/get.go
@@ -0,0 +1,53 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package platform
+
+import (
+	"errors"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+)
+
+// GetCurrentPlatform returns the currently installed platform
+func GetCurrentPlatform(namespace string) (*v1alpha1.IntegrationPlatform, error) {
+	lst, err := ListPlatforms(namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, platform := range lst.Items {
+		if IsActive(&platform) {
+			return &platform, nil
+		}
+	}
+	return nil, errors.New("no active integration platforms found in the namespace")
+}
+
+// ListPlatforms returns all platforms installed in a given namespace (only one will be active)
+func ListPlatforms(namespace string) (*v1alpha1.IntegrationPlatformList, error) {
+	lst := v1alpha1.NewIntegrationPlatformList()
+	if err := sdk.List(namespace, &lst); err != nil {
+		return nil, err
+	}
+	return &lst, nil
+}
+
+// IsActive determines if the given platform is being used
+func IsActive(p *v1alpha1.IntegrationPlatform) bool {
+	return p.Status.Phase != "" && p.Status.Phase != v1alpha1.IntegrationPlatformPhaseDuplicate
+}
diff --git a/pkg/stub/action/context/action.go b/pkg/stub/action/context/action.go
index 23b0f10..97f35c4 100644
--- a/pkg/stub/action/context/action.go
+++ b/pkg/stub/action/context/action.go
@@ -15,14 +15,14 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package context
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
-// IntegrationContextAction --
-type IntegrationContextAction interface {
+// Action --
+type Action interface {
 
 	// a user friendly name for the action
 	Name() string
diff --git a/pkg/stub/action/context/build.go b/pkg/stub/action/context/build.go
index a0ab58f..875114b 100644
--- a/pkg/stub/action/context/build.go
+++ b/pkg/stub/action/context/build.go
@@ -15,12 +15,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package context
 
 import (
 	"context"
-	"github.com/apache/camel-k/pkg/build/assemble"
-	"github.com/apache/camel-k/pkg/build/publish"
+	"github.com/apache/camel-k/pkg/platform"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
@@ -31,49 +30,52 @@ import (
 	"github.com/apache/camel-k/pkg/build"
 )
 
-// NewIntegrationContextBuildAction creates a new build handling action for the context
-func NewIntegrationContextBuildAction(ctx context.Context, namespace string) IntegrationContextAction {
-	assembler := assemble.NewMavenAssembler(ctx)
-	publisher := publish.NewS2IIncrementalPublisher(ctx, namespace, newContextLister(namespace))
-	manager := build.NewManager(ctx, assembler, publisher)
-
-	return &integrationContextBuildAction{
-		buildManager: manager,
+// NewBuildAction creates a new build handling action for the context
+func NewBuildAction(ctx context.Context) Action {
+	return &buildAction{
+		ctx,
 	}
 }
 
-type integrationContextBuildAction struct {
-	buildManager *build.Manager
+type buildAction struct {
+	context.Context
 }
 
-func (action *integrationContextBuildAction) Name() string {
+func (action *buildAction) Name() string {
 	return "build"
 }
 
-func (action *integrationContextBuildAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+func (action *buildAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
 	return context.Status.Phase == v1alpha1.IntegrationContextPhaseBuilding
 }
 
-func (action *integrationContextBuildAction) Handle(context *v1alpha1.IntegrationContext) error {
+func (action *buildAction) Handle(context *v1alpha1.IntegrationContext) error {
+	buildManager, err := platform.GetPlatformBuildManager(action.Context, context.Namespace)
+	if err != nil {
+		return err
+	}
+
 	buildIdentifier := build.Identifier{
 		Name:      "context-" + context.Name,
 		Qualifier: context.ResourceVersion,
 	}
 
-	buildResult := action.buildManager.Get(buildIdentifier)
+	buildResult := buildManager.Get(buildIdentifier)
 	if buildResult.Status == build.StatusNotRequested {
-		action.buildManager.Start(build.Request{
+		buildManager.Start(build.Request{
 			Identifier:   buildIdentifier,
 			Dependencies: context.Spec.Dependencies,
 		})
 		logrus.Info("Build started")
 	} else if buildResult.Status == build.StatusError {
 		target := context.DeepCopy()
+		logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseError)
 		target.Status.Phase = v1alpha1.IntegrationContextPhaseError
 		return sdk.Update(target)
 	} else if buildResult.Status == build.StatusCompleted {
 		target := context.DeepCopy()
 		target.Status.Image = buildResult.Image
+		logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseReady)
 		target.Status.Phase = v1alpha1.IntegrationContextPhaseReady
 
 		target.Status.Classpath = make([]string, len(buildResult.Classpath))
@@ -93,7 +95,7 @@ func (action *integrationContextBuildAction) Handle(context *v1alpha1.Integratio
 }
 
 // informIntegrations triggers the processing of all integrations waiting for this context to be built
-func (action *integrationContextBuildAction) informIntegrations(context *v1alpha1.IntegrationContext) error {
+func (action *buildAction) informIntegrations(context *v1alpha1.IntegrationContext) error {
 	list := v1alpha1.NewIntegrationList()
 	err := sdk.List(context.Namespace, &list, sdk.WithListOptions(&metav1.ListOptions{}))
 	if err != nil {
@@ -116,37 +118,4 @@ func (action *integrationContextBuildAction) informIntegrations(context *v1alpha
 	return nil
 }
 
-// =================================================================
-
-type contextLister struct {
-	namespace string
-}
-
-func newContextLister(namespace string) contextLister {
-	return contextLister{
-		namespace: namespace,
-	}
-}
-
-func (l contextLister) ListPublishedImages() ([]publish.PublishedImage, error) {
-	list := v1alpha1.NewIntegrationContextList()
-	err := sdk.List(l.namespace, &list, sdk.WithListOptions(&metav1.ListOptions{}))
-	if err != nil {
-		return nil, err
-	}
-	images := make([]publish.PublishedImage, 0)
-	for _, ctx := range list.Items {
-		if ctx.Status.Phase != v1alpha1.IntegrationContextPhaseReady || ctx.Labels == nil {
-			continue
-		}
-		if ctxType, present := ctx.Labels["camel.apache.org/context.type"]; !present || ctxType != "platform" {
-			continue
-		}
 
-		images = append(images, publish.PublishedImage{
-			Image:     ctx.Status.Image,
-			Classpath: ctx.Status.Classpath,
-		})
-	}
-	return images, nil
-}
diff --git a/pkg/stub/action/context/initialize.go b/pkg/stub/action/context/initialize.go
index 64d7647..6f7108e 100644
--- a/pkg/stub/action/context/initialize.go
+++ b/pkg/stub/action/context/initialize.go
@@ -15,34 +15,43 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package context
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/platform"
 	"github.com/apache/camel-k/pkg/util/digest"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	"github.com/sirupsen/logrus"
 )
 
-// NewIntegrationContextInitializeAction creates a new initialization handling action for the context
-func NewIntegrationContextInitializeAction() IntegrationContextAction {
-	return &integrationContextInitializeAction{}
+// NewInitializeAction creates a new initialization handling action for the context
+func NewInitializeAction() Action {
+	return &initializeAction{}
 }
 
-type integrationContextInitializeAction struct {
+type initializeAction struct {
 }
 
-func (action *integrationContextInitializeAction) Name() string {
+func (action *initializeAction) Name() string {
 	return "initialize"
 }
 
-func (action *integrationContextInitializeAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+func (action *initializeAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
 	return context.Status.Phase == ""
 }
 
-func (action *integrationContextInitializeAction) Handle(context *v1alpha1.IntegrationContext) error {
+func (action *initializeAction) Handle(context *v1alpha1.IntegrationContext) error {
+	// The integration platform needs to be initialized before starting to create contexts
+	if _, err := platform.GetCurrentPlatform(context.Namespace); err != nil {
+		logrus.Info("Waiting for a integration platform to be initialized")
+		return nil
+	}
+
 	target := context.DeepCopy()
 
 	// update the status
+	logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseBuilding)
 	target.Status.Phase = v1alpha1.IntegrationContextPhaseBuilding
 	target.Status.Digest = digest.ComputeForIntegrationContext(context)
 
diff --git a/pkg/stub/action/context/monitor.go b/pkg/stub/action/context/monitor.go
index e30a1ea..f090ffb 100644
--- a/pkg/stub/action/context/monitor.go
+++ b/pkg/stub/action/context/monitor.go
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package context
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -24,29 +24,30 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// NewIntegrationContextMonitorAction creates a new monitoring handling action for the context
-func NewIntegrationContextMonitorAction() IntegrationContextAction {
-	return &integrationContextMonitorAction{}
+// NewMonitorAction creates a new monitoring handling action for the context
+func NewMonitorAction() Action {
+	return &monitorAction{}
 }
 
-type integrationContextMonitorAction struct {
+type monitorAction struct {
 }
 
-func (action *integrationContextMonitorAction) Name() string {
+func (action *monitorAction) Name() string {
 	return "monitor"
 }
 
-func (action *integrationContextMonitorAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
+func (action *monitorAction) CanHandle(context *v1alpha1.IntegrationContext) bool {
 	return context.Status.Phase == v1alpha1.IntegrationContextPhaseReady || context.Status.Phase == v1alpha1.IntegrationContextPhaseError
 }
 
-func (action *integrationContextMonitorAction) Handle(context *v1alpha1.IntegrationContext) error {
+func (action *monitorAction) Handle(context *v1alpha1.IntegrationContext) error {
 	hash := digest.ComputeForIntegrationContext(context)
 	if hash != context.Status.Digest {
 		logrus.Info("IntegrationContext ", context.Name, " needs a rebuild")
 
 		target := context.DeepCopy()
 		target.Status.Digest = hash
+		logrus.Info("Context ", target.Name, " transitioning to state ", v1alpha1.IntegrationContextPhaseBuilding)
 		target.Status.Phase = v1alpha1.IntegrationContextPhaseBuilding
 		return sdk.Update(target)
 	}
diff --git a/pkg/stub/action/integration/action.go b/pkg/stub/action/integration/action.go
index 9e4a69c..729ec5c 100644
--- a/pkg/stub/action/integration/action.go
+++ b/pkg/stub/action/integration/action.go
@@ -15,14 +15,14 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package integration
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
-// IntegrationAction --
-type IntegrationAction interface {
+// Action --
+type Action interface {
 
 	// a user friendly name for the action
 	Name() string
diff --git a/pkg/stub/action/integration/build.go b/pkg/stub/action/integration/build.go
index 20cd506..e107642 100644
--- a/pkg/stub/action/integration/build.go
+++ b/pkg/stub/action/integration/build.go
@@ -15,10 +15,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package integration
 
 import (
 	"fmt"
+	"github.com/sirupsen/logrus"
 
 	"github.com/apache/camel-k/pkg/util"
 	"github.com/apache/camel-k/pkg/util/digest"
@@ -30,7 +31,7 @@ import (
 )
 
 // NewBuildAction create an action that handles integration build
-func NewBuildAction(namespace string) IntegrationAction {
+func NewBuildAction(namespace string) Action {
 	return &buildAction{
 		namespace: namespace,
 	}
@@ -76,6 +77,7 @@ func (action *buildAction) Handle(integration *v1alpha1.Integration) error {
 			target := integration.DeepCopy()
 			target.Status.Image = ctx.Status.Image
 			target.Spec.Context = ctx.Name
+			logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseDeploying)
 			target.Status.Phase = v1alpha1.IntegrationPhaseDeploying
 			target.Status.Digest = digest.ComputeForIntegration(target)
 			return sdk.Update(target)
diff --git a/pkg/stub/action/integration/deploy.go b/pkg/stub/action/integration/deploy.go
index a679bbd..8067b3c 100644
--- a/pkg/stub/action/integration/deploy.go
+++ b/pkg/stub/action/integration/deploy.go
@@ -15,10 +15,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package integration
 
 import (
 	"fmt"
+	"github.com/sirupsen/logrus"
 	"strings"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -31,7 +32,7 @@ import (
 )
 
 // NewDeployAction create an action that handles integration deploy
-func NewDeployAction() IntegrationAction {
+func NewDeployAction() Action {
 	return &deployAction{}
 }
 
@@ -60,7 +61,11 @@ func (action *deployAction) Handle(integration *v1alpha1.Integration) error {
 		return err
 	}
 
-	return nil
+	target := integration.DeepCopy()
+	logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseRunning)
+	target.Status.Phase = v1alpha1.IntegrationPhaseRunning
+
+	return sdk.Update(target)
 }
 
 // **********************************
@@ -313,8 +318,5 @@ func createOrUpdateDeployment(ctx *v1alpha1.IntegrationContext, integration *v1a
 		return errors.Wrap(err, "could not create or replace deployment for integration "+integration.Name)
 	}
 
-	target := integration.DeepCopy()
-	target.Status.Phase = v1alpha1.IntegrationPhaseRunning
-
-	return sdk.Update(target)
+	return nil
 }
diff --git a/pkg/stub/action/integration/initialize.go b/pkg/stub/action/integration/initialize.go
index 44bac89..d9ab6c0 100644
--- a/pkg/stub/action/integration/initialize.go
+++ b/pkg/stub/action/integration/initialize.go
@@ -15,9 +15,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package integration
 
 import (
+	"github.com/apache/camel-k/pkg/platform"
+	"github.com/sirupsen/logrus"
 	"sort"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -27,7 +29,7 @@ import (
 )
 
 // NewInitializeAction creates a new inititialize action
-func NewInitializeAction() IntegrationAction {
+func NewInitializeAction() Action {
 	return &initializeAction{}
 }
 
@@ -46,6 +48,12 @@ func (action *initializeAction) CanHandle(integration *v1alpha1.Integration) boo
 
 // Handle handles the integratios
 func (action *initializeAction) Handle(integration *v1alpha1.Integration) error {
+	// The integration platform needs to be ready before starting to create integrations
+	if pl, err := platform.GetCurrentPlatform(integration.Namespace); err != nil || pl.Status.Phase != v1alpha1.IntegrationPlatformPhaseReady {
+		logrus.Info("Waiting for a integration platform to be ready")
+		return nil
+	}
+
 	target := integration.DeepCopy()
 	// set default values
 	if target.Spec.Replicas == nil {
@@ -67,6 +75,7 @@ func (action *initializeAction) Handle(integration *v1alpha1.Integration) error
 	// sort the dependencies to get always the same list if they don't change
 	sort.Strings(target.Spec.Dependencies)
 	// update the status
+	logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseBuilding)
 	target.Status.Phase = v1alpha1.IntegrationPhaseBuilding
 	target.Status.Digest = digest.ComputeForIntegration(integration)
 	return sdk.Update(target)
diff --git a/pkg/stub/action/integration/monitor.go b/pkg/stub/action/integration/monitor.go
index 483212e..ebdb420 100644
--- a/pkg/stub/action/integration/monitor.go
+++ b/pkg/stub/action/integration/monitor.go
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package integration
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -25,7 +25,7 @@ import (
 )
 
 // NewMonitorAction creates a new monitoring action for an integration
-func NewMonitorAction() IntegrationAction {
+func NewMonitorAction() Action {
 	return &monitorAction{}
 }
 
@@ -49,6 +49,7 @@ func (action *monitorAction) Handle(integration *v1alpha1.Integration) error {
 
 		target := integration.DeepCopy()
 		target.Status.Digest = hash
+		logrus.Info("Integration ", target.Name, " transitioning to state ", v1alpha1.IntegrationPhaseBuilding)
 		target.Status.Phase = v1alpha1.IntegrationPhaseBuilding
 		return sdk.Update(target)
 	}
diff --git a/pkg/stub/action/integration/util.go b/pkg/stub/action/integration/util.go
index 33c3787..ab9cf79 100644
--- a/pkg/stub/action/integration/util.go
+++ b/pkg/stub/action/integration/util.go
@@ -1,4 +1,21 @@
-package action
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package integration
 
 import (
 	"fmt"
diff --git a/pkg/stub/action/context/action.go b/pkg/stub/action/platform/action.go
similarity index 82%
copy from pkg/stub/action/context/action.go
copy to pkg/stub/action/platform/action.go
index 23b0f10..cb9ba4c 100644
--- a/pkg/stub/action/context/action.go
+++ b/pkg/stub/action/platform/action.go
@@ -15,21 +15,20 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package action
+package platform
 
 import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 )
 
-// IntegrationContextAction --
-type IntegrationContextAction interface {
-
+// Action --
+type Action interface {
 	// a user friendly name for the action
 	Name() string
 
 	// returns true if the action can handle the integration context
-	CanHandle(integration *v1alpha1.IntegrationContext) bool
+	CanHandle(platform *v1alpha1.IntegrationPlatform) bool
 
 	// executes the handling function
-	Handle(integration *v1alpha1.IntegrationContext) error
+	Handle(platform *v1alpha1.IntegrationPlatform) error
 }
diff --git a/pkg/stub/action/platform/create.go b/pkg/stub/action/platform/create.go
new file mode 100644
index 0000000..c313ccf
--- /dev/null
+++ b/pkg/stub/action/platform/create.go
@@ -0,0 +1,54 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package platform
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/install"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	"github.com/sirupsen/logrus"
+)
+
+// NewCreateAction returns a action that creates resources needed by the platform
+func NewCreateAction() Action {
+	return &createAction{}
+}
+
+type createAction struct {
+}
+
+func (action *createAction) Name() string {
+	return "create"
+}
+
+func (action *createAction) CanHandle(platform *v1alpha1.IntegrationPlatform) bool {
+	return platform.Status.Phase == v1alpha1.IntegrationPlatformPhaseCreating
+}
+
+func (action *createAction) Handle(platform *v1alpha1.IntegrationPlatform) error {
+	err := install.Resources(platform.Namespace, "platform-integration-context-core.yaml", "platform-integration-context-groovy.yaml")
+	if err != nil {
+		return err
+	}
+
+	target := platform.DeepCopy()
+	logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseStarting)
+	target.Status.Phase = v1alpha1.IntegrationPlatformPhaseStarting
+
+	return sdk.Update(target)
+}
diff --git a/pkg/stub/action/platform/initialize.go b/pkg/stub/action/platform/initialize.go
new file mode 100644
index 0000000..4215daa
--- /dev/null
+++ b/pkg/stub/action/platform/initialize.go
@@ -0,0 +1,112 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package platform
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	platformutils "github.com/apache/camel-k/pkg/platform"
+	"github.com/operator-framework/operator-sdk/pkg/k8sclient"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	"github.com/sirupsen/logrus"
+	"k8s.io/apimachinery/pkg/api/errors"
+)
+
+// NewInitializeAction returns a action that initializes the platform configuration when not provided by the user
+func NewInitializeAction() Action {
+	return &initializeAction{}
+}
+
+type initializeAction struct {
+}
+
+func (action *initializeAction) Name() string {
+	return "initialize"
+}
+
+func (action *initializeAction) CanHandle(platform *v1alpha1.IntegrationPlatform) bool {
+	return platform.Status.Phase == "" || platform.Status.Phase == v1alpha1.IntegrationPlatformPhaseDuplicate
+}
+
+func (action *initializeAction) Handle(platform *v1alpha1.IntegrationPlatform) error {
+	target := platform.DeepCopy()
+
+	duplicate, err := action.isDuplicate(platform)
+	if err != nil {
+		return err
+	}
+	if duplicate {
+		// another platform already present in the namespace
+		if platform.Status.Phase != v1alpha1.IntegrationPlatformPhaseDuplicate {
+			target := platform.DeepCopy()
+			logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseDuplicate)
+			target.Status.Phase = v1alpha1.IntegrationPlatformPhaseDuplicate
+			return sdk.Update(target)
+		}
+		return nil
+	}
+
+	// update missing fields in the resource
+	if target.Spec.Cluster == "" {
+		// determine the kind of cluster the platform in installed into
+		if openshift, err := action.isOpenshift(); err != nil {
+			return err
+		} else if openshift {
+			target.Spec.Cluster = v1alpha1.IntegrationPlatformClusterOpenShift
+		} else {
+			target.Spec.Cluster = v1alpha1.IntegrationPlatformClusterKubernetes
+		}
+	}
+
+	if target.Spec.Build.PublishStrategy == "" {
+		if target.Spec.Cluster == v1alpha1.IntegrationPlatformClusterOpenShift {
+			target.Spec.Build.PublishStrategy = v1alpha1.IntegrationPlatformBuildPublishStrategyS2I
+		} else {
+			target.Spec.Build.PublishStrategy = v1alpha1.IntegrationPlatformBuildPublishStrategyKaniko
+			// TODO discover registry location
+		}
+	}
+
+	// next status
+	logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseCreating)
+	target.Status.Phase = v1alpha1.IntegrationPlatformPhaseCreating
+	return sdk.Update(target)
+}
+
+func (action *initializeAction) isOpenshift() (bool, error) {
+	_, err := k8sclient.GetKubeClient().Discovery().ServerResourcesForGroupVersion("image.openshift.io/v1")
+	if err != nil && errors.IsNotFound(err) {
+		return false, nil
+	} else if err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+func (action *initializeAction) isDuplicate(thisPlatform *v1alpha1.IntegrationPlatform) (bool, error) {
+	platforms, err := platformutils.ListPlatforms(thisPlatform.Namespace)
+	if err != nil {
+		return false, err
+	}
+	for _, platform := range platforms.Items {
+		if platform.Name != thisPlatform.Name && platformutils.IsActive(&platform) {
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
diff --git a/pkg/stub/action/platform/start.go b/pkg/stub/action/platform/start.go
new file mode 100644
index 0000000..e56ba09
--- /dev/null
+++ b/pkg/stub/action/platform/start.go
@@ -0,0 +1,79 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package platform
+
+import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/operator-framework/operator-sdk/pkg/sdk"
+	"github.com/sirupsen/logrus"
+)
+
+// NewStartAction returns a action that waits for all required platform resources to start
+func NewStartAction() Action {
+	return &startAction{}
+}
+
+type startAction struct {
+}
+
+func (action *startAction) Name() string {
+	return "start"
+}
+
+func (action *startAction) CanHandle(platform *v1alpha1.IntegrationPlatform) bool {
+	return platform.Status.Phase == v1alpha1.IntegrationPlatformPhaseStarting || platform.Status.Phase == v1alpha1.IntegrationPlatformPhaseError
+}
+
+func (action *startAction) Handle(platform *v1alpha1.IntegrationPlatform) error {
+
+	coreStatus, err := action.getContextReady(platform.Namespace, "core")
+	if err != nil {
+		return err
+	}
+
+	groovyStatus, err := action.getContextReady(platform.Namespace, "groovy")
+	if err != nil {
+		return err
+	}
+
+	if coreStatus == v1alpha1.IntegrationContextPhaseError || groovyStatus == v1alpha1.IntegrationContextPhaseError {
+		if platform.Status.Phase != v1alpha1.IntegrationPlatformPhaseError {
+			target := platform.DeepCopy()
+			logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseError)
+			target.Status.Phase = v1alpha1.IntegrationPlatformPhaseError
+			return sdk.Update(target)
+		}
+		return nil
+	} else if coreStatus == v1alpha1.IntegrationContextPhaseReady && groovyStatus == v1alpha1.IntegrationContextPhaseReady {
+		target := platform.DeepCopy()
+		logrus.Info("Platform ", target.Name, " transitioning to state ", v1alpha1.IntegrationPlatformPhaseReady)
+		target.Status.Phase = v1alpha1.IntegrationPlatformPhaseReady
+		return sdk.Update(target)
+	}
+
+	// wait
+	return nil
+}
+
+func (action *startAction) getContextReady(namespace string, name string) (v1alpha1.IntegrationContextPhase, error) {
+	ctx := v1alpha1.NewIntegrationContext(namespace, name)
+	if err := sdk.Get(&ctx); err != nil {
+		return "", err
+	}
+	return ctx.Status.Phase, nil
+}
diff --git a/pkg/stub/handler.go b/pkg/stub/handler.go
index cb78d7b..18ae691 100644
--- a/pkg/stub/handler.go
+++ b/pkg/stub/handler.go
@@ -18,44 +18,50 @@ limitations under the License.
 package stub
 
 import (
-	"context"
-
+	ctx "context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/stub/action/platform"
 
-	caction "github.com/apache/camel-k/pkg/stub/action/context"
-	iaction "github.com/apache/camel-k/pkg/stub/action/integration"
+	"github.com/apache/camel-k/pkg/stub/action/context"
+	"github.com/apache/camel-k/pkg/stub/action/integration"
 	"github.com/operator-framework/operator-sdk/pkg/sdk"
 	"github.com/sirupsen/logrus"
 )
 
 // NewHandler --
-func NewHandler(ctx context.Context, namespace string) sdk.Handler {
+func NewHandler(ctx ctx.Context, namespace string) sdk.Handler {
 	return &handler{
-		integrationActionPool: []iaction.IntegrationAction{
-			iaction.NewInitializeAction(),
-			iaction.NewBuildAction(namespace),
-			iaction.NewDeployAction(),
-			iaction.NewMonitorAction(),
+		integrationActionPool: []integration.Action{
+			integration.NewInitializeAction(),
+			integration.NewBuildAction(namespace),
+			integration.NewDeployAction(),
+			integration.NewMonitorAction(),
+		},
+		integrationContextActionPool: []context.Action{
+			context.NewInitializeAction(),
+			context.NewBuildAction(ctx),
+			context.NewMonitorAction(),
 		},
-		integrationContextActionPool: []caction.IntegrationContextAction{
-			caction.NewIntegrationContextInitializeAction(),
-			caction.NewIntegrationContextBuildAction(ctx, namespace),
-			caction.NewIntegrationContextMonitorAction(),
+		integrationPlatformActionPool: []platform.Action{
+			platform.NewInitializeAction(),
+			platform.NewCreateAction(),
+			platform.NewStartAction(),
 		},
 	}
 }
 
 type handler struct {
-	integrationActionPool        []iaction.IntegrationAction
-	integrationContextActionPool []caction.IntegrationContextAction
+	integrationActionPool         []integration.Action
+	integrationContextActionPool  []context.Action
+	integrationPlatformActionPool []platform.Action
 }
 
-func (h *handler) Handle(ctx context.Context, event sdk.Event) error {
+func (h *handler) Handle(ctx ctx.Context, event sdk.Event) error {
 	switch o := event.Object.(type) {
 	case *v1alpha1.Integration:
 		for _, a := range h.integrationActionPool {
 			if a.CanHandle(o) {
-				logrus.Info("Invoking action ", a.Name(), " on integration ", o.Name)
+				logrus.Debug("Invoking action ", a.Name(), " on integration ", o.Name)
 				if err := a.Handle(o); err != nil {
 					return err
 				}
@@ -64,7 +70,16 @@ func (h *handler) Handle(ctx context.Context, event sdk.Event) error {
 	case *v1alpha1.IntegrationContext:
 		for _, a := range h.integrationContextActionPool {
 			if a.CanHandle(o) {
-				logrus.Info("Invoking action ", a.Name(), " on context ", o.Name)
+				logrus.Debug("Invoking action ", a.Name(), " on context ", o.Name)
+				if err := a.Handle(o); err != nil {
+					return err
+				}
+			}
+		}
+	case *v1alpha1.IntegrationPlatform:
+		for _, a := range h.integrationPlatformActionPool {
+			if a.CanHandle(o) {
+				logrus.Debug("Invoking action ", a.Name(), " on platform ", o.Name)
 				if err := a.Handle(o); err != nil {
 					return err
 				}
diff --git a/pkg/util/openshift/register.go b/pkg/util/openshift/register.go
index 83b08aa..373e42e 100644
--- a/pkg/util/openshift/register.go
+++ b/pkg/util/openshift/register.go
@@ -29,7 +29,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-// Register all Openshift types that we want to manage.
+// Register all OpenShift types that we want to manage.
 func init() {
 	k8sutil.AddToSDKScheme(addKnownTypes)
 }