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 2019/07/10 14:39:45 UTC

[camel-k] branch master updated (8d6fdda -> cc339f7)

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 8d6fdda  fix lint
     new 68df2fb  Add conditions to camel-k CRs #594
     new cc339f7  Add conditions to camel-k CRs #594 (fix PR review)

The 2 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:
 pkg/apis/camel/v1alpha1/build_types.go             |  46 +++++--
 pkg/apis/camel/v1alpha1/build_types_support.go     |  92 ++++++++++++-
 pkg/apis/camel/v1alpha1/common_types.go            |  10 ++
 pkg/apis/camel/v1alpha1/integration_types.go       |  82 ++++++++++--
 .../camel/v1alpha1/integration_types_support.go    | 147 +++++++++++++++++----
 pkg/apis/camel/v1alpha1/integrationkit_types.go    |  47 +++++--
 .../camel/v1alpha1/integrationkit_types_support.go |  97 +++++++++++++-
 .../camel/v1alpha1/integrationplatform_types.go    |  25 +++-
 .../v1alpha1/integrationplatform_types_support.go  |  77 +++++++++++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   | 102 +++++++++++++-
 pkg/cmd/describe_integration.go                    |  48 ++++++-
 pkg/controller/build/build_controller.go           |   6 +-
 pkg/controller/integration/build_kit.go            |  21 +--
 pkg/controller/integration/deploy.go               |   3 +-
 pkg/controller/integration/initialize.go           |   5 +-
 .../integration/integration_controller.go          |  19 ++-
 pkg/controller/integration/util.go                 |  20 ++-
 .../integrationkit/integrationkit_controller.go    |   6 +-
 pkg/platform/platform.go                           |  20 ++-
 pkg/trait/deployment.go                            |  27 +++-
 pkg/trait/ingress.go                               |  71 ++++++----
 pkg/trait/knative_service.go                       |  59 +++++++--
 pkg/trait/route.go                                 |  77 ++++++-----
 pkg/trait/route_test.go                            |   2 +-
 pkg/trait/service.go                               |  49 +++++--
 pkg/trait/trait_types.go                           |   7 +-
 pkg/util/indentedwriter/writer.go                  |  16 ++-
 pkg/util/kubernetes/collection.go                  |  37 ++++++
 pkg/util/kubernetes/resolver.go                    |  17 ++-
 pkg/util/kubernetes/util.go                        |  32 +++--
 30 files changed, 1061 insertions(+), 206 deletions(-)


[camel-k] 01/02: Add conditions to camel-k CRs #594

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 68df2fb0aa8668ef46e89e5c6be1381d595e7e28
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Fri Jun 21 13:12:05 2019 +0200

    Add conditions to camel-k CRs #594
---
 pkg/apis/camel/v1alpha1/build_types.go             |  46 +++++--
 pkg/apis/camel/v1alpha1/build_types_support.go     |  92 ++++++++++++-
 pkg/apis/camel/v1alpha1/common_types.go            |  10 ++
 pkg/apis/camel/v1alpha1/integration_types.go       |  82 ++++++++++--
 .../camel/v1alpha1/integration_types_support.go    | 147 +++++++++++++++++----
 pkg/apis/camel/v1alpha1/integrationkit_types.go    |  47 +++++--
 .../camel/v1alpha1/integrationkit_types_support.go |  97 +++++++++++++-
 .../camel/v1alpha1/integrationplatform_types.go    |  25 +++-
 .../v1alpha1/integrationplatform_types_support.go  |  77 +++++++++++
 pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go   | 102 +++++++++++++-
 pkg/cmd/describe_integration.go                    |  48 ++++++-
 pkg/controller/build/build_controller.go           |   6 +-
 pkg/controller/integration/build_kit.go            |  21 +--
 pkg/controller/integration/deploy.go               |   3 +-
 pkg/controller/integration/initialize.go           |   5 +-
 .../integration/integration_controller.go          |  27 +++-
 pkg/controller/integration/util.go                 |  20 ++-
 .../integrationkit/integrationkit_controller.go    |   6 +-
 pkg/platform/platform.go                           |  20 ++-
 pkg/trait/deployment.go                            |  27 +++-
 pkg/trait/ingress.go                               |  71 ++++++----
 pkg/trait/knative_service.go                       |  59 +++++++--
 pkg/trait/route.go                                 |  77 ++++++-----
 pkg/trait/route_test.go                            |   2 +-
 pkg/trait/service.go                               |  49 +++++--
 pkg/trait/trait_types.go                           |   7 +-
 pkg/util/indentedwriter/writer.go                  |  16 ++-
 pkg/util/kubernetes/collection.go                  |  37 ++++++
 pkg/util/kubernetes/resolver.go                    |  17 ++-
 pkg/util/kubernetes/util.go                        |  32 +++--
 30 files changed, 1069 insertions(+), 206 deletions(-)

diff --git a/pkg/apis/camel/v1alpha1/build_types.go b/pkg/apis/camel/v1alpha1/build_types.go
index 8f8e90a..43b4660 100644
--- a/pkg/apis/camel/v1alpha1/build_types.go
+++ b/pkg/apis/camel/v1alpha1/build_types.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1alpha1
 
 import (
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -42,16 +43,17 @@ type BuildSpec struct {
 
 // BuildStatus defines the observed state of Build
 type BuildStatus struct {
-	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
-	// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
-	Phase       BuildPhase  `json:"phase,omitempty"`
-	Image       string      `json:"image,omitempty"`
-	BaseImage   string      `json:"baseImage,omitempty"`
-	PublicImage string      `json:"publicImage,omitempty"`
-	Artifacts   []Artifact  `json:"artifacts,omitempty"`
-	Error       string      `json:"error,omitempty"`
-	Failure     *Failure    `json:"failure,omitempty"`
-	StartedAt   metav1.Time `json:"startedAt,omitempty"`
+	Phase       BuildPhase       `json:"phase,omitempty"`
+	Image       string           `json:"image,omitempty"`
+	BaseImage   string           `json:"baseImage,omitempty"`
+	PublicImage string           `json:"publicImage,omitempty"`
+	Artifacts   []Artifact       `json:"artifacts,omitempty"`
+	Error       string           `json:"error,omitempty"`
+	Failure     *Failure         `json:"failure,omitempty"`
+	StartedAt   metav1.Time      `json:"startedAt,omitempty"`
+	Platform    string           `json:"platform,omitempty"`
+	Conditions  []BuildCondition `json:"conditions,omitempty"`
+
 	// Change to Duration / ISO 8601 when CRD uses OpenAPI spec v3
 	// https://github.com/OAI/OpenAPI-Specification/issues/845
 	Duration string `json:"duration,omitempty"`
@@ -60,6 +62,9 @@ type BuildStatus struct {
 // BuildPhase --
 type BuildPhase string
 
+// BuildConditionType --
+type BuildConditionType string
+
 const (
 	// BuildKind --
 	BuildKind string = "Build"
@@ -84,6 +89,11 @@ const (
 	BuildPhaseInterrupted = "Interrupted"
 	// BuildPhaseError --
 	BuildPhaseError BuildPhase = "Error"
+
+	// BuildConditionPlatformAvailable --
+	BuildConditionPlatformAvailable BuildConditionType = "IntegrationPlatformAvailable"
+	// BuildConditionPlatformAvailableReason --
+	BuildConditionPlatformAvailableReason string = "IntegrationPlatformAvailable"
 )
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -107,6 +117,22 @@ type BuildList struct {
 	Items           []Build `json:"items"`
 }
 
+// Condition describes the state of a resource at a certain point.
+type BuildCondition struct {
+	// Type of integration condition.
+	Type BuildConditionType `json:"type"`
+	// Status of the condition, one of True, False, Unknown.
+	Status corev1.ConditionStatus `json:"status"`
+	// The last time this condition was updated.
+	LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
+	// Last time the condition transitioned from one status to another.
+	LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
+	// The reason for the condition's last transition.
+	Reason string `json:"reason,omitempty"`
+	// A human readable message indicating details about the transition.
+	Message string `json:"message,omitempty"`
+}
+
 func init() {
 	SchemeBuilder.Register(&Build{}, &BuildList{})
 }
diff --git a/pkg/apis/camel/v1alpha1/build_types_support.go b/pkg/apis/camel/v1alpha1/build_types_support.go
index a49a4aa..8aae4ad 100644
--- a/pkg/apis/camel/v1alpha1/build_types_support.go
+++ b/pkg/apis/camel/v1alpha1/build_types_support.go
@@ -17,7 +17,10 @@ limitations under the License.
 
 package v1alpha1
 
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import (
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
 
 // NewBuild --
 func NewBuild(namespace string, name string) Build {
@@ -42,3 +45,90 @@ func NewBuildList() BuildList {
 		},
 	}
 }
+
+// SetIntegrationPlatform --
+func (in *Build) SetIntegrationPlatform(platform *IntegrationPlatform) {
+	cs := corev1.ConditionTrue
+
+	if platform.Status.Phase != IntegrationPlatformPhaseReady {
+		cs = corev1.ConditionFalse
+	}
+
+	in.Status.SetCondition(BuildConditionPlatformAvailable, cs, BuildConditionPlatformAvailableReason, platform.Name)
+	in.Status.Platform = platform.Name
+}
+
+// GetCondition returns the condition with the provided type.
+func (in *BuildStatus) GetCondition(condType BuildConditionType) *BuildCondition {
+	for i := range in.Conditions {
+		c := in.Conditions[i]
+		if c.Type == condType {
+			return &c
+		}
+	}
+	return nil
+}
+
+// SetCondition --
+func (in *BuildStatus) SetCondition(condType BuildConditionType, status corev1.ConditionStatus, reason string, message string) {
+	in.SetConditions(BuildCondition{
+		Type:               condType,
+		Status:             status,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            message,
+	})
+}
+
+// SetErrorCondition --
+func (in *BuildStatus) SetErrorCondition(condType BuildConditionType, reason string, err error) {
+	in.SetConditions(BuildCondition{
+		Type:               condType,
+		Status:             corev1.ConditionFalse,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            err.Error(),
+	})
+}
+
+// SetConditions updates the resource to include the provided conditions.
+//
+// If a condition that we are about to add already exists and has the same status and
+// reason then we are not going to update.
+func (in *BuildStatus) SetConditions(conditions ...BuildCondition) {
+	for _, condition := range conditions {
+		if condition.LastUpdateTime.IsZero() {
+			condition.LastUpdateTime = metav1.Now()
+		}
+		if condition.LastTransitionTime.IsZero() {
+			condition.LastTransitionTime = metav1.Now()
+		}
+
+		currentCond := in.GetCondition(condition.Type)
+
+		if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
+			return
+		}
+		// Do not update lastTransitionTime if the status of the condition doesn't change.
+		if currentCond != nil && currentCond.Status == condition.Status {
+			condition.LastTransitionTime = currentCond.LastTransitionTime
+		}
+
+		in.RemoveCondition(condition.Type)
+		in.Conditions = append(in.Conditions, condition)
+	}
+}
+
+// RemoveCondition removes the resource condition with the provided type.
+func (in *BuildStatus) RemoveCondition(condType BuildConditionType) {
+	newConditions := in.Conditions[:0]
+	for _, c := range in.Conditions {
+		if c.Type != condType {
+			newConditions = append(newConditions, c)
+		}
+	}
+
+	in.Conditions = newConditions
+}
diff --git a/pkg/apis/camel/v1alpha1/common_types.go b/pkg/apis/camel/v1alpha1/common_types.go
index 1c57c62..cf74f69 100644
--- a/pkg/apis/camel/v1alpha1/common_types.go
+++ b/pkg/apis/camel/v1alpha1/common_types.go
@@ -59,6 +59,11 @@ type Configurable interface {
 	Configurations() []ConfigurationSpec
 }
 
+// PlatformInjectable --
+type PlatformInjectable interface {
+	SetIntegrationPlatform(platform *IntegrationPlatform)
+}
+
 // MavenSpec --
 type MavenSpec struct {
 	Settings ValueSource     `json:"settings,omitempty"`
@@ -72,3 +77,8 @@ type ValueSource struct {
 	// Selects a key of a secret.
 	SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty" `
 }
+
+const (
+	// ServiceTypeUser --
+	ServiceTypeUser = "user"
+)
diff --git a/pkg/apis/camel/v1alpha1/integration_types.go b/pkg/apis/camel/v1alpha1/integration_types.go
index f94320d..b6435af 100644
--- a/pkg/apis/camel/v1alpha1/integration_types.go
+++ b/pkg/apis/camel/v1alpha1/integration_types.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1alpha1
 
 import (
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -39,17 +40,19 @@ type IntegrationSpec struct {
 
 // IntegrationStatus defines the observed state of Integration
 type IntegrationStatus struct {
-	Phase            IntegrationPhase    `json:"phase,omitempty"`
-	Digest           string              `json:"digest,omitempty"`
-	Image            string              `json:"image,omitempty"`
-	Dependencies     []string            `json:"dependencies,omitempty"`
-	Kit              string              `json:"kit,omitempty"`
-	GeneratedSources []SourceSpec        `json:"generatedSources,omitempty"`
-	Failure          *Failure            `json:"failure,omitempty"`
-	CamelVersion     string              `json:"camelVersion,omitempty"`
-	RuntimeVersion   string              `json:"runtimeVersion,omitempty"`
-	Configuration    []ConfigurationSpec `json:"configuration,omitempty"`
-	Version          string              `json:"version,omitempty"`
+	Phase            IntegrationPhase       `json:"phase,omitempty"`
+	Digest           string                 `json:"digest,omitempty"`
+	Image            string                 `json:"image,omitempty"`
+	Dependencies     []string               `json:"dependencies,omitempty"`
+	Kit              string                 `json:"kit,omitempty"`
+	Platform         string                 `json:"platform,omitempty"`
+	GeneratedSources []SourceSpec           `json:"generatedSources,omitempty"`
+	Failure          *Failure               `json:"failure,omitempty"`
+	CamelVersion     string                 `json:"camelVersion,omitempty"`
+	RuntimeVersion   string                 `json:"runtimeVersion,omitempty"`
+	Configuration    []ConfigurationSpec    `json:"configuration,omitempty"`
+	Conditions       []IntegrationCondition `json:"conditions,omitempty"`
+	Version          string                 `json:"version,omitempty"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -139,6 +142,9 @@ var Languages = []Language{
 // IntegrationPhase --
 type IntegrationPhase string
 
+// IntegrationConditionType --
+type IntegrationConditionType string
+
 const (
 	// IntegrationKind --
 	IntegrationKind string = "Integration"
@@ -161,8 +167,62 @@ const (
 	IntegrationPhaseError IntegrationPhase = "Error"
 	// IntegrationPhaseDeleting --
 	IntegrationPhaseDeleting IntegrationPhase = "Deleting"
+
+	// IntegrationConditionKitAvailable --
+	IntegrationConditionKitAvailable IntegrationConditionType = "IntegrationKitAvailable"
+	// IntegrationConditionPlatformAvailable --
+	IntegrationConditionPlatformAvailable IntegrationConditionType = "IntegrationPlatformAvailable"
+	// IntegrationConditionDeploymentAvailable --
+	IntegrationConditionDeploymentAvailable IntegrationConditionType = "DeploymentAvailable"
+	// IntegrationConditionServiceAvailable --
+	IntegrationConditionServiceAvailable IntegrationConditionType = "ServiceAvailable"
+	// IntegrationConditionKnativeServiceAvailable --
+	IntegrationConditionKnativeServiceAvailable IntegrationConditionType = "KnativeServiceAvailable"
+	// IntegrationConditionExposureAvailable --
+	IntegrationConditionExposureAvailable IntegrationConditionType = "ExposureAvailable"
+
+	// IntegrationConditionKitAvailableReason --
+	IntegrationConditionKitAvailableReason string = "IntegrationKitAvailable"
+	// IntegrationConditionPlatformAvailableReason --
+	IntegrationConditionPlatformAvailableReason string = "IntegrationPlatformAvailable"
+	// IntegrationConditionDeploymentAvailableReason --
+	IntegrationConditionDeploymentAvailableReason string = "DeploymentAvailable"
+	// IntegrationConditionDeploymentNotAvailableReason --
+	IntegrationConditionDeploymentNotAvailableReason string = "DeploymentNotAvailable"
+	// IntegrationConditionServiceAvailableReason --
+	IntegrationConditionServiceAvailableReason string = "ServiceAvailable"
+	// IntegrationConditionServiceNotAvailableReason --
+	IntegrationConditionServiceNotAvailableReason string = "ServiceNotAvailable"
+	// IntegrationConditionRouteAvailableReason --
+	IntegrationConditionRouteAvailableReason string = "RouteAvailable"
+	// IntegrationConditionRouteNotAvailableReason --
+	IntegrationConditionRouteNotAvailableReason string = "RouteNotAvailable"
+	// IntegrationConditionIngressAvailableReason --
+	IntegrationConditionIngressAvailableReason string = "IngressAvailable"
+	// IntegrationConditionIngressNotAvailableReason --
+	IntegrationConditionIngressNotAvailableReason string = "IngressNotAvailable"
+	// IntegrationConditionKnativeServiceAvailableReason --
+	IntegrationConditionKnativeServiceAvailableReason string = "KnativeServiceAvailable"
+	// IntegrationConditionKnativeServiceNotAvailableReason --
+	IntegrationConditionKnativeServiceNotAvailableReason string = "KnativeServiceNotAvailable"
 )
 
+// IntegrationCondition describes the state of a resource at a certain point.
+type IntegrationCondition struct {
+	// Type of integration condition.
+	Type IntegrationConditionType `json:"type"`
+	// Status of the condition, one of True, False, Unknown.
+	Status corev1.ConditionStatus `json:"status"`
+	// The last time this condition was updated.
+	LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
+	// Last time the condition transitioned from one status to another.
+	LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
+	// The reason for the condition's last transition.
+	Reason string `json:"reason,omitempty"`
+	// A human readable message indicating details about the transition.
+	Message string `json:"message,omitempty"`
+}
+
 func init() {
 	SchemeBuilder.Register(&Integration{}, &IntegrationList{})
 }
diff --git a/pkg/apis/camel/v1alpha1/integration_types_support.go b/pkg/apis/camel/v1alpha1/integration_types_support.go
index e7e089c..1f72a5e 100644
--- a/pkg/apis/camel/v1alpha1/integration_types_support.go
+++ b/pkg/apis/camel/v1alpha1/integration_types_support.go
@@ -20,6 +20,7 @@ package v1alpha1
 import (
 	"strings"
 
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -57,61 +58,61 @@ func (in *Integration) Sources() []SourceSpec {
 }
 
 // AddSource --
-func (is *IntegrationSpec) AddSource(name string, content string, language Language) {
-	is.Sources = append(is.Sources, NewSourceSpec(name, content, language))
+func (in *IntegrationSpec) AddSource(name string, content string, language Language) {
+	in.Sources = append(in.Sources, NewSourceSpec(name, content, language))
 }
 
 // AddSources --
-func (is *IntegrationSpec) AddSources(sources ...SourceSpec) {
-	is.Sources = append(is.Sources, sources...)
+func (in *IntegrationSpec) AddSources(sources ...SourceSpec) {
+	in.Sources = append(in.Sources, sources...)
 }
 
 // AddResources --
-func (is *IntegrationSpec) AddResources(resources ...ResourceSpec) {
-	is.Resources = append(is.Resources, resources...)
+func (in *IntegrationSpec) AddResources(resources ...ResourceSpec) {
+	in.Resources = append(in.Resources, resources...)
 }
 
 // AddConfiguration --
-func (is *IntegrationSpec) AddConfiguration(confType string, confValue string) {
-	is.Configuration = append(is.Configuration, ConfigurationSpec{
+func (in *IntegrationSpec) AddConfiguration(confType string, confValue string) {
+	in.Configuration = append(in.Configuration, ConfigurationSpec{
 		Type:  confType,
 		Value: confValue,
 	})
 }
 
 // AddDependency --
-func (is *IntegrationSpec) AddDependency(dependency string) {
-	if is.Dependencies == nil {
-		is.Dependencies = make([]string, 0)
+func (in *IntegrationSpec) AddDependency(dependency string) {
+	if in.Dependencies == nil {
+		in.Dependencies = make([]string, 0)
 	}
 	newDep := dependency
 	if strings.HasPrefix(newDep, "camel-") {
 		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-")
 	}
-	for _, d := range is.Dependencies {
+	for _, d := range in.Dependencies {
 		if d == newDep {
 			return
 		}
 	}
-	is.Dependencies = append(is.Dependencies, newDep)
+	in.Dependencies = append(in.Dependencies, newDep)
 }
 
 // Configurations --
-func (is *IntegrationSpec) Configurations() []ConfigurationSpec {
-	if is == nil {
+func (in *IntegrationSpec) Configurations() []ConfigurationSpec {
+	if in == nil {
 		return []ConfigurationSpec{}
 	}
 
-	return is.Configuration
+	return in.Configuration
 }
 
 // Configurations --
-func (is *IntegrationStatus) Configurations() []ConfigurationSpec {
-	if is == nil {
+func (in *IntegrationStatus) Configurations() []ConfigurationSpec {
+	if in == nil {
 		return []ConfigurationSpec{}
 	}
 
-	return is.Configuration
+	return in.Configuration
 }
 
 // Configurations --
@@ -150,14 +151,114 @@ func NewResourceSpec(name string, content string, destination string, resourceTy
 }
 
 // InferLanguage returns the language of the source or discovers it from file extension if not set
-func (s SourceSpec) InferLanguage() Language {
-	if s.Language != "" {
-		return s.Language
+func (in *SourceSpec) InferLanguage() Language {
+	if in.Language != "" {
+		return in.Language
 	}
 	for _, l := range Languages {
-		if strings.HasSuffix(s.Name, "."+string(l)) {
+		if strings.HasSuffix(in.Name, "."+string(l)) {
 			return l
 		}
 	}
 	return ""
 }
+
+// SetIntegrationPlatform --
+func (in *Integration) SetIntegrationPlatform(platform *IntegrationPlatform) {
+	cs := corev1.ConditionTrue
+
+	if platform.Status.Phase != IntegrationPlatformPhaseReady {
+		cs = corev1.ConditionFalse
+	}
+
+	in.Status.SetCondition(IntegrationConditionPlatformAvailable, cs, IntegrationConditionPlatformAvailableReason, platform.Name)
+	in.Status.Platform = platform.Name
+}
+
+// SetIntegrationKit --
+func (in *Integration) SetIntegrationKit(kit *IntegrationKit) {
+	cs := corev1.ConditionTrue
+
+	if kit.Status.Phase != IntegrationKitPhaseReady {
+		cs = corev1.ConditionFalse
+	}
+
+	in.Status.SetCondition(IntegrationConditionKitAvailable, cs, IntegrationConditionKitAvailableReason, kit.Name)
+	in.Status.Kit = kit.Name
+	in.Status.Image = kit.ImageForIntegration()
+}
+
+// GetCondition returns the condition with the provided type.
+func (in *IntegrationStatus) GetCondition(condType IntegrationConditionType) *IntegrationCondition {
+	for i := range in.Conditions {
+		c := in.Conditions[i]
+		if c.Type == condType {
+			return &c
+		}
+	}
+	return nil
+}
+
+// SetCondition --
+func (in *IntegrationStatus) SetCondition(condType IntegrationConditionType, status corev1.ConditionStatus, reason string, message string) {
+	in.SetConditions(IntegrationCondition{
+		Type:               condType,
+		Status:             status,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            message,
+	})
+}
+
+// SetErrorCondition --
+func (in *IntegrationStatus) SetErrorCondition(condType IntegrationConditionType, reason string, err error) {
+	in.SetConditions(IntegrationCondition{
+		Type:               condType,
+		Status:             corev1.ConditionFalse,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            err.Error(),
+	})
+}
+
+// SetConditions updates the resource to include the provided conditions.
+//
+// If a condition that we are about to add already exists and has the same status and
+// reason then we are not going to update.
+func (in *IntegrationStatus) SetConditions(conditions ...IntegrationCondition) {
+	for _, condition := range conditions {
+		if condition.LastUpdateTime.IsZero() {
+			condition.LastUpdateTime = metav1.Now()
+		}
+		if condition.LastTransitionTime.IsZero() {
+			condition.LastTransitionTime = metav1.Now()
+		}
+
+		currentCond := in.GetCondition(condition.Type)
+
+		if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
+			return
+		}
+		// Do not update lastTransitionTime if the status of the condition doesn't change.
+		if currentCond != nil && currentCond.Status == condition.Status {
+			condition.LastTransitionTime = currentCond.LastTransitionTime
+		}
+
+		in.RemoveCondition(condition.Type)
+		in.Conditions = append(in.Conditions, condition)
+	}
+}
+
+// RemoveCondition removes the resource condition with the provided type.
+func (in *IntegrationStatus) RemoveCondition(condType IntegrationConditionType) {
+	newConditions := in.Conditions[:0]
+	for _, c := range in.Conditions {
+		if c.Type != condType {
+			newConditions = append(newConditions, c)
+		}
+	}
+
+	in.Conditions = newConditions
+}
diff --git a/pkg/apis/camel/v1alpha1/integrationkit_types.go b/pkg/apis/camel/v1alpha1/integrationkit_types.go
index f4c584f..0228859 100644
--- a/pkg/apis/camel/v1alpha1/integrationkit_types.go
+++ b/pkg/apis/camel/v1alpha1/integrationkit_types.go
@@ -17,6 +17,7 @@ limitations under the License.
 package v1alpha1
 
 import (
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -34,16 +35,18 @@ type IntegrationKitSpec struct {
 
 // IntegrationKitStatus defines the observed state of IntegrationKit
 type IntegrationKitStatus struct {
-	Phase          IntegrationKitPhase `json:"phase,omitempty"`
-	BaseImage      string              `json:"baseImage,omitempty"`
-	Image          string              `json:"image,omitempty"`
-	PublicImage    string              `json:"publicImage,omitempty"`
-	Digest         string              `json:"digest,omitempty"`
-	Artifacts      []Artifact          `json:"artifacts,omitempty"`
-	Failure        *Failure            `json:"failure,omitempty"`
-	CamelVersion   string              `json:"camelVersion,omitempty"`
-	RuntimeVersion string              `json:"runtimeVersion,omitempty"`
-	Version        string              `json:"version,omitempty"`
+	Phase          IntegrationKitPhase       `json:"phase,omitempty"`
+	BaseImage      string                    `json:"baseImage,omitempty"`
+	Image          string                    `json:"image,omitempty"`
+	PublicImage    string                    `json:"publicImage,omitempty"`
+	Digest         string                    `json:"digest,omitempty"`
+	Artifacts      []Artifact                `json:"artifacts,omitempty"`
+	Failure        *Failure                  `json:"failure,omitempty"`
+	CamelVersion   string                    `json:"camelVersion,omitempty"`
+	RuntimeVersion string                    `json:"runtimeVersion,omitempty"`
+	Platform       string                    `json:"platform,omitempty"`
+	Conditions     []IntegrationKitCondition `json:"conditions,omitempty"`
+	Version        string                    `json:"version,omitempty"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -70,6 +73,9 @@ type IntegrationKitList struct {
 // IntegrationKitPhase --
 type IntegrationKitPhase string
 
+// IntegrationKitConditionType --
+type IntegrationKitConditionType string
+
 const (
 	// IntegrationKindKind --
 	IntegrationKindKind string = "IntegrationKit"
@@ -97,8 +103,29 @@ const (
 	IntegrationKitPhaseReady IntegrationKitPhase = "Ready"
 	// IntegrationKitPhaseError --
 	IntegrationKitPhaseError IntegrationKitPhase = "Error"
+
+	// IntegrationKitConditionPlatformAvailable --
+	IntegrationKitConditionPlatformAvailable IntegrationKitConditionType = "IntegrationPlatformAvailable"
+	// IntegrationKitConditionPlatformAvailableReason --
+	IntegrationKitConditionPlatformAvailableReason string = "IntegrationPlatformAvailable"
 )
 
+// Condition describes the state of a resource at a certain point.
+type IntegrationKitCondition struct {
+	// Type of integration condition.
+	Type IntegrationKitConditionType `json:"type"`
+	// Status of the condition, one of True, False, Unknown.
+	Status corev1.ConditionStatus `json:"status"`
+	// The last time this condition was updated.
+	LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
+	// Last time the condition transitioned from one status to another.
+	LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
+	// The reason for the condition's last transition.
+	Reason string `json:"reason,omitempty"`
+	// A human readable message indicating details about the transition.
+	Message string `json:"message,omitempty"`
+}
+
 func init() {
 	SchemeBuilder.Register(&IntegrationKit{}, &IntegrationKitList{})
 }
diff --git a/pkg/apis/camel/v1alpha1/integrationkit_types_support.go b/pkg/apis/camel/v1alpha1/integrationkit_types_support.go
index 46ce1fe..558cd96 100644
--- a/pkg/apis/camel/v1alpha1/integrationkit_types_support.go
+++ b/pkg/apis/camel/v1alpha1/integrationkit_types_support.go
@@ -17,7 +17,10 @@ limitations under the License.
 
 package v1alpha1
 
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import (
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
 
 // NewIntegrationKit --
 func NewIntegrationKit(namespace string, name string) IntegrationKit {
@@ -68,3 +71,95 @@ func (in *IntegrationKit) Configurations() []ConfigurationSpec {
 
 	return in.Spec.Configuration
 }
+
+// SetIntegrationPlatform --
+func (in *IntegrationKit) SetIntegrationPlatform(platform *IntegrationPlatform) {
+	cs := corev1.ConditionTrue
+
+	if platform.Status.Phase != IntegrationPlatformPhaseReady {
+		cs = corev1.ConditionFalse
+	}
+
+	var message string
+	if platform.Name != "" {
+		message = "IntegrationPlatform (" + platform.Name + ")"
+	}
+
+	in.Status.SetCondition(IntegrationKitConditionPlatformAvailable, cs, IntegrationKitConditionPlatformAvailableReason, message)
+	in.Status.Platform = platform.Name
+}
+
+// GetCondition returns the condition with the provided type.
+func (in *IntegrationKitStatus) GetCondition(condType IntegrationKitConditionType) *IntegrationKitCondition {
+	for i := range in.Conditions {
+		c := in.Conditions[i]
+		if c.Type == condType {
+			return &c
+		}
+	}
+	return nil
+}
+
+// SetCondition --
+func (in *IntegrationKitStatus) SetCondition(condType IntegrationKitConditionType, status corev1.ConditionStatus, reason string, message string) {
+	in.SetConditions(IntegrationKitCondition{
+		Type:               condType,
+		Status:             status,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            message,
+	})
+}
+
+// SetErrorCondition --
+func (in *IntegrationKitStatus) SetErrorCondition(condType IntegrationKitConditionType, reason string, err error) {
+	in.SetConditions(IntegrationKitCondition{
+		Type:               condType,
+		Status:             corev1.ConditionFalse,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            err.Error(),
+	})
+}
+
+// SetConditions updates the resource to include the provided conditions.
+//
+// If a condition that we are about to add already exists and has the same status and
+// reason then we are not going to update.
+func (in *IntegrationKitStatus) SetConditions(conditions ...IntegrationKitCondition) {
+	for _, condition := range conditions {
+		if condition.LastUpdateTime.IsZero() {
+			condition.LastUpdateTime = metav1.Now()
+		}
+		if condition.LastTransitionTime.IsZero() {
+			condition.LastTransitionTime = metav1.Now()
+		}
+
+		currentCond := in.GetCondition(condition.Type)
+
+		if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
+			return
+		}
+		// Do not update lastTransitionTime if the status of the condition doesn't change.
+		if currentCond != nil && currentCond.Status == condition.Status {
+			condition.LastTransitionTime = currentCond.LastTransitionTime
+		}
+
+		in.RemoveCondition(condition.Type)
+		in.Conditions = append(in.Conditions, condition)
+	}
+}
+
+// RemoveCondition removes the resource condition with the provided type.
+func (in *IntegrationKitStatus) RemoveCondition(condType IntegrationKitConditionType) {
+	newConditions := in.Conditions[:0]
+	for _, c := range in.Conditions {
+		if c.Type != condType {
+			newConditions = append(newConditions, c)
+		}
+	}
+
+	in.Conditions = newConditions
+}
diff --git a/pkg/apis/camel/v1alpha1/integrationplatform_types.go b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
index e997d2c..9a1e047 100644
--- a/pkg/apis/camel/v1alpha1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1alpha1/integrationplatform_types.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1alpha1
 
 import (
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -40,8 +41,9 @@ type IntegrationPlatformResourcesSpec struct {
 
 // IntegrationPlatformStatus defines the observed state of IntegrationPlatform
 type IntegrationPlatformStatus struct {
-	Phase   IntegrationPlatformPhase `json:"phase,omitempty"`
-	Version string                   `json:"version,omitempty"`
+	Phase      IntegrationPlatformPhase       `json:"phase,omitempty"`
+	Conditions []IntegrationPlatformCondition `json:"conditions,omitempty"`
+	Version    string                         `json:"version,omitempty"`
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -137,6 +139,9 @@ const (
 // IntegrationPlatformPhase --
 type IntegrationPlatformPhase string
 
+// IntegrationPlatformConditionType --
+type IntegrationPlatformConditionType string
+
 const (
 	// IntegrationPlatformKind --
 	IntegrationPlatformKind string = "IntegrationPlatform"
@@ -153,6 +158,22 @@ const (
 	IntegrationPlatformPhaseDuplicate IntegrationPlatformPhase = "Duplicate"
 )
 
+// Condition describes the state of a resource at a certain point.
+type IntegrationPlatformCondition struct {
+	// Type of integration condition.
+	Type IntegrationPlatformConditionType `json:"type"`
+	// Status of the condition, one of True, False, Unknown.
+	Status corev1.ConditionStatus `json:"status"`
+	// The last time this condition was updated.
+	LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
+	// Last time the condition transitioned from one status to another.
+	LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
+	// The reason for the condition's last transition.
+	Reason string `json:"reason,omitempty"`
+	// A human readable message indicating details about the transition.
+	Message string `json:"message,omitempty"`
+}
+
 func init() {
 	SchemeBuilder.Register(&IntegrationPlatform{}, &IntegrationPlatformList{})
 }
diff --git a/pkg/apis/camel/v1alpha1/integrationplatform_types_support.go b/pkg/apis/camel/v1alpha1/integrationplatform_types_support.go
index a583244..ff35966 100644
--- a/pkg/apis/camel/v1alpha1/integrationplatform_types_support.go
+++ b/pkg/apis/camel/v1alpha1/integrationplatform_types_support.go
@@ -20,6 +20,7 @@ package v1alpha1
 import (
 	"strings"
 
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -74,3 +75,79 @@ func (in *IntegrationPlatform) Configurations() []ConfigurationSpec {
 
 	return in.Spec.Configuration
 }
+
+// GetCondition returns the condition with the provided type.
+func (in *IntegrationPlatformStatus) GetCondition(condType IntegrationPlatformConditionType) *IntegrationPlatformCondition {
+	for i := range in.Conditions {
+		c := in.Conditions[i]
+		if c.Type == condType {
+			return &c
+		}
+
+	}
+	return nil
+}
+
+// SetCondition --
+func (in *IntegrationPlatformStatus) SetCondition(condType IntegrationPlatformConditionType, status corev1.ConditionStatus, reason string, message string) {
+	in.SetConditions(IntegrationPlatformCondition{
+		Type:               condType,
+		Status:             status,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            message,
+	})
+}
+
+// SetErrorCondition --
+func (in *IntegrationPlatformStatus) SetErrorCondition(condType IntegrationPlatformConditionType, reason string, err error) {
+	in.SetConditions(IntegrationPlatformCondition{
+		Type:               condType,
+		Status:             corev1.ConditionFalse,
+		LastUpdateTime:     metav1.Now(),
+		LastTransitionTime: metav1.Now(),
+		Reason:             reason,
+		Message:            err.Error(),
+	})
+}
+
+// SetConditions updates the resource to include the provided conditions.
+//
+// If a condition that we are about to add already exists and has the same status and
+// reason then we are not going to update.
+func (in *IntegrationPlatformStatus) SetConditions(conditions ...IntegrationPlatformCondition) {
+	for _, condition := range conditions {
+		if condition.LastUpdateTime.IsZero() {
+			condition.LastUpdateTime = metav1.Now()
+		}
+		if condition.LastTransitionTime.IsZero() {
+			condition.LastTransitionTime = metav1.Now()
+		}
+
+		currentCond := in.GetCondition(condition.Type)
+
+		if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
+			return
+		}
+		// Do not update lastTransitionTime if the status of the condition doesn't change.
+		if currentCond != nil && currentCond.Status == condition.Status {
+			condition.LastTransitionTime = currentCond.LastTransitionTime
+		}
+
+		in.RemoveCondition(condition.Type)
+		in.Conditions = append(in.Conditions, condition)
+	}
+}
+
+// RemoveCondition removes the resource condition with the provided type.
+func (in *IntegrationPlatformStatus) RemoveCondition(condType IntegrationPlatformConditionType) {
+	newConditions := in.Conditions[:0]
+	for _, c := range in.Conditions {
+		if c.Type != condType {
+			newConditions = append(newConditions, c)
+		}
+	}
+
+	in.Conditions = newConditions
+}
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index 43e14e8..5f31fa6 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -54,6 +54,24 @@ func (in *Build) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BuildCondition) DeepCopyInto(out *BuildCondition) {
+	*out = *in
+	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
+	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuildCondition.
+func (in *BuildCondition) DeepCopy() *BuildCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(BuildCondition)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BuildList) DeepCopyInto(out *BuildList) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
@@ -138,6 +156,13 @@ func (in *BuildStatus) DeepCopyInto(out *BuildStatus) {
 		(*in).DeepCopyInto(*out)
 	}
 	in.StartedAt.DeepCopyInto(&out.StartedAt)
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]BuildCondition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 	return
 }
 
@@ -439,6 +464,24 @@ func (in *Integration) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationCondition) DeepCopyInto(out *IntegrationCondition) {
+	*out = *in
+	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
+	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationCondition.
+func (in *IntegrationCondition) DeepCopy() *IntegrationCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationCondition)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *IntegrationKit) DeepCopyInto(out *IntegrationKit) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
@@ -467,6 +510,24 @@ func (in *IntegrationKit) DeepCopyObject() runtime.Object {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationKitCondition) DeepCopyInto(out *IntegrationKitCondition) {
+	*out = *in
+	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
+	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationKitCondition.
+func (in *IntegrationKitCondition) DeepCopy() *IntegrationKitCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationKitCondition)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *IntegrationKitList) DeepCopyInto(out *IntegrationKitList) {
 	*out = *in
 	out.TypeMeta = in.TypeMeta
@@ -550,6 +611,13 @@ func (in *IntegrationKitStatus) DeepCopyInto(out *IntegrationKitStatus) {
 		*out = new(Failure)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]IntegrationKitCondition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 	return
 }
 
@@ -602,7 +670,7 @@ func (in *IntegrationPlatform) DeepCopyInto(out *IntegrationPlatform) {
 	out.TypeMeta = in.TypeMeta
 	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
 	in.Spec.DeepCopyInto(&out.Spec)
-	out.Status = in.Status
+	in.Status.DeepCopyInto(&out.Status)
 	return
 }
 
@@ -651,6 +719,24 @@ func (in *IntegrationPlatformBuildSpec) DeepCopy() *IntegrationPlatformBuildSpec
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IntegrationPlatformCondition) DeepCopyInto(out *IntegrationPlatformCondition) {
+	*out = *in
+	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
+	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationPlatformCondition.
+func (in *IntegrationPlatformCondition) DeepCopy() *IntegrationPlatformCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(IntegrationPlatformCondition)
+	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
@@ -753,6 +839,13 @@ func (in *IntegrationPlatformSpec) DeepCopy() *IntegrationPlatformSpec {
 // 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
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]IntegrationPlatformCondition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 	return
 }
 
@@ -842,6 +935,13 @@ func (in *IntegrationStatus) DeepCopyInto(out *IntegrationStatus) {
 		*out = make([]ConfigurationSpec, len(*in))
 		copy(*out, *in)
 	}
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]IntegrationCondition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 	return
 }
 
diff --git a/pkg/cmd/describe_integration.go b/pkg/cmd/describe_integration.go
index 5d70cfd..117868f 100644
--- a/pkg/cmd/describe_integration.go
+++ b/pkg/cmd/describe_integration.go
@@ -22,17 +22,18 @@ import (
 	"io"
 	"strings"
 
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/indentedwriter"
 
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/spf13/cobra"
+
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 func newDescribeIntegrationCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
 
 	impl := &describeIntegrationCommand{
-		rootCmdOptions,
+		RootCmdOptions: rootCmdOptions,
 	}
 
 	cmd := cobra.Command{
@@ -52,11 +53,14 @@ func newDescribeIntegrationCmd(rootCmdOptions *RootCmdOptions) *cobra.Command {
 		},
 	}
 
+	cmd.Flags().BoolVar(&impl.showSourceContent, "show-source-content", false, "Print source content")
+
 	return &cmd
 }
 
 type describeIntegrationCommand struct {
 	*RootCmdOptions
+	showSourceContent bool
 }
 
 func (command *describeIntegrationCommand) validate(args []string) error {
@@ -133,10 +137,42 @@ func (command *describeIntegrationCommand) describeIntegration(i v1alpha1.Integr
 
 		if len(i.Sources()) > 0 {
 			w.Write(0, "Sources:\n")
-			for _, s := range i.Sources() {
-				w.Write(1, "Name:\t%s\n", s.Name)
-				w.Write(1, "Content:\n")
-				w.Write(2, "%s\n", strings.TrimSpace(s.Content))
+			if command.showSourceContent {
+				for _, s := range i.Sources() {
+					w.Write(1, "Name:\t%s\n", s.Name)
+					w.Write(1, "Language:\t%s\n", s.InferLanguage())
+					w.Write(1, "Compression:\t%t\n", s.Compression)
+					w.Write(1, "Content:\n")
+
+					if s.ContentRef == "" {
+						w.Write(2, "%s\n", strings.TrimSpace(s.Content))
+					} else {
+						w.Write(2, "Ref:\t%s\n", s.ContentRef)
+						w.Write(2, "Ref Key:\t%s\n", s.ContentKey)
+					}
+				}
+			} else {
+				w.Write(1, "Name\tLanguage\tCompression\tRef\tRef Key\n")
+				for _, s := range i.Sources() {
+					w.Write(1, "%s\t%s\t%t\t%s\t%s\n",
+						s.Name,
+						s.InferLanguage(),
+						s.Compression,
+						s.ContentRef,
+						s.ContentKey)
+				}
+			}
+		}
+
+		if len(i.Status.Conditions) > 0 {
+			w.Write(0, "Conditions:\n")
+			w.Write(1, "Type\tStatus\tReason\tMessage\n")
+			for _, condition := range i.Status.Conditions {
+				w.Write(1, "%s\t%s\t%s\t%s\n",
+					condition.Type,
+					condition.Status,
+					condition.Reason,
+					condition.Message)
 			}
 		}
 
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index 3d6dac6..e582e96 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -167,7 +167,7 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 	targetLog := rlog.ForBuild(target)
 
 	if target.Status.Phase == v1alpha1.BuildPhaseNone || target.Status.Phase == v1alpha1.BuildPhaseWaitingForPlatform {
-		pl, err := platform.GetCurrentPlatform(ctx, r.client, target.Namespace)
+		pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
 		switch {
 		case err != nil:
 			target.Status.Phase = v1alpha1.BuildPhaseError
@@ -179,6 +179,10 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 		}
 
 		if instance.Status.Phase != target.Status.Phase {
+			if pl != nil {
+				target.SetIntegrationPlatform(pl)
+			}
+
 			return r.update(ctx, targetLog, target)
 		}
 
diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go
index 0af3d82..cff1995 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -67,22 +67,23 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1alpha1.
 				// We need to re-generate a kit or search for a new one that
 				// satisfies integrations needs so let's remove the association
 				// with a kit
-				integration.Status.Kit = ""
+				integration.SetIntegrationKit(&v1alpha1.IntegrationKit{})
+
 				return integration, nil
 			}
 		}
 
 		if kit.Status.Phase == v1alpha1.IntegrationKitPhaseError {
 			integration.Status.Image = kit.ImageForIntegration()
-			integration.Status.Kit = kit.Name
 			integration.Status.Phase = v1alpha1.IntegrationPhaseError
+			integration.SetIntegrationKit(kit)
 
 			return integration, nil
 		}
 
 		if kit.Status.Phase == v1alpha1.IntegrationKitPhaseReady {
 			integration.Status.Image = kit.ImageForIntegration()
-			integration.Status.Kit = kit.Name
+			integration.SetIntegrationKit(kit)
 
 			if _, err := trait.Apply(ctx, action.client, integration, kit); err != nil {
 				return nil, err
@@ -92,7 +93,7 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1alpha1.
 		}
 
 		if integration.Status.Kit == "" {
-			integration.Status.Kit = kit.Name
+			integration.SetIntegrationKit(kit)
 
 			return integration, nil
 		}
@@ -100,12 +101,12 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1alpha1.
 		return nil, nil
 	}
 
-	platformCtxName := fmt.Sprintf("kit-%s", xid.New())
-	platformCtx := v1alpha1.NewIntegrationKit(integration.Namespace, platformCtxName)
+	platformKitName := fmt.Sprintf("kit-%s", xid.New())
+	platformKit := v1alpha1.NewIntegrationKit(integration.Namespace, platformKitName)
 
 	// Add some information for post-processing, this may need to be refactored
 	// to a proper data structure
-	platformCtx.Labels = map[string]string{
+	platformKit.Labels = map[string]string{
 		"camel.apache.org/kit.type":               v1alpha1.IntegrationKitTypePlatform,
 		"camel.apache.org/kit.created.by.kind":    v1alpha1.IntegrationKind,
 		"camel.apache.org/kit.created.by.name":    integration.Name,
@@ -113,19 +114,19 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1alpha1.
 	}
 
 	// Set the kit to have the same characteristics as the integrations
-	platformCtx.Spec = v1alpha1.IntegrationKitSpec{
+	platformKit.Spec = v1alpha1.IntegrationKitSpec{
 		Dependencies: integration.Status.Dependencies,
 		Repositories: integration.Spec.Repositories,
 		Traits:       integration.Spec.Traits,
 	}
 
-	if err := action.client.Create(ctx, &platformCtx); err != nil {
+	if err := action.client.Create(ctx, &platformKit); err != nil {
 		return nil, err
 	}
 
 	// Set the kit name so the next handle loop, will fall through the
 	// same path as integration with a user defined kit
-	integration.Status.Kit = platformCtxName
+	integration.SetIntegrationKit(&platformKit)
 
 	return integration, nil
 }
diff --git a/pkg/controller/integration/deploy.go b/pkg/controller/integration/deploy.go
index d61e5ec..fa03160 100644
--- a/pkg/controller/integration/deploy.go
+++ b/pkg/controller/integration/deploy.go
@@ -53,7 +53,8 @@ func (action *deployAction) Handle(ctx context.Context, integration *v1alpha1.In
 		return nil, errors.Wrapf(err, "unable to find integration kit %s, %s", integration.Status.Kit, err)
 	}
 
-	if _, err := trait.Apply(ctx, action.client, integration, kit); err != nil {
+	_, err = trait.Apply(ctx, action.client, integration, kit)
+	if err != nil {
 		return nil, err
 	}
 
diff --git a/pkg/controller/integration/initialize.go b/pkg/controller/integration/initialize.go
index 325e8e8..924fc12 100644
--- a/pkg/controller/integration/initialize.go
+++ b/pkg/controller/integration/initialize.go
@@ -50,9 +50,10 @@ func (action *initializeAction) Handle(ctx context.Context, integration *v1alpha
 		return nil, err
 	}
 
+	kit := v1alpha1.NewIntegrationKit(integration.Namespace, integration.Spec.Kit)
+
 	integration.Status.Phase = v1alpha1.IntegrationPhaseBuildingKit
-	integration.Status.Kit = integration.Spec.Kit
-	integration.Status.Image = ""
+	integration.SetIntegrationKit(&kit)
 	integration.Status.Version = defaults.Version
 
 	return integration, nil
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index ef1defc..6bd6e7e 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -24,11 +24,12 @@ import (
 	"github.com/apache/camel-k/pkg/util/digest"
 
 	"k8s.io/apimachinery/pkg/api/errors"
-	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 
+	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -78,6 +79,14 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
 		UpdateFunc: func(e event.UpdateEvent) bool {
 			oldIntegration := e.ObjectOld.(*v1alpha1.Integration)
 			newIntegration := e.ObjectNew.(*v1alpha1.Integration)
+
+			if oldIntegration.Status.Phase != newIntegration.Status.Phase {
+				Log.ForIntegration(newIntegration).Info(
+					"Phase transition",
+					"old-phase", oldIntegration.Status.Phase,
+					"new-phase", newIntegration.Status.Phase,
+				)
+			}
 			// Ignore updates to the integration status in which case metadata.Generation does not change,
 			// or except when the integration phase changes as it's used to transition from one phase
 			// to another
@@ -226,16 +235,16 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 		return reconcile.Result{}, err
 	}
 
-	// Delete phase
-	if instance.GetDeletionTimestamp() != nil {
-		instance.Status.Phase = v1alpha1.IntegrationPhaseDeleting
-	}
-
 	target := instance.DeepCopy()
 	targetLog := rlog.ForIntegration(target)
 
+	// Delete phase
+	if target.GetDeletionTimestamp() != nil {
+		target.Status.Phase = v1alpha1.IntegrationPhaseDeleting
+	}
+
 	if target.Status.Phase == v1alpha1.IntegrationPhaseNone || target.Status.Phase == v1alpha1.IntegrationPhaseWaitingForPlatform {
-		pl, err := platform.GetCurrentPlatform(ctx, r.client, target.Namespace)
+		pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
 		switch {
 		case err != nil:
 			target.Status.Phase = v1alpha1.IntegrationPhaseError
@@ -247,6 +256,10 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 		}
 
 		if instance.Status.Phase != target.Status.Phase {
+			if pl != nil {
+				target.SetIntegrationPlatform(pl)
+			}
+
 			return r.update(ctx, targetLog, target)
 		}
 
diff --git a/pkg/controller/integration/util.go b/pkg/controller/integration/util.go
index 7de88d2..2c6fce0 100644
--- a/pkg/controller/integration/util.go
+++ b/pkg/controller/integration/util.go
@@ -20,12 +20,13 @@ package integration
 import (
 	"context"
 
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
 
-	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
-
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/pkg/errors"
+
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 var allowedLookupLabels = map[string]bool{
@@ -36,17 +37,12 @@ var allowedLookupLabels = map[string]bool{
 // LookupKitForIntegration --
 func LookupKitForIntegration(ctx context.Context, c k8sclient.Reader, integration *v1alpha1.Integration) (*v1alpha1.IntegrationKit, error) {
 	if integration.Status.Kit != "" {
-		name := integration.Status.Kit
-		kit := v1alpha1.NewIntegrationKit(integration.Namespace, name)
-		key := k8sclient.ObjectKey{
-			Namespace: integration.Namespace,
-			Name:      name,
-		}
-		if err := c.Get(ctx, key, &kit); err != nil {
-			return nil, errors.Wrapf(err, "unable to find integration kit %s, %s", name, err)
+		kit, err := kubernetes.GetIntegrationKit(ctx, c, integration.Status.Kit, integration.Namespace)
+		if err != nil {
+			return nil, errors.Wrapf(err, "unable to find integration kit %s, %s", integration.Status.Kit, err)
 		}
 
-		return &kit, nil
+		return kit, nil
 	}
 
 	ctxList := v1alpha1.NewIntegrationKitList()
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index fe14bc0..fd2d599 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -148,7 +148,7 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 	targetLog := rlog.ForIntegrationKit(target)
 
 	if target.Status.Phase == v1alpha1.IntegrationKitPhaseNone || target.Status.Phase == v1alpha1.IntegrationKitPhaseWaitingForPlatform {
-		pl, err := platform.GetCurrentPlatform(ctx, r.client, target.Namespace)
+		pl, err := platform.GetOrLookup(ctx, r.client, target.Namespace, target.Status.Platform)
 		switch {
 		case err != nil:
 			target.Status.Phase = v1alpha1.IntegrationKitPhaseError
@@ -160,6 +160,10 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 		}
 
 		if instance.Status.Phase != target.Status.Phase {
+			if pl != nil {
+				target.SetIntegrationPlatform(pl)
+			}
+
 			return r.update(ctx, targetLog, target)
 		}
 
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index daee58d..a8ea575 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -24,11 +24,25 @@ import (
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"github.com/apache/camel-k/pkg/client"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
 )
 
+// GetOrLookup --
+func GetOrLookup(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+	if name != "" {
+		return Get(ctx, c, namespace, name)
+	}
+
+	return GetCurrentPlatform(ctx, c, namespace)
+}
+
+// Get returns the currently installed platform
+func Get(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1alpha1.IntegrationPlatform, error) {
+	return kubernetes.GetIntegrationPlatform(ctx, c, namespace, name)
+}
+
 // GetCurrentPlatform returns the currently installed platform
-func GetCurrentPlatform(ctx context.Context, c client.Client, namespace string) (*v1alpha1.IntegrationPlatform, error) {
+func GetCurrentPlatform(ctx context.Context, c k8sclient.Reader, namespace string) (*v1alpha1.IntegrationPlatform, error) {
 	lst, err := ListPlatforms(ctx, c, namespace)
 	if err != nil {
 		return nil, err
@@ -44,7 +58,7 @@ func GetCurrentPlatform(ctx context.Context, c client.Client, namespace string)
 }
 
 // ListPlatforms returns all platforms installed in a given namespace (only one will be active)
-func ListPlatforms(ctx context.Context, c client.Client, namespace string) (*v1alpha1.IntegrationPlatformList, error) {
+func ListPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1alpha1.IntegrationPlatformList, error) {
 	lst := v1alpha1.NewIntegrationPlatformList()
 	if err := c.List(ctx, &k8sclient.ListOptions{Namespace: namespace}, &lst); err != nil {
 		return nil, err
diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index 35062ec..86bda93 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -40,6 +40,13 @@ func newDeploymentTrait() *deploymentTrait {
 
 func (t *deploymentTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionDeploymentAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionDeploymentAvailableReason,
+			"explicitly disabled",
+		)
+
 		return false, nil
 	}
 
@@ -51,6 +58,12 @@ func (t *deploymentTrait) Configure(e *Environment) (bool, error) {
 		//
 		strategy, err := e.DetermineControllerStrategy(t.ctx, t.client)
 		if err != nil {
+			e.Integration.Status.SetErrorCondition(
+				v1alpha1.IntegrationConditionDeploymentAvailable,
+				v1alpha1.IntegrationConditionDeploymentAvailableReason,
+				err,
+			)
+
 			return false, err
 		}
 
@@ -84,8 +97,18 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 	}
 
 	if e.InPhase(v1alpha1.IntegrationKitPhaseReady, v1alpha1.IntegrationPhaseDeploying) {
-		e.Resources.AddAll(e.ComputeConfigMaps())
-		e.Resources.Add(t.getDeploymentFor(e))
+		maps := e.ComputeConfigMaps()
+		depl := t.getDeploymentFor(e)
+
+		e.Resources.AddAll(maps)
+		e.Resources.Add(depl)
+
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionDeploymentAvailable,
+			corev1.ConditionTrue,
+			v1alpha1.IntegrationConditionDeploymentAvailableReason,
+			depl.Name,
+		)
 	}
 
 	return nil
diff --git a/pkg/trait/ingress.go b/pkg/trait/ingress.go
index b1184b3..8a6d68c 100644
--- a/pkg/trait/ingress.go
+++ b/pkg/trait/ingress.go
@@ -19,12 +19,15 @@ package trait
 
 import (
 	"errors"
+	"fmt"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	corev1 "k8s.io/api/core/v1"
+
 	"k8s.io/api/extensions/v1beta1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 type ingressTrait struct {
@@ -42,6 +45,12 @@ func newIngressTrait() *ingressTrait {
 
 func (t *ingressTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionExposureAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionIngressNotAvailableReason,
+			"explicitly disabled",
+		)
 		return false, nil
 	}
 
@@ -50,16 +59,30 @@ func (t *ingressTrait) Configure(e *Environment) (bool, error) {
 	}
 
 	if t.Auto == nil || *t.Auto {
-		hasService := t.getTargetService(e) != nil
+		hasService := e.Resources.GetUserServiceForIntegration(e.Integration) != nil
 		hasHost := t.Host != ""
 		enabled := hasService && hasHost
 
 		if !enabled {
+			e.Integration.Status.SetCondition(
+				v1alpha1.IntegrationConditionExposureAvailable,
+				corev1.ConditionFalse,
+				v1alpha1.IntegrationConditionIngressNotAvailableReason,
+				"no host or service defined",
+			)
+
 			return false, nil
 		}
 	}
 
 	if t.Host == "" {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionExposureAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionIngressNotAvailableReason,
+			"no host defined",
+		)
+
 		return false, errors.New("cannot Apply ingress trait: no host defined")
 	}
 
@@ -67,33 +90,11 @@ func (t *ingressTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *ingressTrait) Apply(e *Environment) error {
-	if t.Host == "" {
-		return errors.New("cannot Apply ingress trait: no host defined")
-	}
-	service := t.getTargetService(e)
+	service := e.Resources.GetUserServiceForIntegration(e.Integration)
 	if service == nil {
 		return errors.New("cannot Apply ingress trait: no target service")
 	}
 
-	e.Resources.Add(t.getIngressFor(service))
-	return nil
-}
-
-func (t *ingressTrait) getTargetService(e *Environment) (service *corev1.Service) {
-	e.Resources.VisitService(func(s *corev1.Service) {
-		if s.ObjectMeta.Labels != nil {
-			if s.ObjectMeta.Labels["camel.apache.org/integration"] == e.Integration.Name &&
-				s.ObjectMeta.Labels["camel.apache.org/service.type"] == ServiceTypeUser {
-				// We should build an ingress only on top of the user service (e.g. not if the service contains
-				// only prometheus)
-				service = s
-			}
-		}
-	})
-	return
-}
-
-func (t *ingressTrait) getIngressFor(service *corev1.Service) *v1beta1.Ingress {
 	ingress := v1beta1.Ingress{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Ingress",
@@ -115,5 +116,21 @@ func (t *ingressTrait) getIngressFor(service *corev1.Service) *v1beta1.Ingress {
 			},
 		},
 	}
-	return &ingress
+
+	e.Resources.Add(&ingress)
+
+	message := fmt.Sprintf("%s(%s) -> %s(%s)",
+		ingress.Name,
+		t.Host,
+		ingress.Spec.Backend.ServiceName,
+		ingress.Spec.Backend.ServicePort.String())
+
+	e.Integration.Status.SetCondition(
+		v1alpha1.IntegrationConditionExposureAvailable,
+		corev1.ConditionTrue,
+		v1alpha1.IntegrationConditionIngressAvailableReason,
+		message,
+	)
+
+	return nil
 }
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 0835a56..db674de 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -27,7 +27,6 @@ import (
 	"github.com/apache/camel-k/pkg/metadata"
 	"github.com/apache/camel-k/pkg/util/envvar"
 	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
-	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -59,6 +58,13 @@ func newKnativeServiceTrait() *knativeServiceTrait {
 
 func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionKnativeServiceAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionKnativeServiceNotAvailableReason,
+			"explicitly disabled",
+		)
+
 		return false, nil
 	}
 
@@ -66,22 +72,36 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
+	if e.Resources.GetDeploymentForIntegration(e.Integration) != nil {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionKnativeServiceAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionKnativeServiceNotAvailableReason,
+			"controller strategy: "+ControllerStrategyDeployment,
+		)
+
+		// A controller is already present for the integration
+		return false, nil
+	}
+
 	strategy, err := e.DetermineControllerStrategy(t.ctx, t.client)
 	if err != nil {
+		e.Integration.Status.SetErrorCondition(
+			v1alpha1.IntegrationConditionKnativeServiceAvailable,
+			v1alpha1.IntegrationConditionKnativeServiceNotAvailableReason,
+			err,
+		)
+
 		return false, err
 	}
 	if strategy != ControllerStrategyKnativeService {
-		return false, nil
-	}
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionKnativeServiceAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionKnativeServiceNotAvailableReason,
+			"controller strategy: "+string(strategy),
+		)
 
-	deployment := e.Resources.GetDeployment(func(d *appsv1.Deployment) bool {
-		if name, ok := d.ObjectMeta.Labels["camel.apache.org/integration"]; ok {
-			return name == e.Integration.Name
-		}
-		return false
-	})
-	if deployment != nil {
-		// A controller is already present for the integration
 		return false, nil
 	}
 
@@ -90,6 +110,12 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 		if t.MinScale == nil {
 			sources, err := kubernetes.ResolveIntegrationSources(t.ctx, t.client, e.Integration, e.Resources)
 			if err != nil {
+				e.Integration.Status.SetErrorCondition(
+					v1alpha1.IntegrationConditionKnativeServiceAvailable,
+					v1alpha1.IntegrationConditionKnativeServiceNotAvailableReason,
+					err,
+				)
+
 				return false, err
 			}
 
@@ -110,11 +136,18 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *knativeServiceTrait) Apply(e *Environment) error {
-	svc := t.getServiceFor(e)
+	ksvc := t.getServiceFor(e)
 	maps := e.ComputeConfigMaps()
 
-	e.Resources.Add(svc)
 	e.Resources.AddAll(maps)
+	e.Resources.Add(ksvc)
+
+	e.Integration.Status.SetCondition(
+		v1alpha1.IntegrationConditionDeploymentAvailable,
+		corev1.ConditionTrue,
+		v1alpha1.IntegrationConditionKnativeServiceAvailableReason,
+		ksvc.Name,
+	)
 
 	return nil
 }
diff --git a/pkg/trait/route.go b/pkg/trait/route.go
index 2d53872..c3eb320 100644
--- a/pkg/trait/route.go
+++ b/pkg/trait/route.go
@@ -18,6 +18,7 @@ limitations under the License.
 package trait
 
 import (
+	"fmt"
 	"reflect"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -49,6 +50,13 @@ func newRouteTrait() *routeTrait {
 
 func (t *routeTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionExposureAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionRouteNotAvailableReason,
+			"explicitly disabled",
+		)
+
 		return false, nil
 	}
 
@@ -56,8 +64,15 @@ func (t *routeTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	t.service = t.getTargetService(e)
+	t.service = e.Resources.GetUserServiceForIntegration(e.Integration)
 	if t.service == nil {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionExposureAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionRouteNotAvailableReason,
+			"no target service found",
+		)
+
 		return false, nil
 	}
 
@@ -65,41 +80,14 @@ func (t *routeTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *routeTrait) Apply(e *Environment) error {
-	if e.Integration == nil || e.Integration.Status.Phase != v1alpha1.IntegrationPhaseDeploying {
-		return nil
-	}
-
-	e.Resources.Add(t.getRouteFor(t.service))
-	return nil
-}
-
-func (t *routeTrait) getTargetService(e *Environment) *corev1.Service {
-	var service *corev1.Service
-
-	e.Resources.VisitService(func(s *corev1.Service) {
-		if s.ObjectMeta.Labels != nil {
-			if s.ObjectMeta.Labels["camel.apache.org/integration"] == e.Integration.Name &&
-				s.ObjectMeta.Labels["camel.apache.org/service.type"] == ServiceTypeUser {
-
-				// We should build a route only on top of the user service (e.g. not if the service contains
-				// only prometheus)
-				service = s
-			}
-		}
-	})
-
-	return service
-}
-
-func (t *routeTrait) getRouteFor(service *corev1.Service) *routev1.Route {
 	route := routev1.Route{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Route",
 			APIVersion: routev1.SchemeGroupVersion.String(),
 		},
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      service.Name,
-			Namespace: service.Namespace,
+			Name:      t.service.Name,
+			Namespace: t.service.Namespace,
 		},
 		Spec: routev1.RouteSpec{
 			Port: &routev1.RoutePort{
@@ -107,13 +95,38 @@ func (t *routeTrait) getRouteFor(service *corev1.Service) *routev1.Route {
 			},
 			To: routev1.RouteTargetReference{
 				Kind: "Service",
-				Name: service.Name,
+				Name: t.service.Name,
 			},
 			Host: t.Host,
 			TLS:  t.getTLSConfig(),
 		},
 	}
-	return &route
+
+	e.Resources.Add(&route)
+
+	var message string
+
+	if t.Host == "" {
+		message = fmt.Sprintf("%s -> %s(%s)",
+			route.Name,
+			route.Spec.To.Name,
+			route.Spec.Port.TargetPort.String())
+	} else {
+		message = fmt.Sprintf("%s(%s) -> %s(%s)",
+			route.Name,
+			t.Host,
+			route.Spec.To.Name,
+			route.Spec.Port.TargetPort.String())
+	}
+
+	e.Integration.Status.SetCondition(
+		v1alpha1.IntegrationConditionExposureAvailable,
+		corev1.ConditionTrue,
+		v1alpha1.IntegrationConditionRouteAvailableReason,
+		message,
+	)
+
+	return nil
 }
 
 func (t *routeTrait) getTLSConfig() *routev1.TLSConfig {
diff --git a/pkg/trait/route_test.go b/pkg/trait/route_test.go
index 48310fd..0f81683 100644
--- a/pkg/trait/route_test.go
+++ b/pkg/trait/route_test.go
@@ -81,7 +81,7 @@ func createTestRouteEnvironment(t *testing.T, name string) *Environment {
 					Namespace: "test-ns",
 					Labels: map[string]string{
 						"camel.apache.org/integration":  name,
-						"camel.apache.org/service.type": ServiceTypeUser,
+						"camel.apache.org/service.type": v1alpha1.ServiceTypeUser,
 					},
 				},
 				Spec: corev1.ServiceSpec{
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index 64f410e..3bcbcc4 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -18,10 +18,11 @@ limitations under the License.
 package trait
 
 import (
+	"fmt"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/metadata"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
-	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
@@ -51,6 +52,13 @@ func newServiceTrait() *serviceTrait {
 
 func (t *serviceTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1alpha1.IntegrationConditionServiceAvailable,
+			corev1.ConditionFalse,
+			v1alpha1.IntegrationConditionServiceNotAvailableReason,
+			"explicitly disabled",
+		)
+
 		return false, nil
 	}
 
@@ -61,10 +69,25 @@ func (t *serviceTrait) Configure(e *Environment) (bool, error) {
 	if t.Auto == nil || *t.Auto {
 		sources, err := kubernetes.ResolveIntegrationSources(t.ctx, t.client, e.Integration, e.Resources)
 		if err != nil {
+			e.Integration.Status.SetCondition(
+				v1alpha1.IntegrationConditionServiceAvailable,
+				corev1.ConditionFalse,
+				v1alpha1.IntegrationConditionServiceNotAvailableReason,
+				err.Error(),
+			)
+
 			return false, err
 		}
+
 		meta := metadata.ExtractAll(e.CamelCatalog, sources)
 		if !meta.RequiresHTTPService {
+			e.Integration.Status.SetCondition(
+				v1alpha1.IntegrationConditionServiceAvailable,
+				corev1.ConditionFalse,
+				v1alpha1.IntegrationConditionServiceNotAvailableReason,
+				"no http service required",
+			)
+
 			return false, nil
 		}
 	}
@@ -91,24 +114,34 @@ func (t *serviceTrait) Apply(e *Environment) (err error) {
 	svc.Spec.Ports = append(svc.Spec.Ports, port)
 
 	// Mark the service as a user service
-	svc.Labels["camel.apache.org/service.type"] = ServiceTypeUser
+	svc.Labels["camel.apache.org/service.type"] = v1alpha1.ServiceTypeUser
 
 	// Register a post processor to add a container port to the integration deployment
 	e.PostProcessors = append(e.PostProcessors, func(environment *Environment) error {
-		var container *corev1.Container
-		environment.Resources.VisitContainer(func(c *corev1.Container) {
-			if c.Name == environment.Integration.Name {
-				container = c
-			}
+		container := environment.Resources.GetContainer(func(c *corev1.Container) bool {
+			return c.Name == environment.Integration.Name
 		})
+
 		if container != nil {
 			container.Ports = append(container.Ports, corev1.ContainerPort{
 				Name:          t.ContainerPortName,
 				ContainerPort: int32(t.ContainerPort),
 				Protocol:      corev1.ProtocolTCP,
 			})
+
+			message := fmt.Sprintf("%s(%s/%d) -> %s(%s/%d)",
+				svc.Name, port.Name, port.Port,
+				container.Name, t.ContainerPortName, t.ContainerPort,
+			)
+
+			environment.Integration.Status.SetCondition(
+				v1alpha1.IntegrationConditionServiceAvailable,
+				corev1.ConditionTrue,
+				v1alpha1.IntegrationConditionServiceAvailableReason,
+				message,
+			)
 		} else {
-			return errors.New("Cannot add HTTP container port: no integration container")
+			return fmt.Errorf("cannot add %s container port: no integration container", t.ContainerPortName)
 		}
 		return nil
 	})
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 63b55bb..3399057 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -28,6 +28,8 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	controller "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -43,9 +45,6 @@ import (
 // True --
 const True = "true"
 
-// ServiceTypeUser --
-const ServiceTypeUser = "user"
-
 // Identifiable represent an identifiable type
 type Identifiable interface {
 	ID() ID
@@ -196,7 +195,7 @@ func (e *Environment) DetermineProfile() v1alpha1.TraitProfile {
 }
 
 // DetermineControllerStrategy determines the type of controller that should be used for the integration
-func (e *Environment) DetermineControllerStrategy(ctx context.Context, c client.Client) (ControllerStrategy, error) {
+func (e *Environment) DetermineControllerStrategy(ctx context.Context, c controller.Reader) (ControllerStrategy, error) {
 	if e.DetermineProfile() != v1alpha1.TraitProfileKnative {
 		return ControllerStrategyDeployment, nil
 	}
diff --git a/pkg/util/indentedwriter/writer.go b/pkg/util/indentedwriter/writer.go
index 99259be..cab0e8c 100644
--- a/pkg/util/indentedwriter/writer.go
+++ b/pkg/util/indentedwriter/writer.go
@@ -21,6 +21,7 @@ import (
 	"bytes"
 	"fmt"
 	"io"
+	"strings"
 	"text/tabwriter"
 )
 
@@ -41,12 +42,15 @@ func NewWriter(out io.Writer) *Writer {
 
 // Write --
 func (iw *Writer) Write(indentLevel int, format string, i ...interface{}) {
-	indent := "  "
-	prefix := ""
-	for i := 0; i < indentLevel; i++ {
-		prefix += indent
-	}
-	fmt.Fprintf(iw.out, prefix+format, i...)
+	fmt.Fprint(iw.out, strings.Repeat("  ", indentLevel))
+	fmt.Fprintf(iw.out, format, i...)
+}
+
+// Writeln --
+func (iw *Writer) Writeln(indentLevel int, format string, i ...interface{}) {
+	fmt.Fprint(iw.out, strings.Repeat("  ", indentLevel))
+	fmt.Fprintf(iw.out, format, i...)
+	fmt.Fprint(iw.out, "\n")
 }
 
 // Flush --
diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go
index 6eff785..418b2db 100644
--- a/pkg/util/kubernetes/collection.go
+++ b/pkg/util/kubernetes/collection.go
@@ -18,6 +18,7 @@ limitations under the License.
 package kubernetes
 
 import (
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
 	routev1 "github.com/openshift/api/route/v1"
 	appsv1 "k8s.io/api/apps/v1"
@@ -101,6 +102,17 @@ func (c *Collection) GetDeployment(filter func(*appsv1.Deployment) bool) *appsv1
 	return retValue
 }
 
+// GetDeploymentForIntegration returns a Deployment for the given integration
+func (c *Collection) GetDeploymentForIntegration(integration *v1alpha1.Integration) *appsv1.Deployment {
+	if integration == nil {
+		return nil
+	}
+
+	return c.GetDeployment(func(d *appsv1.Deployment) bool {
+		return d.ObjectMeta.Labels["camel.apache.org/integration"] == integration.Name
+	})
+}
+
 // HasDeployment returns true if a deployment matching the given condition is present
 func (c *Collection) HasDeployment(filter func(*appsv1.Deployment) bool) bool {
 	return c.GetDeployment(filter) != nil
@@ -174,6 +186,18 @@ func (c *Collection) GetService(filter func(*corev1.Service) bool) *corev1.Servi
 	return retValue
 }
 
+// GetUserServiceForIntegration returns a user Service for the given integration
+func (c *Collection) GetUserServiceForIntegration(integration *v1alpha1.Integration) *corev1.Service {
+	if integration == nil {
+		return nil
+	}
+	return c.GetService(func(s *corev1.Service) bool {
+		return s.ObjectMeta.Labels != nil &&
+			s.ObjectMeta.Labels["camel.apache.org/integration"] == integration.Name &&
+			s.ObjectMeta.Labels["camel.apache.org/service.type"] == v1alpha1.ServiceTypeUser
+	})
+}
+
 // GetKnativeService returns a knative Service that matches the given function
 func (c *Collection) GetKnativeService(filter func(*serving.Service) bool) *serving.Service {
 	var retValue *serving.Service
@@ -214,6 +238,19 @@ func (c *Collection) VisitKnativeService(visitor func(*serving.Service)) {
 	})
 }
 
+// GetContainer --
+func (c *Collection) GetContainer(filter func(container *corev1.Container) bool) *corev1.Container {
+	var retValue *corev1.Container
+
+	c.VisitContainer(func(container *corev1.Container) {
+		if filter(container) {
+			retValue = container
+		}
+	})
+
+	return retValue
+}
+
 // VisitContainer executes the visitor function on all Containers inside deployments or other resources
 func (c *Collection) VisitContainer(visitor func(container *corev1.Container)) {
 	c.VisitDeployment(func(d *appsv1.Deployment) {
diff --git a/pkg/util/kubernetes/resolver.go b/pkg/util/kubernetes/resolver.go
index d2ad8fc..3303409 100644
--- a/pkg/util/kubernetes/resolver.go
+++ b/pkg/util/kubernetes/resolver.go
@@ -22,8 +22,9 @@ import (
 	"fmt"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"github.com/apache/camel-k/pkg/client"
+
 	corev1 "k8s.io/api/core/v1"
+	controller "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // ResolveSources --
@@ -78,7 +79,12 @@ func Resolve(data *v1alpha1.DataSpec, mapLookup func(string) (*corev1.ConfigMap,
 }
 
 // ResolveIntegrationSources --
-func ResolveIntegrationSources(context context.Context, client client.Client, integration *v1alpha1.Integration, resources *Collection) ([]v1alpha1.SourceSpec, error) {
+func ResolveIntegrationSources(
+	context context.Context,
+	client controller.Reader,
+	integration *v1alpha1.Integration,
+	resources *Collection) ([]v1alpha1.SourceSpec, error) {
+
 	if integration == nil {
 		return nil, nil
 	}
@@ -100,7 +106,12 @@ func ResolveIntegrationSources(context context.Context, client client.Client, in
 
 // ResolveIntegrationResources --
 // nolint: lll
-func ResolveIntegrationResources(context context.Context, client client.Client, integration *v1alpha1.Integration, resources *Collection) ([]v1alpha1.ResourceSpec, error) {
+func ResolveIntegrationResources(
+	context context.Context,
+	client controller.Reader,
+	integration *v1alpha1.Integration,
+	resources *Collection) ([]v1alpha1.ResourceSpec, error) {
+
 	if integration == nil {
 		return nil, nil
 	}
diff --git a/pkg/util/kubernetes/util.go b/pkg/util/kubernetes/util.go
index 7f1df15..7b995fb 100644
--- a/pkg/util/kubernetes/util.go
+++ b/pkg/util/kubernetes/util.go
@@ -70,7 +70,7 @@ func JSONToYAML(src []byte) ([]byte, error) {
 }
 
 // GetConfigMap --
-func GetConfigMap(context context.Context, client client.Client, name string, namespace string) (*corev1.ConfigMap, error) {
+func GetConfigMap(context context.Context, client k8sclient.Reader, name string, namespace string) (*corev1.ConfigMap, error) {
 	key := k8sclient.ObjectKey{
 		Name:      name,
 		Namespace: namespace,
@@ -95,7 +95,7 @@ func GetConfigMap(context context.Context, client client.Client, name string, na
 }
 
 // GetSecret --
-func GetSecret(context context.Context, client client.Client, name string, namespace string) (*corev1.Secret, error) {
+func GetSecret(context context.Context, client k8sclient.Reader, name string, namespace string) (*corev1.Secret, error) {
 	key := k8sclient.ObjectKey{
 		Name:      name,
 		Namespace: namespace,
@@ -119,8 +119,24 @@ func GetSecret(context context.Context, client client.Client, name string, names
 	return &answer, nil
 }
 
+// GetIntegrationPlatform --
+func GetIntegrationPlatform(context context.Context, client k8sclient.Reader, name string, namespace string) (*v1alpha1.IntegrationPlatform, error) {
+	key := k8sclient.ObjectKey{
+		Name:      name,
+		Namespace: namespace,
+	}
+
+	answer := v1alpha1.NewIntegrationPlatform(namespace, name)
+
+	if err := client.Get(context, key, &answer); err != nil {
+		return nil, err
+	}
+
+	return &answer, nil
+}
+
 // GetIntegrationKit --
-func GetIntegrationKit(context context.Context, client client.Client, name string, namespace string) (*v1alpha1.IntegrationKit, error) {
+func GetIntegrationKit(context context.Context, client k8sclient.Reader, name string, namespace string) (*v1alpha1.IntegrationKit, error) {
 	key := k8sclient.ObjectKey{
 		Name:      name,
 		Namespace: namespace,
@@ -136,7 +152,7 @@ func GetIntegrationKit(context context.Context, client client.Client, name strin
 }
 
 // GetIntegration --
-func GetIntegration(context context.Context, client client.Client, name string, namespace string) (*v1alpha1.Integration, error) {
+func GetIntegration(context context.Context, client k8sclient.Reader, name string, namespace string) (*v1alpha1.Integration, error) {
 	key := k8sclient.ObjectKey{
 		Name:      name,
 		Namespace: namespace,
@@ -168,7 +184,7 @@ func GetBuild(context context.Context, client client.Client, name string, namesp
 }
 
 // GetService --
-func GetService(context context.Context, client client.Client, name string, namespace string) (*corev1.Service, error) {
+func GetService(context context.Context, client k8sclient.Reader, name string, namespace string) (*corev1.Service, error) {
 	key := k8sclient.ObjectKey{
 		Name:      name,
 		Namespace: namespace,
@@ -255,7 +271,7 @@ func LookUpResources(ctx context.Context, client client.Client, namespace string
 }
 
 // GetSecretRefValue returns the value of a secret in the supplied namespace --
-func GetSecretRefValue(ctx context.Context, client client.Client, namespace string, selector *corev1.SecretKeySelector) (string, error) {
+func GetSecretRefValue(ctx context.Context, client k8sclient.Reader, namespace string, selector *corev1.SecretKeySelector) (string, error) {
 	secret, err := GetSecret(ctx, client, selector.Name, namespace)
 	if err != nil {
 		return "", err
@@ -270,7 +286,7 @@ func GetSecretRefValue(ctx context.Context, client client.Client, namespace stri
 }
 
 // GetConfigMapRefValue returns the value of a configmap in the supplied namespace
-func GetConfigMapRefValue(ctx context.Context, client client.Client, namespace string, selector *corev1.ConfigMapKeySelector) (string, error) {
+func GetConfigMapRefValue(ctx context.Context, client k8sclient.Reader, namespace string, selector *corev1.ConfigMapKeySelector) (string, error) {
 	cm, err := GetConfigMap(ctx, client, selector.Name, namespace)
 	if err != nil {
 		return "", err
@@ -284,7 +300,7 @@ func GetConfigMapRefValue(ctx context.Context, client client.Client, namespace s
 }
 
 // ResolveValueSource --
-func ResolveValueSource(ctx context.Context, client client.Client, namespace string, valueSource *v1alpha1.ValueSource) (string, error) {
+func ResolveValueSource(ctx context.Context, client k8sclient.Reader, namespace string, valueSource *v1alpha1.ValueSource) (string, error) {
 	if valueSource.ConfigMapKeyRef != nil && valueSource.SecretKeyRef != nil {
 		return "", fmt.Errorf("value source has bot config map and secret configured")
 	}


[camel-k] 02/02: Add conditions to camel-k CRs #594 (fix PR review)

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 cc339f7d2c3d0a14f3c7c3b0bb055156b2372141
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Wed Jul 10 12:42:11 2019 +0200

    Add conditions to camel-k CRs #594 (fix PR review)
---
 pkg/controller/integration/integration_controller.go | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 6bd6e7e..641eaa3 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -79,14 +79,6 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
 		UpdateFunc: func(e event.UpdateEvent) bool {
 			oldIntegration := e.ObjectOld.(*v1alpha1.Integration)
 			newIntegration := e.ObjectNew.(*v1alpha1.Integration)
-
-			if oldIntegration.Status.Phase != newIntegration.Status.Phase {
-				Log.ForIntegration(newIntegration).Info(
-					"Phase transition",
-					"old-phase", oldIntegration.Status.Phase,
-					"new-phase", newIntegration.Status.Phase,
-				)
-			}
 			// Ignore updates to the integration status in which case metadata.Generation does not change,
 			// or except when the integration phase changes as it's used to transition from one phase
 			// to another