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 2020/02/24 13:52:45 UTC

[camel-k] branch master updated (abacac8 -> 85808ff)

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 abacac8  Fix #1286: fix tekton test
     new ba6e439  # This is a combination of 2 commits. # This is the 1st commit message:
     new d1cf15f  #1199: add events to all CRD
     new e110c42  #1199: multicasting events of dependent resources to integration
     new 9f03af2  #1199: logging status information in dev and wait mode
     new fd88d0d  #1199: add cronjob conditions
     new 622d0a7  #1199: fix lint
     new 6e994c0  1199: fix cronjob conditions and message
     new e5350d9  #1199: fix order of messages
     new 8f41cf7  Fix #1199: add old logs for cases where events are not generated
     new ba2603d  Fix #1199: add optional permission for creating events
     new 2ea6321  Fix #1199: fix lint
     new 968b48c  Fix #1233: start dev mode also when integration is already running
     new 0d61e86  Fix #1233: fix dev mode test and rebase
     new 85808ff  Fix #1199: fix builder permissions

The 14 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:
 .gitignore                                         |   3 +
 deploy/builder-role-kubernetes.yaml                |   9 +-
 deploy/builder-role-openshift.yaml                 |   9 +-
 ...ding.yaml => operator-role-binding-events.yaml} |   4 +-
 ...role-binding.yaml => operator-role-events.yaml} |  21 +-
 deploy/operator-role-olm.yaml                      |   1 +
 deploy/platform-integration-kit-groovy.yaml        |   4 +-
 deploy/platform-integration-kit-java.yaml          |   4 +-
 deploy/platform-integration-kit-js.yaml            |   4 +-
 deploy/platform-integration-kit-knative.yaml       |   4 +-
 deploy/platform-integration-kit-kotlin.yaml        |   4 +-
 deploy/platform-integration-kit-main.yaml          |   4 +-
 deploy/platform-integration-kit-xml.yaml           |   4 +-
 deploy/platform-integration-kit-yaml.yaml          |   4 +-
 deploy/resources.go                                |  60 +++--
 e2e/dev_mode_test.go                               |   5 +-
 helm/camel-k/templates/operator-role.yaml          |   1 +
 pkg/apis/camel/v1/build_types_support.go           |  41 ++++
 pkg/apis/camel/v1/common_types.go                  |  10 +
 pkg/apis/camel/v1/integration_types.go             |   6 +
 pkg/apis/camel/v1/integration_types_support.go     |  51 ++++-
 pkg/apis/camel/v1/integrationkit_types_support.go  |  41 ++++
 pkg/apis/camel/v1/integrationplatform_types.go     |   2 +
 .../camel/v1/integrationplatform_types_support.go  |  41 ++++
 pkg/builder/s2i/publisher.go                       |   4 +
 pkg/cmd/install.go                                 |  24 +-
 pkg/cmd/operator/operator.go                       |  32 ++-
 pkg/cmd/reset.go                                   |   2 +-
 pkg/cmd/run.go                                     |  29 +--
 pkg/controller/build/build_controller.go           |  19 +-
 pkg/controller/build/schedule_pod.go               |   3 +
 pkg/controller/integration/build_kit.go            |  12 +-
 .../integration/integration_controller.go          |  19 +-
 pkg/controller/integrationkit/build.go             |   1 +
 .../integrationkit/integrationkit_controller.go    |  19 +-
 .../integrationplatform_controller.go              |  15 +-
 pkg/event/manager.go                               | 245 +++++++++++++++++++++
 pkg/install/operator.go                            |  17 ++
 pkg/metadata/metadata.go                           |   2 +-
 pkg/trait/cron.go                                  |  40 ++++
 pkg/trait/deployment.go                            |   4 +-
 pkg/trait/deployment_test.go                       |   2 +-
 pkg/trait/knative_service.go                       |   7 +-
 pkg/trait/rest-dsl.go                              |   2 +-
 pkg/{ => util}/gzip/compress.go                    |   0
 pkg/{ => util}/gzip/compress_test.go               |   0
 pkg/util/kubernetes/camel_labels.go                |  74 +++++++
 pkg/util/kubernetes/permission.go                  |  54 +++++
 pkg/util/olm/operator.go                           |  36 +--
 pkg/util/watch/watch.go                            | 170 +++++++++++++-
 50 files changed, 1007 insertions(+), 162 deletions(-)
 copy deploy/{operator-role-binding.yaml => operator-role-binding-events.yaml} (94%)
 copy deploy/{builder-role-binding.yaml => operator-role-events.yaml} (84%)
 create mode 100644 pkg/event/manager.go
 rename pkg/{ => util}/gzip/compress.go (100%)
 rename pkg/{ => util}/gzip/compress_test.go (100%)
 create mode 100644 pkg/util/kubernetes/camel_labels.go
 create mode 100644 pkg/util/kubernetes/permission.go


[camel-k] 09/14: Fix #1199: add old logs for cases where events are not generated

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 8f41cf794d678dc99e61be83a698eb29677c4180
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Fri Feb 21 10:58:33 2020 +0100

    Fix #1199: add old logs for cases where events are not generated
---
 pkg/cmd/run.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index e6dee28..35e43e0 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -303,6 +303,10 @@ func (o *runCmdOptions) waitForIntegrationReady(cmd *cobra.Command, integration
 		//
 		// TODO when we add health checks, we should Wait until they are passed
 		//
+		if i.Status.Phase != "" {
+			// TODO remove this log when we make sure that events are always created
+			fmt.Printf("progress: integration %q in phase %s\n", integration.Name, string(i.Status.Phase))
+		}
 		if i.Status.Phase == v1.IntegrationPhaseRunning || i.Status.Phase == v1.IntegrationPhaseError {
 			return false
 		}


[camel-k] 10/14: Fix #1199: add optional permission for creating events

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 ba2603da84ce40b61cdf7e1d05ca04ad19ec60c2
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Fri Feb 21 11:41:35 2020 +0100

    Fix #1199: add optional permission for creating events
---
 deploy/operator-role-binding-events.yaml           | 30 +++++++
 ...e-kubernetes.yaml => operator-role-events.yaml} | 91 +---------------------
 deploy/operator-role-kubernetes.yaml               |  1 -
 deploy/operator-role-openshift.yaml                |  1 -
 deploy/resources.go                                | 68 +++++++++-------
 helm/camel-k/templates/operator-role.yaml          |  1 +
 pkg/cmd/operator/operator.go                       | 17 +++-
 pkg/install/operator.go                            | 13 ++++
 pkg/util/kubernetes/permission.go                  | 54 +++++++++++++
 pkg/util/olm/operator.go                           | 36 +--------
 10 files changed, 159 insertions(+), 153 deletions(-)

diff --git a/deploy/operator-role-binding-events.yaml b/deploy/operator-role-binding-events.yaml
new file mode 100644
index 0000000..dbbb3a7
--- /dev/null
+++ b/deploy/operator-role-binding-events.yaml
@@ -0,0 +1,30 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+  name: camel-k-operator-events
+  labels:
+    app: "camel-k"
+subjects:
+- kind: ServiceAccount
+  name: camel-k-operator
+roleRef:
+  kind: Role
+  name: camel-k-operator-events
+  apiGroup: rbac.authorization.k8s.io
diff --git a/deploy/operator-role-kubernetes.yaml b/deploy/operator-role-events.yaml
similarity index 50%
copy from deploy/operator-role-kubernetes.yaml
copy to deploy/operator-role-events.yaml
index bca4878..5fc8fab 100644
--- a/deploy/operator-role-kubernetes.yaml
+++ b/deploy/operator-role-events.yaml
@@ -18,50 +18,11 @@
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
-  name: camel-k-operator
+  name: camel-k-operator-events
   labels:
     app: "camel-k"
 rules:
 - apiGroups:
-  - camel.apache.org
-  resources:
-  - "*"
-  verbs:
-  - "*"
-- apiGroups:
-  - ""
-  resources:
-  - pods
-  - services
-  - endpoints
-  - persistentvolumeclaims
-  - configmaps
-  - secrets
-  - serviceaccounts
-  verbs:
-  - create
-  - delete
-  - deletecollection
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
-  - rbac.authorization.k8s.io
-  resources:
-  - roles
-  - rolebindings
-  verbs:
-  - create
-  - delete
-  - deletecollection
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
   - ""
   resources:
   - events
@@ -70,53 +31,3 @@ rules:
   - get
   - list
   - watch
-- apiGroups:
-  - apps
-  resources:
-  - deployments
-  - replicasets
-  - statefulsets
-  verbs:
-  - create
-  - delete
-  - deletecollection
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
-  - batch
-  resources:
-  - cronjobs
-  verbs:
-  - create
-  - delete
-  - deletecollection
-  - get
-  - list
-  - patch
-  - update
-  - watch
-- apiGroups:
-  - apps
-  attributeRestrictions: null
-  resources:
-  - daemonsets
-  verbs:
-  - get
-  - list
-  - watch
-- apiGroups:
-  - extensions
-  resources:
-  - ingresses
-  verbs:
-  - create
-  - delete
-  - deletecollection
-  - get
-  - list
-  - patch
-  - update
-  - watch
diff --git a/deploy/operator-role-kubernetes.yaml b/deploy/operator-role-kubernetes.yaml
index bca4878..4e9db4c 100644
--- a/deploy/operator-role-kubernetes.yaml
+++ b/deploy/operator-role-kubernetes.yaml
@@ -66,7 +66,6 @@ rules:
   resources:
   - events
   verbs:
-  - create
   - get
   - list
   - watch
diff --git a/deploy/operator-role-openshift.yaml b/deploy/operator-role-openshift.yaml
index 46ea8c5..9da5132 100644
--- a/deploy/operator-role-openshift.yaml
+++ b/deploy/operator-role-openshift.yaml
@@ -66,7 +66,6 @@ rules:
   resources:
   - events
   verbs:
-  - create
   - get
   - list
   - watch
diff --git a/deploy/resources.go b/deploy/resources.go
index 8719462..518327e 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -70,16 +70,16 @@ var assets = func() http.FileSystem {
 		"/builder-role-kubernetes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-role-kubernetes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1387,
+			uncompressedSize: 1467,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x4d\x73\xdb\x36\x10\xbd\xe3\x57\xbc\x21\x2f\x49\xc7\x92\x9a\x9e\x3a\xea\x49\x75\xec\x96\xd3\x8c\x34\x63\x2a\xcd\xe4\x08\x82\x2b\x72\xc7\x20\x80\x2e\x40\x33\xee\xaf\xef\x80\x94\x1a\xb9\xbe\xf4\x60\x5c\xb4\x80\x16\xef\x03\x6f\xa5\x12\xab\xb7\x5b\xaa\xc4\x27\x36\xe4\x22\xb5\x48\x1e\xa9\x27\xec\x82\x36\x3d\xa1\xf6\xa7\x34\x69\x21\xdc\xfb\xd1\xb5\x3a\xb1\x77\x78\xb7\xab\xef\xdf\x63\x74\x2d\x09\xbc\x23\x78\xc1\xe0\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x41\x8f\xdb\x36\x17\xbc\xf3\x57\x0c\xa4\x4b\xf2\x61\x2d\x7f\xe9\xa9\x70\x4f\xee\x66\xb7\x15\x1a\xd8\xc0\xca\x69\x90\x23\x45\x3e\x4b\x0f\x4b\x91\x2c\x49\xad\xb2\xfd\xf5\x05\x69\xbb\xf1\x76\x11\xa0\x05\xc2\x8b\x1f\xe9\xe1\xbc\x19\xce\xb3\x6b\xac\xbe\xdf\x12\x35\x3e\xb0\x22\x1b\x49\x23\x39\xa4\x91\xb0\xf5\x52\x8d\x84\xce\x1d\xd3\x22\x03\xe1\xde\xcd\x56\xcb\xc4\xce\xe2\xcd\xb6\xbb\x7f\x8b\xd9\x6a\x0a\x70\x96\xe0\x [...]
 		},
 		"/builder-role-openshift.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-role-openshift.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 2052,
+			uncompressedSize: 2132,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\x41\x8f\xdb\x36\x13\xbd\xf3\x57\x3c\x48\x97\xe4\xc3\x5a\xfe\xd2\x53\xe1\x9e\xdc\xcd\x6e\x6b\x34\xb0\x81\x95\xd3\x20\xc7\x91\x34\x96\x06\x4b\x91\x2c\x49\xad\xb2\xfd\xf5\x85\x28\xbb\x6b\xc7\x69\xda\x43\x80\xe8\xe2\xd1\x70\x38\xef\xbd\x79\x63\xe5\x58\x7c\xbb\x47\xe5\x78\x27\x35\x9b\xc0\x0d\xa2\x45\xec\x18\x6b\x47\x75\xc7\x28\xed\x21\x8e\xe4\x19\xf7\x76\x30\x0d\x45\xb1\x06\xaf\xd6\xe5\xfd\x6b\x0c\xa6\x61\x0f\x6b\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xa4\x4b\x52\xac\xe5\xa6\xa7\xc2\x3d\xb9\x9b\xdd\xd6\x68\x60\x03\x2b\xa7\x41\x8e\x23\x69\x2c\x0d\x96\x22\x59\x92\x5a\xc5\xfd\xfa\x42\xb4\xdd\xb5\xe3\xa4\x4d\x80\x00\xd1\xc5\xa3\xe1\xf0\xcd\x7b\xf3\xc6\xca\x31\xfb\x76\x8f\xca\xf1\x46\x6a\x36\x81\x1b\x44\x8b\xd8\x31\x96\x8e\xea\x8e\x51\xda\x5d\x1c\xc9\x33\xee\xed\x60\x1a\x8a\x62\x0d\x5e\x2c\xcb\xfb\x97\x18\x4c\xc3\x1e\xd6\x30\x [...]
 		},
 		"/builder-service-account.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-service-account.yaml",
@@ -151,6 +151,13 @@ var assets = func() http.FileSystem {
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x2e\x10\xdb\xc9\x1e\xd5\x93\xea\x38\x88\xd1\x54\x36\x2c\x6f\x83\x3d\x15\x13\x6a\x24\x11\xa1\x48\x95\xa4\xa2\xd5\xdf\x17\x94\xed\xc4\xce\x66\xd3\x1e\x82\xe5\xc9\xe6\xcc\xbc\x79\x6f\xde\x88\x31\xa6\x1f\x77\xa2\x18\x77\x52\xb0\x76\x5c\xc0\x1b\xf8\x9a\x91\xb6\x24\x6a\x46\x6e\x4a\xdf\x93\x65\xdc\x98\x4e\x17\xe4\xa5\xd1\xf8\x94\xe6\x37\x9f\xd1\xe9\x82\x2d\x8c\x66\x18\x8b\x [...]
 		},
+		"/operator-role-binding-events.yaml": &vfsgen۰CompressedFileInfo{
+			name:             "operator-role-binding-events.yaml",
+			modTime:          time.Time{},
+			uncompressedSize: 1224,
+
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x93\x41\x6f\xdb\x46\x10\x85\xef\xfb\x2b\x1e\xc4\x4b\x02\x58\x54\xd3\x53\xa1\x9e\x18\xc7\x6e\x89\x06\x12\x20\x2a\x0d\x72\x1c\x2e\x47\xe4\xd4\xe4\x0e\xbb\xbb\x34\xe3\xfe\xfa\x62\x29\xa9\x76\x50\xb4\xc8\xc1\x7b\x13\x34\x7c\xf3\xbd\x7d\x6f\x33\xac\x5f\xef\x98\x0c\x1f\xc5\xb2\x0b\xdc\x20\x2a\x62\xc7\x28\x46\xb2\x1d\xa3\xd2\x53\x9c\xc9\x33\xee\x75\x72\x0d\x45\x51\x87\x37\x45\x75\xff\x16\x93\x6b\xd8\x43\x1d\x43\x3d\x06\x [...]
+		},
 		"/operator-role-binding-knative.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-binding-knative.yaml",
 			modTime:          time.Time{},
@@ -165,6 +172,13 @@ var assets = func() http.FileSystem {
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x93\x41\x6f\xdb\x46\x10\x85\xef\xfb\x2b\x1e\xc4\x4b\x02\x58\x54\xd3\x53\xa1\x9e\x18\xc7\x6e\x89\x06\x12\x20\x2a\x0d\x72\x1c\x2e\x47\xe4\xd4\xe4\x0e\xbb\xbb\x34\xe3\xfe\xfa\x62\x29\xa9\x76\x50\x24\x27\xef\x8d\xe0\xf0\xcd\xf7\xf6\x3d\x66\x58\xbf\xde\x31\x19\x3e\x8a\x65\x17\xb8\x41\x54\xc4\x8e\x51\x8c\x64\x3b\x46\xa5\xa7\x38\x93\x67\xdc\xeb\xe4\x1a\x8a\xa2\x0e\x6f\x8a\xea\xfe\x2d\x26\xd7\xb0\x87\x3a\x86\x7a\x0c\xea\x [...]
 		},
+		"/operator-role-events.yaml": &vfsgen۰CompressedFileInfo{
+			name:             "operator-role-events.yaml",
+			modTime:          time.Time{},
+			uncompressedSize: 1165,
+
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xac\x4b\x02\xac\xe5\xa6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\x63\x69\x2c\x0d\x56\xe2\xa8\x43\x6a\x15\xf7\xeb\x0b\xca\x72\xb2\x41\xae\xe1\x45\x14\xf5\xf4\xe6\xbd\x79\xc3\x0c\xeb\x9f\xb7\x5c\x86\x0f\x52\xb1\x0f\x5c\x23\x2a\x62\xcb\xd8\x0d\x54\xb5\x8c\x52\xcf\x71\x22\x63\x3c\xea\xe8\x6b\x8a\xa2\x1e\x6f\x76\xe5\xe3\x5b\x8c\xbe\x66\x83\x7a\x86\x1a\x7a\x35\x76\x [...]
+		},
 		"/operator-role-knative.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-knative.yaml",
 			modTime:          time.Time{},
@@ -175,23 +189,23 @@ var assets = func() http.FileSystem {
 		"/operator-role-kubernetes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-kubernetes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 2249,
+			uncompressedSize: 2260,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x6e\x1b\x37\x10\xbd\xf3\x2b\x1e\xb4\x97\xa4\xb0\xe4\xa6\xa7\x42\x3d\xa9\x8e\xdd\x0a\x0d\x24\xc0\xab\x34\xc8\x71\x96\x3b\x5a\xb1\xe6\x72\x58\x92\x2b\xd9\xfd\xfa\x82\xd4\x2a\x91\xa3\x04\xe8\x21\xa8\xf7\xa2\x21\x77\xf6\xcd\x9b\xf7\x46\x53\x61\xfa\xfd\x1e\x55\xe1\x9d\xd1\xec\x22\xb7\x48\x82\xb4\x63\x2c\x3c\xe9\x1d\xa3\x96\x6d\x3a\x50\x60\xdc\xc9\xe0\x5a\x4a\x46\x1c\x5e\x2d\xea\xbb\xd7\x18\x5c\xcb\x01\xe2\x18\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\x41\x73\xdb\x36\x13\xbd\xe3\x57\xbc\x11\x2f\xc9\x37\x96\xfc\xa5\xa7\x8e\x7a\x52\x1d\xbb\xd5\x34\x23\xcd\x98\x4a\x33\x39\x2e\xc1\x15\x85\x1a\xc4\xa2\x00\x28\xd9\xfd\xf5\x1d\x40\x54\x22\x47\x49\xa7\x87\x4c\xcd\x8b\x16\xe0\xf2\xed\xdb\xf7\x56\x5b\x61\xfa\xfd\x1e\x55\xe1\x9d\xd1\xec\x22\xb7\x48\x82\xb4\x63\x2c\x3c\xe9\x1d\xa3\x96\x6d\x3a\x50\x60\xdc\xc9\xe0\x5a\x4a\x46\x1c\x5e\x2d\xea\xbb\xd7\x18\x5c\xcb\x01\xe2\x [...]
 		},
 		"/operator-role-olm.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-olm.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 3530,
+			uncompressedSize: 3541,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x51\x8f\xda\x46\x10\x7e\xf7\xaf\x18\xe1\x97\xa4\x3a\x4c\xd3\xa7\x8a\x3e\xd1\xcb\x5d\x8b\x1a\x81\x74\x90\x46\x79\x1c\xaf\x07\x7b\xca\x7a\x67\xbb\xbb\x86\xa3\xbf\xbe\xf2\xda\x24\xe6\x7c\xa7\x4b\xa5\x54\xf0\xc2\x7a\x76\xf8\xe6\x9b\xef\x1b\x06\x52\x98\x7e\xbf\x57\x92\xc2\x07\x56\x64\x3c\x15\x10\x04\x42\x45\xb0\xb0\xa8\x2a\x82\x8d\xec\xc2\x11\x1d\xc1\xbd\x34\xa6\xc0\xc0\x62\xe0\xcd\x62\x73\xff\x16\x1a\x53\x90\x03\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x41\x93\xda\x46\x13\xbd\xeb\x57\x74\xa1\x8b\xfd\xd5\x22\x3e\xe7\x94\x22\x27\xb2\xde\x4d\xa8\xb8\xa0\x6a\xc1\x71\xf9\xd8\x1a\x35\x52\x87\xd1\xf4\x64\x66\x04\x4b\x7e\x7d\x4a\x23\x61\x8b\xd5\x6e\xd6\xa9\x72\x0a\x2e\x8c\x7a\x9a\xd7\xaf\xdf\x6b\x1a\x52\x98\x7e\xbf\x57\x92\xc2\x07\x56\x64\x3c\x15\x10\x04\x42\x45\xb0\xb0\xa8\x2a\x82\x8d\xec\xc2\x11\x1d\xc1\xbd\x34\xa6\xc0\xc0\x62\xe0\xcd\x62\x73\xff\x16\x1a\x53\x90\x [...]
 		},
 		"/operator-role-openshift.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-openshift.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 3028,
+			uncompressedSize: 3039,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x08\xe9\x92\x14\x6b\xb9\xe9\xa9\x70\x4f\x6e\xb2\xdb\x1a\x0d\xbc\xc0\xca\x69\x90\x23\x35\xa2\x25\x76\x47\xc3\xe9\xcc\xc8\x8a\xfb\xf5\x85\x46\x72\x62\xaf\x76\x91\x16\x08\x60\x5f\x4c\x71\xa8\xc7\xc7\xf7\xa8\xc9\x60\xf1\xfd\x7e\x49\x06\xef\x59\x91\xf1\x54\x41\x10\x08\x0d\xc1\xda\xa2\x6a\x08\x0a\xd9\x87\x1e\x1d\xc1\x9d\x74\xa6\xc2\xc0\x62\xe0\xd5\xba\xb8\x7b\x0d\x9d\xa9\xc8\x81\x18\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x08\xe9\x92\x14\x6b\xbb\xe9\xa9\x70\x4f\xee\x66\xb7\x35\x1a\xd8\xc0\xca\x69\x90\x23\x35\xa2\x25\x76\x47\xc3\xe9\xcc\xc8\x8a\xfb\xf5\x85\x46\x72\x62\xaf\x76\x9b\x06\x08\x60\x5f\x4c\x71\xa8\xc7\xc7\xf7\xa8\xc9\x60\xf6\xfd\x7e\x49\x06\xef\x58\x91\xf1\x54\x42\x10\x08\x35\xc1\xca\xa2\xaa\x09\x72\xd9\x87\x0e\x1d\xc1\xbd\xb4\xa6\xc4\xc0\x62\xe0\xd5\x2a\xbf\x7f\x0d\xad\x29\xc9\x81\x18\x [...]
 		},
 		"/operator-service-account.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-service-account.yaml",
@@ -217,58 +231,58 @@ var assets = func() http.FileSystem {
 		"/platform-integration-kit-groovy.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-groovy.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1318,
+			uncompressedSize: 1310,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xee\xc9\xdd\xec\xa2\x42\x02\x1b\x58\x39\x0d\x72\x1c\x8b\x63\x79\x60\x89\x64\x87\xd4\x2a\xfe\xf7\x05\x25\xbb\x71\x90\x43\x72\x08\x6f\x12\x67\xde\xc7\xbc\x61\x81\xe5\xaf\x3b\xa6\xc0\x07\x69\xd8\x45\xb6\x48\x1e\xe9\xc4\xd8\x04\x6a\x4e\x8c\xda\x1f\xd3\x48\xca\x78\xf6\x83\xb3\x94\xc4\x3b\xbc\xd9\xd4\xcf\x6f\x31\x38\xcb\x0a\xef\x18\x5e\xd1\x7b\x65\x53\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xee\xc9\xdd\xec\xa2\x42\x02\x1b\x58\x39\x0d\x72\x1c\x8b\x63\x79\x60\x89\x64\x87\xd4\x2a\xfe\xf7\x05\x25\xbb\x71\x10\xa0\xcd\x21\xbc\x49\x9c\x79\x1f\xf3\x86\x05\x96\x3f\xef\x98\x02\x1f\xa4\x61\x17\xd9\x22\x79\xa4\x13\x63\x13\xa8\x39\x31\x6a\x7f\x4c\x23\x29\xe3\xd9\x0f\xce\x52\x12\xef\xf0\x66\x53\x3f\xbf\xc5\xe0\x2c\x2b\xbc\x63\x78\x45\xef\x95\x4d\x [...]
 		},
 		"/platform-integration-kit-java.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-java.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1314,
+			uncompressedSize: 1306,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\xb0\xe5\xb6\x47\xf5\xe4\x6e\x6c\x54\x48\x60\x03\x2b\xa7\x41\x8e\x63\x71\x2c\x4d\x2d\x91\x2c\x49\x59\xf1\xbf\x2f\x28\xdb\x8d\x17\x7b\xe8\x1e\x96\x37\x51\x33\xef\x63\xde\x30\xc3\xe2\xfd\x8e\xca\xf0\x45\x6a\x36\x81\x35\xa2\x45\x6c\x19\x2b\x47\x75\xcb\xa8\xec\x31\x8e\xe4\x19\x1b\x3b\x18\x4d\x51\xac\xc1\x87\x55\xb5\xf9\x88\xc1\x68\xf6\xb0\x86\x61\x3d\x7a\xeb\x59\x65\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\xb0\xe5\xb6\x47\xf5\xe4\x6e\x6c\x54\x48\x60\x03\x2b\xa7\x41\x8e\x63\x71\x2c\x4d\x2d\x91\x2c\x49\x59\xf1\xbf\x2f\x28\xdb\x5d\x2f\x16\x68\x7b\x58\xde\x44\xcd\xbc\x8f\x79\xc3\x0c\x8b\xf7\x3b\x2a\xc3\x17\xa9\xd9\x04\xd6\x88\x16\xb1\x65\xac\x1c\xd5\x2d\xa3\xb2\xc7\x38\x92\x67\x6c\xec\x60\x34\x45\xb1\x06\x1f\x56\xd5\xe6\x23\x06\xa3\xd9\xc3\x1a\x86\xf5\xe8\xad\x67\x95\x [...]
 		},
 		"/platform-integration-kit-js.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-js.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1310,
+			uncompressedSize: 1302,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\xb0\xe5\xb6\x47\xf5\xe4\x6e\x6c\x54\x48\x60\x03\x2b\xa7\x41\x8e\x63\x71\x2c\x4d\x2c\x91\x2c\x49\xad\xe2\x7f\x5f\x50\xb6\xbb\x5e\xec\x21\x7b\x58\xde\x44\xcd\xbc\x8f\x79\xc3\x0c\x8b\xf7\x3b\x2a\xc3\x17\xa9\xd9\x04\xd6\x88\x16\xb1\x65\xac\x1c\xd5\x2d\xa3\xb2\xc7\x38\x92\x67\x6c\xec\x60\x34\x45\xb1\x06\x1f\x56\xd5\xe6\x23\x06\xa3\xd9\xc3\x1a\x86\xf5\xe8\xad\x67\x95\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\xb0\xe5\xb6\x47\xf5\xe4\x6e\x6c\x54\x48\x60\x03\x2b\xa7\x41\x8e\x63\x71\x2c\x4d\x2c\x91\x2c\x49\xad\xd6\xff\xbe\xa0\x6c\x77\xbd\x58\xa0\xcd\x61\x79\x13\x35\xf3\x3e\xe6\x0d\x33\x2c\xde\xef\xa8\x0c\x5f\xa4\x66\x13\x58\x23\x5a\xc4\x96\xb1\x72\x54\xb7\x8c\xca\x1e\xe3\x48\x9e\xb1\xb1\x83\xd1\x14\xc5\x1a\x7c\x58\x55\x9b\x8f\x18\x8c\x66\x0f\x6b\x18\xd6\xa3\xb7\x9e\x55\x [...]
 		},
 		"/platform-integration-kit-knative.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-knative.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1321,
+			uncompressedSize: 1313,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcd\xce\xdb\x36\x10\xbc\xf3\x29\x06\xd6\x25\x01\x6c\xb9\xed\x51\x3d\xb9\x5f\x6c\x54\x48\x60\x03\x9f\x9c\x06\x39\xae\xc5\xb5\xb4\xb0\x44\xb2\x24\x65\xc5\x6f\x5f\x50\x96\x1b\x07\x39\xb4\x01\xc2\x9b\xc4\xdd\xf9\xd9\x59\x66\x58\xfd\xbc\xa3\x32\x7c\x90\x9a\x4d\x60\x8d\x68\x11\x5b\xc6\xc6\x51\xdd\x32\x2a\x7b\x8e\x23\x79\xc6\xce\x0e\x46\x53\x14\x6b\xf0\x66\x53\xed\xde\x62\x30\x9a\x3d\xac\x61\x58\x8f\xde\x7a\x56\x19\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcd\xce\xdb\x36\x10\xbc\xf3\x29\x06\xd6\x25\x01\x6c\xb9\xed\x51\x3d\xb9\x5f\x6c\x54\x48\x60\x03\x9f\x9c\x06\x39\xae\xc5\xb5\xb4\xb0\x44\xb2\x24\x65\xc5\x6f\x5f\x50\x96\x1b\x07\x01\x5a\x04\x08\x6f\x12\x77\xe7\x67\x67\x99\x61\xf5\xf3\x8e\xca\xf0\x41\x6a\x36\x81\x35\xa2\x45\x6c\x19\x1b\x47\x75\xcb\xa8\xec\x39\x8e\xe4\x19\x3b\x3b\x18\x4d\x51\xac\xc1\x9b\x4d\xb5\x7b\x8b\xc1\x68\xf6\xb0\x86\x61\x3d\x7a\xeb\x59\x65\x [...]
 		},
 		"/platform-integration-kit-kotlin.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-kotlin.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1318,
+			uncompressedSize: 1310,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xec\xa2\x42\x02\x1b\x58\x39\x0d\x72\x1c\x8b\x63\x69\x60\x8a\x64\x49\x6a\x15\xff\xfb\x82\x92\xdd\x38\xc8\x21\x39\x84\x37\x89\x33\xef\x63\xde\xb0\xc0\xfa\xd7\x1d\x55\xe0\x83\xb4\x6c\x23\x6b\x24\x87\xd4\x33\xb6\x9e\xda\x9e\xd1\xb8\x53\x9a\x28\x30\x9e\xdd\x68\x35\x25\x71\x16\x6f\xb6\xcd\xf3\x5b\x8c\x56\x73\x80\xb3\x0c\x17\x30\xb8\xc0\xaa\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xec\xa2\x42\x02\x1b\x58\x39\x0d\x72\x1c\x8b\x63\x69\x60\x8a\x64\x49\x6a\x15\xff\xfb\x82\x92\xdd\x38\x08\xd0\xe6\x10\xde\x24\xce\xbc\x8f\x79\xc3\x02\xeb\x9f\x77\x54\x81\x0f\xd2\xb2\x8d\xac\x91\x1c\x52\xcf\xd8\x7a\x6a\x7b\x46\xe3\x4e\x69\xa2\xc0\x78\x76\xa3\xd5\x94\xc4\x59\xbc\xd9\x36\xcf\x6f\x31\x5a\xcd\x01\xce\x32\x5c\xc0\xe0\x02\xab\x [...]
 		},
 		"/platform-integration-kit-main.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-main.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1265,
+			uncompressedSize: 1257,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xe3\x36\x10\xbd\xf3\x57\x3c\x58\x97\x5d\xc0\x96\xdb\x1e\xd5\x93\x9b\xb5\x51\x61\x17\x36\x10\x79\x1b\xe4\x38\x16\xc7\xd2\xc0\x12\xc9\x92\x54\x14\xff\xfb\x82\xb2\xdd\x38\xc8\xa1\x3d\x84\x37\x51\x33\xef\x63\xde\x30\xc3\xe2\xf3\x8e\xca\xf0\x43\x6a\x36\x81\x35\xa2\x45\x6c\x19\x2b\x47\x75\xcb\xa8\xec\x31\x8e\xe4\x19\x1b\x3b\x18\x4d\x51\xac\xc1\x97\x55\xb5\xf9\x8a\xc1\x68\xf6\xb0\x86\x61\x3d\x7a\xeb\x59\x65\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xe3\x36\x10\xbd\xf3\x57\x3c\x58\x97\x5d\xc0\x96\xdb\x1e\xd5\x93\x9b\xb5\x51\x61\x17\x36\x10\x79\x1b\xe4\x38\x16\xc7\xd2\xc0\x12\xc9\x92\x54\x14\xff\xfb\x82\xb2\xdd\x38\x08\xd0\x5e\xc2\x9b\xa8\xe1\xfb\xe0\x7b\xcc\xb0\xf8\xbc\xa5\x32\xfc\x90\x9a\x4d\x60\x8d\x68\x11\x5b\xc6\xca\x51\xdd\x32\x2a\x7b\x8c\x23\x79\xc6\xc6\x0e\x46\x53\x14\x6b\xf0\x65\x55\x6d\xbe\x62\x30\x9a\x3d\xac\x61\x58\x8f\xde\x7a\x56\x19\x [...]
 		},
 		"/platform-integration-kit-xml.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-xml.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1311,
+			uncompressedSize: 1303,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xac\x51\x21\x81\x0d\xac\x9c\x06\x39\x8e\xc5\xb1\x34\x35\x45\xb2\x24\xb5\x5a\xff\xfb\x82\xb2\xdd\x38\xc8\xa1\x39\x2c\x6f\xa2\x66\xde\xc7\xbc\x61\x81\xe5\xdb\x1d\x55\xe0\x93\xb4\x6c\x23\x6b\x24\x87\xd4\x33\xd6\x9e\xda\x9e\xd1\xb8\x63\x9a\x28\x30\x36\x6e\xb4\x9a\x92\x38\x8b\x77\xeb\x66\xf3\x1e\xa3\xd5\x1c\xe0\x2c\xc3\x05\x0c\x2e\xb0\x2a\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xac\x51\x21\x81\x0d\xac\x9c\x06\x39\x8e\xc5\xb1\x34\x35\x45\xb2\x24\xb5\x5a\xff\xfb\x82\xb2\xdd\x38\x08\xd0\xf6\xb0\xbc\x89\x9a\x79\x1f\xf3\x86\x05\x96\x6f\x77\x54\x81\x4f\xd2\xb2\x8d\xac\x91\x1c\x52\xcf\x58\x7b\x6a\x7b\x46\xe3\x8e\x69\xa2\xc0\xd8\xb8\xd1\x6a\x4a\xe2\x2c\xde\xad\x9b\xcd\x7b\x8c\x56\x73\x80\xb3\x0c\x17\x30\xb8\xc0\xaa\x [...]
 		},
 		"/platform-integration-kit-yaml.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "platform-integration-kit-yaml.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1314,
+			uncompressedSize: 1306,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xd8\xa8\x90\xc0\x06\x56\x4e\x83\x1c\xc7\xe2\x58\x1a\x98\x22\x59\x92\x5a\xc5\xff\xbe\xa0\x6c\x37\x0e\x72\x48\x0e\xe1\x4d\xd4\xcc\xfb\x98\x37\x2c\xb0\xfc\x75\x47\x15\xf8\x20\x2d\xdb\xc8\x1a\xc9\x21\xf5\x8c\xb5\xa7\xb6\x67\x34\xee\x94\x26\x0a\x8c\xad\x1b\xad\xa6\x24\xce\xe2\xcd\xba\xd9\xbe\xc5\x68\x35\x07\x38\xcb\x70\x01\x83\x0b\xac\x0a\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x58\x97\x04\x58\xcb\x6d\x8f\xea\xc9\xdd\xd8\xa8\x90\xc0\x06\x56\x4e\x83\x1c\xc7\xe2\x58\x1a\x98\x22\x59\x92\x5a\xc5\xff\xbe\xa0\x6c\x37\x0e\x02\xb4\x39\x84\x37\x51\x33\xef\x63\xde\xb0\xc0\xf2\xe7\x1d\x55\xe0\x83\xb4\x6c\x23\x6b\x24\x87\xd4\x33\xd6\x9e\xda\x9e\xd1\xb8\x53\x9a\x28\x30\xb6\x6e\xb4\x9a\x92\x38\x8b\x37\xeb\x66\xfb\x16\xa3\xd5\x1c\xe0\x2c\xc3\x05\x0c\x2e\xb0\x2a\x [...]
 		},
 		"/prometheus-jmx-exporter.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "prometheus-jmx-exporter.yaml",
@@ -346,8 +360,10 @@ var assets = func() http.FileSystem {
 		fs["/crd-integration-platform.yaml"].(os.FileInfo),
 		fs["/crd-integration.yaml"].(os.FileInfo),
 		fs["/operator-deployment.yaml"].(os.FileInfo),
+		fs["/operator-role-binding-events.yaml"].(os.FileInfo),
 		fs["/operator-role-binding-knative.yaml"].(os.FileInfo),
 		fs["/operator-role-binding.yaml"].(os.FileInfo),
+		fs["/operator-role-events.yaml"].(os.FileInfo),
 		fs["/operator-role-knative.yaml"].(os.FileInfo),
 		fs["/operator-role-kubernetes.yaml"].(os.FileInfo),
 		fs["/operator-role-olm.yaml"].(os.FileInfo),
diff --git a/helm/camel-k/templates/operator-role.yaml b/helm/camel-k/templates/operator-role.yaml
index a9d6c6a..5a9218a 100644
--- a/helm/camel-k/templates/operator-role.yaml
+++ b/helm/camel-k/templates/operator-role.yaml
@@ -67,6 +67,7 @@ rules:
   resources:
   - events
   verbs:
+  - create
   - get
   - list
   - watch
diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index 012179f..1347e1d 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -27,10 +27,12 @@ import (
 	"time"
 
 	"github.com/apache/camel-k/pkg/client"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
 	"github.com/operator-framework/operator-sdk/pkg/leader"
 	"github.com/operator-framework/operator-sdk/pkg/ready"
 	sdkVersion "github.com/operator-framework/operator-sdk/version"
+	corev1 "k8s.io/api/core/v1"
 	typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
 	"k8s.io/client-go/tools/record"
 
@@ -109,9 +111,18 @@ func Run() {
 		log.Error(err, "cannot initialize client")
 		os.Exit(1)
 	}
-	eventBroadcaster := record.NewBroadcaster()
-	//eventBroadcaster.StartLogging(camellog.WithName("events").Infof)
-	eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: c.CoreV1().Events(namespace)})
+
+	// Configure event broadcaster
+	var eventBroadcaster record.EventBroadcaster
+	if ok, err := kubernetes.CheckPermission(c, corev1.GroupName, "events", namespace, "", "create"); err != nil {
+		log.Error(err, "cannot check permissions for configuring event broadcaster")
+	} else if !ok {
+		log.Info("Event broadcasting to Kubernetes is disabled because of missing permissions to create events")
+	} else {
+		eventBroadcaster = record.NewBroadcaster()
+		//eventBroadcaster.StartLogging(camellog.WithName("events").Infof)
+		eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: c.CoreV1().Events(namespace)})
+	}
 
 	// Create a new Cmd to provide shared dependencies and start components
 	mgr, err := manager.New(cfg, manager.Options{
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index e61f13f..28a2a58 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -20,6 +20,7 @@ package install
 import (
 	"context"
 	"errors"
+	"fmt"
 	"strings"
 
 	appsv1 "k8s.io/api/apps/v1"
@@ -124,6 +125,11 @@ func OperatorOrCollect(ctx context.Context, c client.Client, cfg OperatorConfigu
 	if isKnative {
 		return installKnative(ctx, c, cfg.Namespace, customizer, collection, force)
 	}
+
+	if errevt := installEvents(ctx, c, cfg.Namespace, customizer, collection); errevt != nil {
+		fmt.Println("Warning: the operator will not be able to publish Kubernetes events. Try installing as cluster-admin to allow it to generate events.")
+	}
+
 	return nil
 }
 
@@ -152,6 +158,13 @@ func installKnative(ctx context.Context, c client.Client, namespace string, cust
 	)
 }
 
+func installEvents(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection) error {
+	return ResourcesOrCollect(ctx, c, namespace, collection, customizer,
+		"operator-role-events.yaml",
+		"operator-role-binding-events.yaml",
+	)
+}
+
 // Platform installs the platform custom resource
 // nolint: lll
 func Platform(ctx context.Context, c client.Client, clusterType string, namespace string, registry v1.IntegrationPlatformRegistrySpec) (*v1.IntegrationPlatform, error) {
diff --git a/pkg/util/kubernetes/permission.go b/pkg/util/kubernetes/permission.go
new file mode 100644
index 0000000..e72be7d
--- /dev/null
+++ b/pkg/util/kubernetes/permission.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 kubernetes
+
+import (
+	"github.com/apache/camel-k/pkg/client"
+	authorizationv1 "k8s.io/api/authorization/v1"
+	k8serrors "k8s.io/apimachinery/pkg/api/errors"
+)
+
+// CheckPermission can be used to check if the current user/service-account is allowed to execute a given operation
+// in the cluster.
+// E.g. checkPermission(client, olmv1alpha1.GroupName, "clusterserviceversions", namespace, "camel-k", "get")
+//
+// nolint:unparam
+func CheckPermission(client client.Client, group, resource, namespace, name, verb string) (bool, error) {
+	sarReview := &authorizationv1.SelfSubjectAccessReview{
+		Spec: authorizationv1.SelfSubjectAccessReviewSpec{
+			ResourceAttributes: &authorizationv1.ResourceAttributes{
+				Group:     group,
+				Resource:  resource,
+				Namespace: namespace,
+				Name:      name,
+				Verb:      verb,
+			},
+		},
+	}
+
+	sar, err := client.AuthorizationV1().SelfSubjectAccessReviews().Create(sarReview)
+	if err != nil {
+		if k8serrors.IsForbidden(err) {
+			return false, nil
+		}
+		return false, err
+	} else if !sar.Status.Allowed {
+		return false, nil
+	}
+	return true, nil
+}
diff --git a/pkg/util/olm/operator.go b/pkg/util/olm/operator.go
index a85c414..e6ce7e7 100644
--- a/pkg/util/olm/operator.go
+++ b/pkg/util/olm/operator.go
@@ -27,8 +27,6 @@ import (
 	olmv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1"
 	olmv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
 	"github.com/pkg/errors"
-	authorizationv1 "k8s.io/api/authorization/v1"
-	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	runtime "sigs.k8s.io/controller-runtime/pkg/client"
 )
@@ -89,7 +87,7 @@ func IsOperatorInstalled(ctx context.Context, client client.Client, namespace st
 
 // HasPermissionToInstall checks if the current user/serviceaccount has the right permissions to install camel k via OLM
 func HasPermissionToInstall(ctx context.Context, client client.Client, namespace string, global bool, options Options) (bool, error) {
-	if ok, err := checkPermission(client, olmv1alpha1.GroupName, "clusterserviceversions", namespace, options.Package, "list"); err != nil {
+	if ok, err := kubernetes.CheckPermission(client, olmv1alpha1.GroupName, "clusterserviceversions", namespace, options.Package, "list"); err != nil {
 		return false, err
 	} else if !ok {
 		return false, nil
@@ -100,7 +98,7 @@ func HasPermissionToInstall(ctx context.Context, client client.Client, namespace
 		targetNamespace = options.GlobalNamespace
 	}
 
-	if ok, err := checkPermission(client, olmv1alpha1.GroupName, "subscriptions", targetNamespace, options.Package, "create"); err != nil {
+	if ok, err := kubernetes.CheckPermission(client, olmv1alpha1.GroupName, "subscriptions", targetNamespace, options.Package, "create"); err != nil {
 		return false, err
 	} else if !ok {
 		return false, nil
@@ -113,7 +111,7 @@ func HasPermissionToInstall(ctx context.Context, client client.Client, namespace
 	}
 
 	if !global {
-		if ok, err := checkPermission(client, olmv1.GroupName, "operatorgroups", namespace, options.Package, "list"); err != nil {
+		if ok, err := kubernetes.CheckPermission(client, olmv1.GroupName, "operatorgroups", namespace, options.Package, "list"); err != nil {
 			return false, err
 		} else if !ok {
 			return false, nil
@@ -124,7 +122,7 @@ func HasPermissionToInstall(ctx context.Context, client client.Client, namespace
 			return false, err
 		}
 		if group == nil {
-			if ok, err := checkPermission(client, olmv1.GroupName, "operatorgroups", namespace, options.Package, "create"); err != nil {
+			if ok, err := kubernetes.CheckPermission(client, olmv1.GroupName, "operatorgroups", namespace, options.Package, "create"); err != nil {
 				return false, err
 			} else if !ok {
 				return false, nil
@@ -135,32 +133,6 @@ func HasPermissionToInstall(ctx context.Context, client client.Client, namespace
 	return true, nil
 }
 
-// nolint:unparam
-func checkPermission(client client.Client, group, resource, namespace, name, verb string) (bool, error) {
-	sarReview := &authorizationv1.SelfSubjectAccessReview{
-		Spec: authorizationv1.SelfSubjectAccessReviewSpec{
-			ResourceAttributes: &authorizationv1.ResourceAttributes{
-				Group:     group,
-				Resource:  resource,
-				Namespace: namespace,
-				Name:      name,
-				Verb:      verb,
-			},
-		},
-	}
-
-	sar, err := client.AuthorizationV1().SelfSubjectAccessReviews().Create(sarReview)
-	if err != nil {
-		if k8serrors.IsForbidden(err) {
-			return false, nil
-		}
-		return false, err
-	} else if !sar.Status.Allowed {
-		return false, nil
-	}
-	return true, nil
-}
-
 // Install creates a subscription for the OLM package
 func Install(ctx context.Context, client client.Client, namespace string, global bool, options Options, collection *kubernetes.Collection) (bool, error) {
 	options = fillDefaults(options)


[camel-k] 08/14: #1199: fix order of messages

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 e5350d900ba91b2e288ca041d52af7cce134e105
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Jan 28 01:47:48 2020 +0100

    #1199: fix order of messages
---
 pkg/event/manager.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pkg/event/manager.go b/pkg/event/manager.go
index 6b85b4c..c773c23 100644
--- a/pkg/event/manager.go
+++ b/pkg/event/manager.go
@@ -87,10 +87,10 @@ func NotifyIntegrationUpdated(ctx context.Context, c client.Client, recorder rec
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration", new.Name, ReasonIntegrationPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration", new.Name, ReasonIntegrationConditionChanged)
 	}
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration", new.Name, ReasonIntegrationPhaseUpdated)
 }
 
 // NotifyIntegrationKitUpdated automatically generates events when an integration kit changes
@@ -104,10 +104,10 @@ func NotifyIntegrationKitUpdated(ctx context.Context, c client.Client, recorder
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Kit", new.Name, ReasonIntegrationKitPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationKitPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Kit", new.Name, ReasonIntegrationKitConditionChanged)
 	}
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Kit", new.Name, ReasonIntegrationKitPhaseUpdated)
 }
 
 // NotifyIntegrationKitError automatically generates error events when the integration kit reconcile cycle phase has an error
@@ -133,10 +133,10 @@ func NotifyIntegrationPlatformUpdated(ctx context.Context, c client.Client, reco
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Platform", new.Name, ReasonIntegrationPlatformPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationPlatformPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Platform", new.Name, ReasonIntegrationPlatformConditionChanged)
 	}
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Platform", new.Name, ReasonIntegrationPlatformPhaseUpdated)
 }
 
 // NotifyIntegrationPlatformError automatically generates error events when the integration Platform reconcile cycle phase has an error
@@ -162,10 +162,10 @@ func NotifyBuildUpdated(ctx context.Context, c client.Client, recorder record.Ev
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Build", new.Name, ReasonBuildPhaseUpdated)
 	if new.Status.Phase != v1.BuildPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Build", new.Name, ReasonBuildConditionChanged)
 	}
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Build", new.Name, ReasonBuildPhaseUpdated)
 }
 
 // NotifyBuildError automatically generates error events when the build reconcile cycle phase has an error


[camel-k] 13/14: Fix #1233: fix dev mode test and rebase

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 0d61e86d5aabb86fd018a993975ea562d8c6fd08
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Sat Feb 22 10:14:02 2020 +0100

    Fix #1233: fix dev mode test and rebase
---
 deploy/resources.go     |  8 ++++----
 e2e/dev_mode_test.go    |  4 ++--
 pkg/cmd/run.go          |  2 +-
 pkg/install/operator.go | 10 +++++++---
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/deploy/resources.go b/deploy/resources.go
index 518327e..77c6542 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -189,9 +189,9 @@ var assets = func() http.FileSystem {
 		"/operator-role-kubernetes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-kubernetes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 2260,
+			uncompressedSize: 2249,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\x41\x73\xdb\x36\x13\xbd\xe3\x57\xbc\x11\x2f\xc9\x37\x96\xfc\xa5\xa7\x8e\x7a\x52\x1d\xbb\xd5\x34\x23\xcd\x98\x4a\x33\x39\x2e\xc1\x15\x85\x1a\xc4\xa2\x00\x28\xd9\xfd\xf5\x1d\x40\x54\x22\x47\x49\xa7\x87\x4c\xcd\x8b\x16\xe0\xf2\xed\xdb\xf7\x56\x5b\x61\xfa\xfd\x1e\x55\xe1\x9d\xd1\xec\x22\xb7\x48\x82\xb4\x63\x2c\x3c\xe9\x1d\xa3\x96\x6d\x3a\x50\x60\xdc\xc9\xe0\x5a\x4a\x46\x1c\x5e\x2d\xea\xbb\xd7\x18\x5c\xcb\x01\xe2\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x6e\x1b\x37\x10\xbd\xf3\x2b\x1e\xb4\x97\xa4\xb0\xe4\xa6\xa7\x42\x3d\xa9\x8e\xdd\x0a\x0d\x24\xc0\xab\x34\xc8\x71\x96\x3b\x5a\xb1\xe6\x72\x58\x92\x2b\xd9\xfd\xfa\x82\xd4\x2a\x91\xa3\x04\xe8\x21\xa8\xf7\xa2\x21\x77\xf6\xcd\x9b\xf7\x46\x53\x61\xfa\xfd\x1e\x55\xe1\x9d\xd1\xec\x22\xb7\x48\x82\xb4\x63\x2c\x3c\xe9\x1d\xa3\x96\x6d\x3a\x50\x60\xdc\xc9\xe0\x5a\x4a\x46\x1c\x5e\x2d\xea\xbb\xd7\x18\x5c\xcb\x01\xe2\x18\x [...]
 		},
 		"/operator-role-olm.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-olm.yaml",
@@ -203,9 +203,9 @@ var assets = func() http.FileSystem {
 		"/operator-role-openshift.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-role-openshift.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 3039,
+			uncompressedSize: 3028,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x08\xe9\x92\x14\x6b\xbb\xe9\xa9\x70\x4f\xee\x66\xb7\x35\x1a\xd8\xc0\xca\x69\x90\x23\x35\xa2\x25\x76\x47\xc3\xe9\xcc\xc8\x8a\xfb\xf5\x85\x46\x72\x62\xaf\x76\x9b\x06\x08\x60\x5f\x4c\x71\xa8\xc7\xc7\xf7\xa8\xc9\x60\xf6\xfd\x7e\x49\x06\xef\x58\x91\xf1\x54\x42\x10\x08\x35\xc1\xca\xa2\xaa\x09\x72\xd9\x87\x0e\x1d\xc1\xbd\xb4\xa6\xc4\xc0\x62\xe0\xd5\x2a\xbf\x7f\x0d\xad\x29\xc9\x81\x18\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x08\xe9\x92\x14\x6b\xb9\xe9\xa9\x70\x4f\x6e\xb2\xdb\x1a\x0d\xbc\xc0\xca\x69\x90\x23\x35\xa2\x25\x76\x47\xc3\xe9\xcc\xc8\x8a\xfb\xf5\x85\x46\x72\x62\xaf\x76\x91\x16\x08\x60\x5f\x4c\x71\xa8\xc7\xc7\xf7\xa8\xc9\x60\xf1\xfd\x7e\x49\x06\xef\x59\x91\xf1\x54\x41\x10\x08\x0d\xc1\xda\xa2\x6a\x08\x0a\xd9\x87\x1e\x1d\xc1\x9d\x74\xa6\xc2\xc0\x62\xe0\xd5\xba\xb8\x7b\x0d\x9d\xa9\xc8\x81\x18\x [...]
 		},
 		"/operator-service-account.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "operator-service-account.yaml",
diff --git a/e2e/dev_mode_test.go b/e2e/dev_mode_test.go
index a028917..2b42ea7 100644
--- a/e2e/dev_mode_test.go
+++ b/e2e/dev_mode_test.go
@@ -48,11 +48,11 @@ func TestRunDevMode(t *testing.T) {
 			kamelRun := kamelWithContext(ctx, "run", "-n", ns, file, "--dev")
 			kamelRun.SetOut(pipew)
 
-			logScanner := util.NewLogScanner(ctx, piper, "Integration yaml in phase Running", "Magicstring!", "Magicjordan!")
+			logScanner := util.NewLogScanner(ctx, piper, `integration "yaml" in phase Running`, "Magicstring!", "Magicjordan!")
 
 			go kamelRun.Execute()
 
-			Eventually(logScanner.IsFound("Integration yaml in phase Running"), 5*time.Minute).Should(BeTrue())
+			Eventually(logScanner.IsFound(`integration "yaml" in phase Running`), 5*time.Minute).Should(BeTrue())
 			Eventually(logScanner.IsFound("Magicstring!"), 3*time.Minute).Should(BeTrue())
 			Expect(logScanner.IsFound("Magicjordan!")()).To(BeFalse())
 
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 35e43e0..3755b6c 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -305,7 +305,7 @@ func (o *runCmdOptions) waitForIntegrationReady(cmd *cobra.Command, integration
 		//
 		if i.Status.Phase != "" {
 			// TODO remove this log when we make sure that events are always created
-			fmt.Printf("progress: integration %q in phase %s\n", integration.Name, string(i.Status.Phase))
+			fmt.Fprintf(cmd.OutOrStdout(), "Progress: integration %q in phase %s\n", integration.Name, string(i.Status.Phase))
 		}
 		if i.Status.Phase == v1.IntegrationPhaseRunning || i.Status.Phase == v1.IntegrationPhaseError {
 			return false
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 28a2a58..9d3d3f4 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -25,6 +25,7 @@ import (
 
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/api/rbac/v1beta1"
+	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 
@@ -126,7 +127,10 @@ func OperatorOrCollect(ctx context.Context, c client.Client, cfg OperatorConfigu
 		return installKnative(ctx, c, cfg.Namespace, customizer, collection, force)
 	}
 
-	if errevt := installEvents(ctx, c, cfg.Namespace, customizer, collection); errevt != nil {
+	if errevt := installEvents(ctx, c, cfg.Namespace, customizer, collection, force); errevt != nil {
+		if k8serrors.IsAlreadyExists(err) {
+			return err
+		}
 		fmt.Println("Warning: the operator will not be able to publish Kubernetes events. Try installing as cluster-admin to allow it to generate events.")
 	}
 
@@ -158,8 +162,8 @@ func installKnative(ctx context.Context, c client.Client, namespace string, cust
 	)
 }
 
-func installEvents(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection) error {
-	return ResourcesOrCollect(ctx, c, namespace, collection, customizer,
+func installEvents(ctx context.Context, c client.Client, namespace string, customizer ResourceCustomizer, collection *kubernetes.Collection, force bool) error {
+	return ResourcesOrCollect(ctx, c, namespace, collection, force, customizer,
 		"operator-role-events.yaml",
 		"operator-role-binding-events.yaml",
 	)


[camel-k] 04/14: #1199: logging status information in dev and wait mode

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 9f03af22c76b29e785833959765fe965a738b5f5
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Jan 28 00:46:47 2020 +0100

    #1199: logging status information in dev and wait mode
---
 deploy/operator-role-kubernetes.yaml               |   1 +
 deploy/operator-role-olm.yaml                      |   1 +
 deploy/operator-role-openshift.yaml                |   1 +
 e2e/dev_mode_test.go                               |   5 +-
 pkg/cmd/install.go                                 |  23 ++--
 pkg/cmd/run.go                                     |  24 ++--
 pkg/controller/build/build_controller.go           |   8 +-
 .../integration/integration_controller.go          |   8 +-
 .../integrationkit/integrationkit_controller.go    |   8 +-
 .../integrationplatform_controller.go              |   8 +-
 pkg/{events => event}/manager.go                   |   2 +-
 pkg/trait/deployment_test.go                       |   2 +-
 pkg/util/watch/watch.go                            | 132 ++++++++++++++++++++-
 13 files changed, 172 insertions(+), 51 deletions(-)

diff --git a/deploy/operator-role-kubernetes.yaml b/deploy/operator-role-kubernetes.yaml
index 4e9db4c..bca4878 100644
--- a/deploy/operator-role-kubernetes.yaml
+++ b/deploy/operator-role-kubernetes.yaml
@@ -66,6 +66,7 @@ rules:
   resources:
   - events
   verbs:
+  - create
   - get
   - list
   - watch
diff --git a/deploy/operator-role-olm.yaml b/deploy/operator-role-olm.yaml
index a213197..18a6f91 100644
--- a/deploy/operator-role-olm.yaml
+++ b/deploy/operator-role-olm.yaml
@@ -66,6 +66,7 @@ rules:
   resources:
   - events
   verbs:
+  - create
   - get
   - list
   - watch
diff --git a/deploy/operator-role-openshift.yaml b/deploy/operator-role-openshift.yaml
index 9da5132..46ea8c5 100644
--- a/deploy/operator-role-openshift.yaml
+++ b/deploy/operator-role-openshift.yaml
@@ -66,6 +66,7 @@ rules:
   resources:
   - events
   verbs:
+  - create
   - get
   - list
   - watch
diff --git a/e2e/dev_mode_test.go b/e2e/dev_mode_test.go
index fd057e9..a028917 100644
--- a/e2e/dev_mode_test.go
+++ b/e2e/dev_mode_test.go
@@ -48,11 +48,12 @@ func TestRunDevMode(t *testing.T) {
 			kamelRun := kamelWithContext(ctx, "run", "-n", ns, file, "--dev")
 			kamelRun.SetOut(pipew)
 
-			logScanner := util.NewLogScanner(ctx, piper, "Magicstring!", "Magicjordan!")
+			logScanner := util.NewLogScanner(ctx, piper, "Integration yaml in phase Running", "Magicstring!", "Magicjordan!")
 
 			go kamelRun.Execute()
 
-			Eventually(logScanner.IsFound("Magicstring!"), 5*time.Minute).Should(BeTrue())
+			Eventually(logScanner.IsFound("Integration yaml in phase Running"), 5*time.Minute).Should(BeTrue())
+			Eventually(logScanner.IsFound("Magicstring!"), 3*time.Minute).Should(BeTrue())
 			Expect(logScanner.IsFound("Magicjordan!")()).To(BeFalse())
 
 			util.ReplaceInFile(t, file, "string!", "jordan!")
diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index b0441dc..248d7d7 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -366,7 +366,7 @@ func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
 
 		if collection == nil {
 			if o.Wait {
-				err = o.waitForPlatformReady(platform)
+				err = o.waitForPlatformReady(cobraCmd, platform)
 				if err != nil {
 					return err
 				}
@@ -418,25 +418,20 @@ func (o *installCmdOptions) printOutput(collection *kubernetes.Collection) error
 	return nil
 }
 
-func (o *installCmdOptions) waitForPlatformReady(platform *v1.IntegrationPlatform) error {
+func (o *installCmdOptions) waitForPlatformReady(cmd *cobra.Command, platform *v1.IntegrationPlatform) error {
 	handler := func(i *v1.IntegrationPlatform) bool {
-		if i.Status.Phase != "" {
-			fmt.Println("platform \""+platform.Name+"\" in phase", i.Status.Phase)
-
-			if i.Status.Phase == v1.IntegrationPlatformPhaseReady {
-				// TODO display some error info when available in the status
-				return false
-			}
-
-			if i.Status.Phase == v1.IntegrationPlatformPhaseError {
-				fmt.Println("platform installation failed")
-				return false
-			}
+		if i.Status.Phase == v1.IntegrationPlatformPhaseReady || i.Status.Phase == v1.IntegrationPlatformPhaseError {
+			return false
 		}
 
 		return true
 	}
 
+	go watch.HandleIntegrationPlatformEvents(o.Context, platform, func(event *corev1.Event) bool {
+		fmt.Fprintln(cmd.OutOrStdout(), event.Message)
+		return true
+	})
+
 	return watch.HandlePlatformStateChanges(o.Context, platform, handler)
 }
 
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index b529955..bb7b6f3 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -43,6 +43,7 @@ import (
 	"github.com/magiconair/properties"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
+	corev1 "k8s.io/api/core/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -245,7 +246,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 	}
 	if o.Wait || o.Dev {
 		for {
-			integrationPhase, err := o.waitForIntegrationReady(integration)
+			integrationPhase, err := o.waitForIntegrationReady(cmd, integration)
 			if err != nil {
 				return err
 			}
@@ -253,7 +254,6 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 			if integrationPhase == nil || *integrationPhase == v1.IntegrationPhaseError {
 				return fmt.Errorf("integration \"%s\" deployment failed", integration.Name)
 			} else if *integrationPhase == v1.IntegrationPhaseRunning {
-				fmt.Println("Running")
 				break
 			}
 
@@ -297,27 +297,23 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 	return nil
 }
 
-func (o *runCmdOptions) waitForIntegrationReady(integration *v1.Integration) (*v1.IntegrationPhase, error) {
+func (o *runCmdOptions) waitForIntegrationReady(cmd *cobra.Command, integration *v1.Integration) (*v1.IntegrationPhase, error) {
 	handler := func(i *v1.Integration) bool {
 		//
 		// TODO when we add health checks, we should Wait until they are passed
 		//
-		if i.Status.Phase != "" {
-			fmt.Println("integration \""+integration.Name+"\" in phase", i.Status.Phase)
-
-			if i.Status.Phase == v1.IntegrationPhaseRunning {
-				// TODO display some error info when available in the status
-				return false
-			}
-
-			if i.Status.Phase == v1.IntegrationPhaseError {
-				return false
-			}
+		if i.Status.Phase == v1.IntegrationPhaseRunning || i.Status.Phase == v1.IntegrationPhaseError {
+			return false
 		}
 
 		return true
 	}
 
+	go watch.HandleIntegrationEvents(o.Context, integration, func(event *corev1.Event) bool {
+		fmt.Fprintln(cmd.OutOrStdout(), event.Message)
+		return true
+	})
+
 	return watch.HandleIntegrationStateChanges(o.Context, integration, handler)
 }
 
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index ecb2995..092dc68 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -22,7 +22,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/apache/camel-k/pkg/events"
+	camelevent "github.com/apache/camel-k/pkg/event"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -208,13 +208,13 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
+				camelevent.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
+					camelevent.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -231,7 +231,7 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyBuildUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+			camelevent.NotifyBuildUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 205004b..1532c45 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -20,7 +20,7 @@ package integration
 import (
 	"context"
 
-	"github.com/apache/camel-k/pkg/events"
+	camelevent "github.com/apache/camel-k/pkg/event"
 	appsv1 "k8s.io/api/apps/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -260,13 +260,13 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
+				camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
+					camelevent.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -281,7 +281,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+			camelevent.NotifyIntegrationUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index c86947a..dd4b271 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -20,7 +20,7 @@ package integrationkit
 import (
 	"context"
 
-	"github.com/apache/camel-k/pkg/events"
+	camelevent "github.com/apache/camel-k/pkg/event"
 	"github.com/apache/camel-k/pkg/platform"
 	"k8s.io/client-go/tools/record"
 
@@ -227,13 +227,13 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
+				camelevent.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
+					camelevent.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -248,7 +248,7 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationKitUpdated(ctx, r.client, r.recorder, &instance, newTarget)
+			camelevent.NotifyIntegrationKitUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 1ad9a60..0f8668a 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -21,7 +21,7 @@ import (
 	"context"
 	"time"
 
-	"github.com/apache/camel-k/pkg/events"
+	camelevent "github.com/apache/camel-k/pkg/event"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/tools/record"
@@ -151,13 +151,13 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			target, err = a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
+				camelevent.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
 				return reconcile.Result{}, err
 			}
 
 			if target != nil {
 				if err := r.client.Status().Patch(ctx, target, k8sclient.MergeFrom(&instance)); err != nil {
-					events.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
+					camelevent.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
 					return reconcile.Result{}, err
 				}
 
@@ -174,7 +174,7 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationPlatformUpdated(ctx, r.client, r.recorder, &instance, target)
+			camelevent.NotifyIntegrationPlatformUpdated(ctx, r.client, r.recorder, &instance, target)
 			break
 		}
 	}
diff --git a/pkg/events/manager.go b/pkg/event/manager.go
similarity index 99%
rename from pkg/events/manager.go
rename to pkg/event/manager.go
index 5622d27..9e4869a 100644
--- a/pkg/events/manager.go
+++ b/pkg/event/manager.go
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package events
+package event
 
 import (
 	"context"
diff --git a/pkg/trait/deployment_test.go b/pkg/trait/deployment_test.go
index 7d9c666..8a6a785 100644
--- a/pkg/trait/deployment_test.go
+++ b/pkg/trait/deployment_test.go
@@ -119,7 +119,7 @@ func TestApplyDeploymentTraitWhileDeployingIntegrationDoesSucceed(t *testing.T)
 	conditions := environment.Integration.Status.Conditions
 	assert.Len(t, conditions, 1)
 	assert.Equal(t, v1.IntegrationConditionDeploymentAvailable, conditions[0].Type)
-	assert.Equal(t, "integration-name", conditions[0].Message)
+	assert.Equal(t, "deployment name is integration-name", conditions[0].Message)
 }
 
 func TestApplyDeploymentTraitWhileRunningIntegrationDoesSucceed(t *testing.T) {
diff --git a/pkg/util/watch/watch.go b/pkg/util/watch/watch.go
index baaaa7c..289fc12 100644
--- a/pkg/util/watch/watch.go
+++ b/pkg/util/watch/watch.go
@@ -19,12 +19,13 @@ package watch
 
 import (
 	"context"
-
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-	"github.com/apache/camel-k/pkg/util/log"
+	"fmt"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/kubernetes/customclient"
+	"github.com/apache/camel-k/pkg/util/log"
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/json"
@@ -97,6 +98,69 @@ func HandleIntegrationStateChanges(ctx context.Context, integration *v1.Integrat
 }
 
 //
+// HandleIntegrationEvents watches all events related to the given integration.
+//
+//     watch.HandleIntegrationEvents(o.Context, integration, func(event *corev1.Event) bool {
+//		 println(event.Message)
+//		 return true
+//	   })
+//
+// This function blocks until the handler function returns true or either the events channel or the context is closed.
+//
+func HandleIntegrationEvents(ctx context.Context, integration *v1.Integration,
+	handler func(event *corev1.Event) bool) error {
+	dynamicClient, err := customclient.GetDynamicClientFor("", "v1", "events", integration.Namespace)
+	if err != nil {
+		return err
+	}
+	watcher, err := dynamicClient.Watch(metav1.ListOptions{
+		FieldSelector: fmt.Sprintf("involvedObject.kind=Integration,"+
+			"involvedObject.apiVersion=%s,"+
+			"involvedObject.name=%s",
+			v1.SchemeGroupVersion.String(), integration.Name),
+	})
+	if err != nil {
+		return err
+	}
+
+	defer watcher.Stop()
+	events := watcher.ResultChan()
+
+	for {
+		select {
+		case <-ctx.Done():
+			return nil
+		case e, ok := <-events:
+			if !ok {
+				return nil
+			}
+
+			if e.Object != nil {
+				if runtimeUnstructured, ok := e.Object.(runtime.Unstructured); ok {
+					jsondata, err := kubernetes.ToJSON(runtimeUnstructured)
+					if err != nil {
+						return err
+					}
+					evt := corev1.Event{}
+					err = json.Unmarshal(jsondata, &evt)
+					if err != nil {
+						log.Error(err, "Unexpected error detected when watching resource")
+						return nil
+					}
+
+					if evt.CreationTimestamp.UnixNano() >= integration.CreationTimestamp.UnixNano() {
+						if !handler(&evt) {
+							return nil
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+
+//
 // HandlePlatformStateChanges watches a platform resource and invoke the given handler when its status changes.
 //
 //     err := watch.HandlePlatformStateChanges(ctx, platform, func(i *v1.IntegrationPlatform) bool {
@@ -159,3 +223,65 @@ func HandlePlatformStateChanges(ctx context.Context, platform *v1.IntegrationPla
 		}
 	}
 }
+
+//
+// HandleIntegrationPlatformEvents watches all events related to the given integration platform.
+//
+//     watch.HandleIntegrationPlatformEvents(o.Context, platform, func(event *corev1.Event) bool {
+//		 println(event.Message)
+//		 return true
+//	   })
+//
+// This function blocks until the handler function returns true or either the events channel or the context is closed.
+//
+func HandleIntegrationPlatformEvents(ctx context.Context, p *v1.IntegrationPlatform,
+	handler func(event *corev1.Event) bool) error {
+	dynamicClient, err := customclient.GetDynamicClientFor("", "v1", "events", p.Namespace)
+	if err != nil {
+		return err
+	}
+	watcher, err := dynamicClient.Watch(metav1.ListOptions{
+		FieldSelector: fmt.Sprintf("involvedObject.kind=IntegrationPlatform,"+
+			"involvedObject.apiVersion=%s,"+
+			"involvedObject.name=%s",
+			v1.SchemeGroupVersion.String(), p.Name),
+	})
+	if err != nil {
+		return err
+	}
+
+	defer watcher.Stop()
+	events := watcher.ResultChan()
+
+	for {
+		select {
+		case <-ctx.Done():
+			return nil
+		case e, ok := <-events:
+			if !ok {
+				return nil
+			}
+
+			if e.Object != nil {
+				if runtimeUnstructured, ok := e.Object.(runtime.Unstructured); ok {
+					jsondata, err := kubernetes.ToJSON(runtimeUnstructured)
+					if err != nil {
+						return err
+					}
+					evt := corev1.Event{}
+					err = json.Unmarshal(jsondata, &evt)
+					if err != nil {
+						log.Error(err, "Unexpected error detected when watching resource")
+						return nil
+					}
+
+					if evt.CreationTimestamp.UnixNano() >= p.CreationTimestamp.UnixNano() {
+						if !handler(&evt) {
+							return nil
+						}
+					}
+				}
+			}
+		}
+	}
+}


[camel-k] 02/14: #1199: add events to all 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 d1cf15fd13254ab679dcc34d73415a08fef47485
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Mon Jan 27 15:46:27 2020 +0100

    #1199: add events to all CRD
---
 akamel-config.yaml                                 |   3 -
 pkg/apis/camel/v1/build_types_support.go           |  41 +++++
 pkg/apis/camel/v1/common_types.go                  |  10 ++
 pkg/apis/camel/v1/integration_types_support.go     |  41 +++++
 pkg/apis/camel/v1/integrationkit_types_support.go  |  41 +++++
 pkg/apis/camel/v1/integrationplatform_types.go     |   2 +
 .../camel/v1/integrationplatform_types_support.go  |  41 +++++
 pkg/cmd/operator/operator.go                       |   3 +-
 pkg/controller/build/build_controller.go           |  19 ++-
 .../integrationkit/integrationkit_controller.go    |  19 ++-
 .../integrationplatform_controller.go              |  11 +-
 pkg/events/manager.go                              | 173 +++++++++++++++++----
 12 files changed, 358 insertions(+), 46 deletions(-)

diff --git a/akamel-config.yaml b/akamel-config.yaml
deleted file mode 100755
index 1f20f9b..0000000
--- a/akamel-config.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-kamel:
-  install:
-    maven-repositories: '[https://repository.apache.org/content/repositories/orgapachecamel-1171]'
diff --git a/pkg/apis/camel/v1/build_types_support.go b/pkg/apis/camel/v1/build_types_support.go
index 19ee880..2c8243b 100644
--- a/pkg/apis/camel/v1/build_types_support.go
+++ b/pkg/apis/camel/v1/build_types_support.go
@@ -142,3 +142,44 @@ func (in *BuildStatus) RemoveCondition(condType BuildConditionType) {
 
 	in.Conditions = newConditions
 }
+
+var _ ResourceCondition = BuildCondition{}
+
+// GetConditions --
+func (in *BuildStatus) GetConditions() []ResourceCondition {
+	res := make([]ResourceCondition, 0, len(in.Conditions))
+	for _, c := range in.Conditions {
+		res = append(res, c)
+	}
+	return res
+}
+
+// GetType --
+func (c BuildCondition) GetType() string {
+	return string(c.Type)
+}
+
+// GetStatus --
+func (c BuildCondition) GetStatus() corev1.ConditionStatus {
+	return c.Status
+}
+
+// GetLastUpdateTime --
+func (c BuildCondition) GetLastUpdateTime() metav1.Time {
+	return c.LastUpdateTime
+}
+
+// GetLastTransitionTime --
+func (c BuildCondition) GetLastTransitionTime() metav1.Time {
+	return c.LastTransitionTime
+}
+
+// GetReason --
+func (c BuildCondition) GetReason() string {
+	return c.Reason
+}
+
+// GetMessage --
+func (c BuildCondition) GetMessage() string {
+	return c.Message
+}
diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go
index 36df7e7..0bcc485 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -99,3 +99,13 @@ const (
 	// ServiceTypeUser --
 	ServiceTypeUser = "user"
 )
+
+// ResourceCondition is a common type for all conditions
+type ResourceCondition interface {
+	GetType() string
+	GetStatus() corev1.ConditionStatus
+	GetLastUpdateTime() metav1.Time
+	GetLastTransitionTime() metav1.Time
+	GetReason() string
+	GetMessage() string
+}
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 5516986..d04e1bc 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -299,3 +299,44 @@ func (in *IntegrationStatus) RemoveCondition(condType IntegrationConditionType)
 
 	in.Conditions = newConditions
 }
+
+var _ ResourceCondition = IntegrationCondition{}
+
+// GetConditions --
+func (in *IntegrationStatus) GetConditions() []ResourceCondition {
+	res := make([]ResourceCondition, 0, len(in.Conditions))
+	for _, c := range in.Conditions {
+		res = append(res, c)
+	}
+	return res
+}
+
+// GetType --
+func (c IntegrationCondition) GetType() string {
+	return string(c.Type)
+}
+
+// GetStatus --
+func (c IntegrationCondition) GetStatus() corev1.ConditionStatus {
+	return c.Status
+}
+
+// GetLastUpdateTime --
+func (c IntegrationCondition) GetLastUpdateTime() metav1.Time {
+	return c.LastUpdateTime
+}
+
+// GetLastTransitionTime --
+func (c IntegrationCondition) GetLastTransitionTime() metav1.Time {
+	return c.LastTransitionTime
+}
+
+// GetReason --
+func (c IntegrationCondition) GetReason() string {
+	return c.Reason
+}
+
+// GetMessage --
+func (c IntegrationCondition) GetMessage() string {
+	return c.Message
+}
diff --git a/pkg/apis/camel/v1/integrationkit_types_support.go b/pkg/apis/camel/v1/integrationkit_types_support.go
index df3a95d..fb310df 100644
--- a/pkg/apis/camel/v1/integrationkit_types_support.go
+++ b/pkg/apis/camel/v1/integrationkit_types_support.go
@@ -155,3 +155,44 @@ func (in *IntegrationKitStatus) RemoveCondition(condType IntegrationKitCondition
 
 	in.Conditions = newConditions
 }
+
+var _ ResourceCondition = IntegrationKitCondition{}
+
+// GetConditions --
+func (in *IntegrationKitStatus) GetConditions() []ResourceCondition {
+	res := make([]ResourceCondition, 0, len(in.Conditions))
+	for _, c := range in.Conditions {
+		res = append(res, c)
+	}
+	return res
+}
+
+// GetType --
+func (c IntegrationKitCondition) GetType() string {
+	return string(c.Type)
+}
+
+// GetStatus --
+func (c IntegrationKitCondition) GetStatus() corev1.ConditionStatus {
+	return c.Status
+}
+
+// GetLastUpdateTime --
+func (c IntegrationKitCondition) GetLastUpdateTime() metav1.Time {
+	return c.LastUpdateTime
+}
+
+// GetLastTransitionTime --
+func (c IntegrationKitCondition) GetLastTransitionTime() metav1.Time {
+	return c.LastTransitionTime
+}
+
+// GetReason --
+func (c IntegrationKitCondition) GetReason() string {
+	return c.Reason
+}
+
+// GetMessage --
+func (c IntegrationKitCondition) GetMessage() string {
+	return c.Message
+}
diff --git a/pkg/apis/camel/v1/integrationplatform_types.go b/pkg/apis/camel/v1/integrationplatform_types.go
index ef72193..ff9afbb 100644
--- a/pkg/apis/camel/v1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1/integrationplatform_types.go
@@ -156,6 +156,8 @@ const (
 	// IntegrationPlatformKind --
 	IntegrationPlatformKind string = "IntegrationPlatform"
 
+	// IntegrationPlatformPhaseNone --
+	IntegrationPlatformPhaseNone IntegrationPlatformPhase = ""
 	// IntegrationPlatformPhaseCreating --
 	IntegrationPlatformPhaseCreating IntegrationPlatformPhase = "Creating"
 	// IntegrationPlatformPhaseWarming --
diff --git a/pkg/apis/camel/v1/integrationplatform_types_support.go b/pkg/apis/camel/v1/integrationplatform_types_support.go
index 8a2a806..ce33114 100644
--- a/pkg/apis/camel/v1/integrationplatform_types_support.go
+++ b/pkg/apis/camel/v1/integrationplatform_types_support.go
@@ -202,3 +202,44 @@ func (m MavenSpec) GetTimeout() metav1.Duration {
 	}
 	return *m.Timeout
 }
+
+var _ ResourceCondition = IntegrationPlatformCondition{}
+
+// GetConditions --
+func (in *IntegrationPlatformStatus) GetConditions() []ResourceCondition {
+	res := make([]ResourceCondition, 0, len(in.Conditions))
+	for _, c := range in.Conditions {
+		res = append(res, c)
+	}
+	return res
+}
+
+// GetType --
+func (c IntegrationPlatformCondition) GetType() string {
+	return string(c.Type)
+}
+
+// GetStatus --
+func (c IntegrationPlatformCondition) GetStatus() corev1.ConditionStatus {
+	return c.Status
+}
+
+// GetLastUpdateTime --
+func (c IntegrationPlatformCondition) GetLastUpdateTime() metav1.Time {
+	return c.LastUpdateTime
+}
+
+// GetLastTransitionTime --
+func (c IntegrationPlatformCondition) GetLastTransitionTime() metav1.Time {
+	return c.LastTransitionTime
+}
+
+// GetReason --
+func (c IntegrationPlatformCondition) GetReason() string {
+	return c.Reason
+}
+
+// GetMessage --
+func (c IntegrationPlatformCondition) GetMessage() string {
+	return c.Message
+}
diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index 92229df..012179f 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -27,7 +27,6 @@ import (
 	"time"
 
 	"github.com/apache/camel-k/pkg/client"
-	camellog "github.com/apache/camel-k/pkg/util/log"
 	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
 	"github.com/operator-framework/operator-sdk/pkg/leader"
 	"github.com/operator-framework/operator-sdk/pkg/ready"
@@ -111,7 +110,7 @@ func Run() {
 		os.Exit(1)
 	}
 	eventBroadcaster := record.NewBroadcaster()
-	eventBroadcaster.StartLogging(camellog.WithName("events").Infof)
+	//eventBroadcaster.StartLogging(camellog.WithName("events").Infof)
 	eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: c.CoreV1().Events(namespace)})
 
 	// Create a new Cmd to provide shared dependencies and start components
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index b69b4a6..ddf5da7 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -22,9 +22,11 @@ import (
 	"sync"
 	"time"
 
+	"github.com/apache/camel-k/pkg/events"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/tools/record"
 
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -54,10 +56,11 @@ func Add(mgr manager.Manager) error {
 // newReconciler returns a new reconcile.Reconciler
 func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 	return &ReconcileBuild{
-		client:  c,
-		reader:  mgr.GetAPIReader(),
-		scheme:  mgr.GetScheme(),
-		builder: builder.New(c),
+		client:   c,
+		reader:   mgr.GetAPIReader(),
+		scheme:   mgr.GetScheme(),
+		builder:  builder.New(c),
+		recorder: mgr.GetEventRecorderFor("camel-k-build-controller"),
 	}
 }
 
@@ -121,6 +124,7 @@ type ReconcileBuild struct {
 	scheme   *runtime.Scheme
 	builder  builder.Builder
 	routines sync.Map
+	recorder record.EventRecorder
 }
 
 // Reconcile reads that state of the cluster for a Build object and makes changes based on the state read
@@ -204,12 +208,14 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
+				events.NotifyBuildError(r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
-				if r, err := r.update(ctx, &instance, newTarget); err != nil {
-					return r, err
+				if res, err := r.update(ctx, &instance, newTarget); err != nil {
+					events.NotifyBuildError(r.recorder, &instance, newTarget, err)
+					return res, err
 				}
 
 				if newTarget.Status.Phase != target.Status.Phase {
@@ -225,6 +231,7 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			// handle one action at time so the resource
 			// is always at its latest state
+			events.NotifyBuildUpdated(r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index d9144aa..fc87130 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -20,7 +20,9 @@ package integrationkit
 import (
 	"context"
 
+	"github.com/apache/camel-k/pkg/events"
 	"github.com/apache/camel-k/pkg/platform"
+	"k8s.io/client-go/tools/record"
 
 	"github.com/apache/camel-k/pkg/util/digest"
 	"github.com/apache/camel-k/pkg/util/log"
@@ -55,8 +57,9 @@ func Add(mgr manager.Manager) error {
 // newReconciler returns a new reconcile.Reconciler
 func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 	return &ReconcileIntegrationKit{
-		client: c,
-		scheme: mgr.GetScheme(),
+		client:   c,
+		scheme:   mgr.GetScheme(),
+		recorder: mgr.GetEventRecorderFor("camel-k-integration-kit-controller"),
 	}
 }
 
@@ -152,8 +155,9 @@ var _ reconcile.Reconciler = &ReconcileIntegrationKit{}
 type ReconcileIntegrationKit struct {
 	// This client, initialized using mgr.Client() above, is a split client
 	// that reads objects from the cache and writes to the apiserver
-	client client.Client
-	scheme *runtime.Scheme
+	client   client.Client
+	scheme   *runtime.Scheme
+	recorder record.EventRecorder
 }
 
 // Reconcile reads that state of the cluster for a IntegrationKit object and makes changes based on the state read
@@ -223,12 +227,14 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
+				events.NotifyIntegrationKitError(r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
-				if r, err := r.update(ctx, &instance, newTarget); err != nil {
-					return r, err
+				if res, err := r.update(ctx, &instance, newTarget); err != nil {
+					events.NotifyIntegrationKitError(r.recorder, &instance, newTarget, err)
+					return res, err
 				}
 
 				if newTarget.Status.Phase != target.Status.Phase {
@@ -242,6 +248,7 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			// handle one action at time so the resource
 			// is always at its latest state
+			events.NotifyIntegrationKitUpdated(r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 5b77310..37fd592 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -21,8 +21,10 @@ import (
 	"context"
 	"time"
 
+	"github.com/apache/camel-k/pkg/events"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/tools/record"
 
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -52,6 +54,7 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 	return &ReconcileIntegrationPlatform{
 		client: c,
 		scheme: mgr.GetScheme(),
+		recorder: mgr.GetEventRecorderFor("camel-k-integration-platform-controller"),
 	}
 }
 
@@ -92,8 +95,9 @@ var _ reconcile.Reconciler = &ReconcileIntegrationPlatform{}
 type ReconcileIntegrationPlatform struct {
 	// This client, initialized using mgr.Client() above, is a split client
 	// that reads objects from the cache and writes to the apiserver
-	client client.Client
-	scheme *runtime.Scheme
+	client   client.Client
+	scheme   *runtime.Scheme
+	recorder record.EventRecorder
 }
 
 // Reconcile reads that state of the cluster for a IntegrationPlatform object and makes changes based
@@ -147,11 +151,13 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			target, err = a.Handle(ctx, target)
 			if err != nil {
+				events.NotifyIntegrationPlatformError(r.recorder, &instance, target, err)
 				return reconcile.Result{}, err
 			}
 
 			if target != nil {
 				if err := r.client.Status().Patch(ctx, target, k8sclient.MergeFrom(&instance)); err != nil {
+					events.NotifyIntegrationPlatformError(r.recorder, &instance, target, err)
 					return reconcile.Result{}, err
 				}
 
@@ -168,6 +174,7 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			// handle one action at time so the resource
 			// is always at its latest state
+			events.NotifyIntegrationPlatformUpdated(r.recorder, &instance, target)
 			break
 		}
 	}
diff --git a/pkg/events/manager.go b/pkg/events/manager.go
index 5cd9a70..2a792eb 100644
--- a/pkg/events/manager.go
+++ b/pkg/events/manager.go
@@ -22,6 +22,7 @@ import (
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/tools/record"
 )
 
@@ -30,8 +31,29 @@ const (
 	ReasonIntegrationPhaseUpdated = "IntegrationPhaseUpdated"
 	// ReasonIntegrationConditionChanged --
 	ReasonIntegrationConditionChanged = "IntegrationConditionChanged"
-	// ReasonIntegrationError
+	// ReasonIntegrationError --
 	ReasonIntegrationError = "IntegrationError"
+
+	// ReasonIntegrationKitPhaseUpdated --
+	ReasonIntegrationKitPhaseUpdated = "IntegrationKitPhaseUpdated"
+	// ReasonIntegrationKitConditionChanged --
+	ReasonIntegrationKitConditionChanged = "IntegrationKitConditionChanged"
+	// ReasonIntegrationKitError --
+	ReasonIntegrationKitError = "IntegrationKitError"
+
+	// ReasonIntegrationPlatformPhaseUpdated --
+	ReasonIntegrationPlatformPhaseUpdated = "IntegrationPlatformPhaseUpdated"
+	// ReasonIntegrationPlatformConditionChanged --
+	ReasonIntegrationPlatformConditionChanged = "IntegrationPlatformConditionChanged"
+	// ReasonIntegrationPlatformError --
+	ReasonIntegrationPlatformError = "IntegrationPlatformError"
+
+	// ReasonBuildPhaseUpdated --
+	ReasonBuildPhaseUpdated = "BuildPhaseUpdated"
+	// ReasonBuildConditionChanged --
+	ReasonBuildConditionChanged = "BuildConditionChanged"
+	// ReasonBuildError --
+	ReasonBuildError = "BuildError"
 )
 
 // NotifyIntegrationError automatically generates error events when the integration reconcile cycle phase has an error
@@ -43,7 +65,7 @@ func NotifyIntegrationError(recorder record.EventRecorder, old, new *v1.Integrat
 	if it == nil {
 		return
 	}
-	recorder.Eventf(it, corev1.EventTypeWarning, ReasonIntegrationError, "Cannot reconcile integration %s: %v", it.Name, err)
+	recorder.Eventf(it, corev1.EventTypeWarning, ReasonIntegrationError, "Cannot reconcile Integration %s: %v", it.Name, err)
 }
 
 // NotifyIntegrationUpdated automatically generates events when the integration changes
@@ -51,43 +73,140 @@ func NotifyIntegrationUpdated(recorder record.EventRecorder, old, new *v1.Integr
 	if new == nil {
 		return
 	}
+	oldPhase := ""
+	var oldConditions []v1.ResourceCondition
+	if old != nil {
+		oldPhase = string(old.Status.Phase)
+		oldConditions = old.Status.GetConditions()
+	}
+	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration", new.Name, ReasonIntegrationPhaseUpdated)
+	if new.Status.Phase != v1.IntegrationPhaseNone {
+		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration", new.Name, ReasonIntegrationConditionChanged)
+	}
+}
+
+// NotifyIntegrationKitUpdated automatically generates events when an integration kit changes
+func NotifyIntegrationKitUpdated(recorder record.EventRecorder, old, new *v1.IntegrationKit) {
+	if new == nil {
+		return
+	}
+	oldPhase := ""
+	var oldConditions []v1.ResourceCondition
+	if old != nil {
+		oldPhase = string(old.Status.Phase)
+		oldConditions = old.Status.GetConditions()
+	}
+	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration Kit", new.Name, ReasonIntegrationKitPhaseUpdated)
+	if new.Status.Phase != v1.IntegrationKitPhaseNone {
+		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Kit", new.Name, ReasonIntegrationKitConditionChanged)
+	}
+}
+
+// NotifyIntegrationKitError automatically generates error events when the integration kit reconcile cycle phase has an error
+func NotifyIntegrationKitError(recorder record.EventRecorder, old, new *v1.IntegrationKit, err error) {
+	kit := old
+	if new != nil {
+		kit = new
+	}
+	if kit == nil {
+		return
+	}
+	recorder.Eventf(kit, corev1.EventTypeWarning, ReasonIntegrationKitError, "Cannot reconcile Integration Kit %s: %v", kit.Name, err)
+}
+
+// NotifyIntegrationPlatformUpdated automatically generates events when an integration platform changes
+func NotifyIntegrationPlatformUpdated(recorder record.EventRecorder, old, new *v1.IntegrationPlatform) {
+	if new == nil {
+		return
+	}
+	oldPhase := ""
+	var oldConditions []v1.ResourceCondition
+	if old != nil {
+		oldPhase = string(old.Status.Phase)
+		oldConditions = old.Status.GetConditions()
+	}
+	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration Platform", new.Name, ReasonIntegrationPlatformPhaseUpdated)
+	if new.Status.Phase != v1.IntegrationPlatformPhaseNone {
+		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Platform", new.Name, ReasonIntegrationPlatformConditionChanged)
+	}
+}
 
+// NotifyIntegrationPlatformError automatically generates error events when the integration Platform reconcile cycle phase has an error
+func NotifyIntegrationPlatformError(recorder record.EventRecorder, old, new *v1.IntegrationPlatform, err error) {
+	p := old
+	if new != nil {
+		p = new
+	}
+	if p == nil {
+		return
+	}
+	recorder.Eventf(p, corev1.EventTypeWarning, ReasonIntegrationPlatformError, "Cannot reconcile Integration Platform %s: %v", p.Name, err)
+}
+
+// NotifyBuildUpdated automatically generates events when a build changes
+func NotifyBuildUpdated(recorder record.EventRecorder, old, new *v1.Build) {
+	if new == nil {
+		return
+	}
+	oldPhase := ""
+	var oldConditions []v1.ResourceCondition
+	if old != nil {
+		oldPhase = string(old.Status.Phase)
+		oldConditions = old.Status.GetConditions()
+	}
+	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Build", new.Name, ReasonBuildPhaseUpdated)
+	if new.Status.Phase != v1.BuildPhaseNone {
+		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Build", new.Name, ReasonBuildConditionChanged)
+	}
+}
+
+// NotifyBuildError automatically generates error events when the build reconcile cycle phase has an error
+func NotifyBuildError(recorder record.EventRecorder, old, new *v1.Build, err error) {
+	p := old
+	if new != nil {
+		p = new
+	}
+	if p == nil {
+		return
+	}
+	recorder.Eventf(p, corev1.EventTypeWarning, ReasonBuildError, "Cannot reconcile Build %s: %v", p.Name, err)
+}
+
+func notifyIfPhaseUpdated(recorder record.EventRecorder, new runtime.Object, oldPhase, newPhase string, resourceType, name, reason string) {
 	// Update information about phase changes
-	if old == nil || old.Status.Phase != new.Status.Phase {
-		phase := new.Status.Phase
-		if phase == v1.IntegrationPhaseNone {
+	if oldPhase != newPhase {
+		phase := newPhase
+		if phase == "" {
 			phase = "[none]"
 		}
-		recorder.Eventf(new, corev1.EventTypeNormal, ReasonIntegrationPhaseUpdated, "Integration %s in phase %s", new.Name, phase)
+		recorder.Eventf(new, corev1.EventTypeNormal, reason, "%s %s in phase %s", resourceType, name, phase)
 	}
+}
 
+func notifyIfConditionUpdated(recorder record.EventRecorder, new runtime.Object, oldConditions, newConditions []v1.ResourceCondition, resourceType, name, reason string) {
 	// Update information about changes in conditions
-	if new.Status.Phase != v1.IntegrationPhaseNone {
-		for _, cond := range getChangedConditions(old, new) {
-			head := ""
-			if cond.Status == corev1.ConditionFalse {
-				head = "No "
-			}
-			tail := ""
-			if cond.Message != "" {
-				tail = fmt.Sprintf(": %s", cond.Message)
-			}
-			recorder.Eventf(new, corev1.EventTypeNormal, ReasonIntegrationConditionChanged, "%s%s for integration %s%s", head, cond.Type, new.Name, tail)
+	for _, cond := range getCommonChangedConditions(oldConditions, newConditions) {
+		head := ""
+		if cond.GetStatus() == corev1.ConditionFalse {
+			head = "No "
+		}
+		tail := ""
+		if cond.GetMessage() != "" {
+			tail = fmt.Sprintf(": %s", cond.GetMessage())
 		}
+		recorder.Eventf(new, corev1.EventTypeNormal, reason, "%s%s for %s %s%s", head, cond.GetType(), resourceType, name, tail)
 	}
-
 }
 
-func getChangedConditions(old, new *v1.Integration) (res []v1.IntegrationCondition) {
-	if old == nil {
-		old = &v1.Integration{}
+func getCommonChangedConditions(old, new []v1.ResourceCondition) (res []v1.ResourceCondition) {
+	oldState := make(map[string]v1.ResourceCondition)
+	for _, c := range old {
+		oldState[c.GetType()] = c
 	}
-	if new == nil {
-		new = &v1.Integration{}
-	}
-	for _, newCond := range new.Status.Conditions {
-		oldCond := old.Status.GetCondition(newCond.Type)
-		if oldCond == nil || oldCond.Status != newCond.Status || oldCond.Message != newCond.Message {
+
+	for _, newCond := range new {
+		oldCond := oldState[newCond.GetType()]
+		if oldCond == nil || oldCond.GetStatus() != newCond.GetStatus() || oldCond.GetMessage() != newCond.GetMessage() {
 			res = append(res, newCond)
 		}
 	}


[camel-k] 14/14: Fix #1199: fix builder permissions

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 85808ffa4a4b0620c0371fddb3edd7cf212ad4ac
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Mon Feb 24 08:02:42 2020 +0100

    Fix #1199: fix builder permissions
---
 deploy/builder-role-kubernetes.yaml | 1 -
 deploy/builder-role-openshift.yaml  | 1 -
 deploy/resources.go                 | 8 ++++----
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/deploy/builder-role-kubernetes.yaml b/deploy/builder-role-kubernetes.yaml
index 5a18caf..7a551ca 100644
--- a/deploy/builder-role-kubernetes.yaml
+++ b/deploy/builder-role-kubernetes.yaml
@@ -55,7 +55,6 @@ rules:
   resources:
   - events
   verbs:
-  - create
   - get
   - list
   - watch
diff --git a/deploy/builder-role-openshift.yaml b/deploy/builder-role-openshift.yaml
index a0ab82b..7271d04 100644
--- a/deploy/builder-role-openshift.yaml
+++ b/deploy/builder-role-openshift.yaml
@@ -55,7 +55,6 @@ rules:
   resources:
   - events
   verbs:
-  - create
   - get
   - list
   - watch
diff --git a/deploy/resources.go b/deploy/resources.go
index 77c6542..5d30d0b 100644
--- a/deploy/resources.go
+++ b/deploy/resources.go
@@ -70,16 +70,16 @@ var assets = func() http.FileSystem {
 		"/builder-role-kubernetes.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-role-kubernetes.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 1467,
+			uncompressedSize: 1456,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x41\x8f\xdb\x36\x17\xbc\xf3\x57\x0c\xa4\x4b\xf2\x61\x2d\x7f\xe9\xa9\x70\x4f\xee\x66\xb7\x15\x1a\xd8\xc0\xca\x69\x90\x23\x45\x3e\x4b\x0f\x4b\x91\x2c\x49\xad\xb2\xfd\xf5\x05\x69\xbb\xf1\x76\x11\xa0\x05\xc2\x8b\x1f\xe9\xe1\xbc\x19\xce\xb3\x6b\xac\xbe\xdf\x12\x35\x3e\xb0\x22\x1b\x49\x23\x39\xa4\x91\xb0\xf5\x52\x8d\x84\xce\x1d\xd3\x22\x03\xe1\xde\xcd\x56\xcb\xc4\xce\xe2\xcd\xb6\xbb\x7f\x8b\xd9\x6a\x0a\x70\x96\xe0\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\xc1\x8e\xdb\x36\x14\xbc\xf3\x2b\x06\xd2\x25\x29\xd6\x72\xd3\x53\xe1\x9e\xdc\xcd\x6e\x2b\x34\xb0\x81\x95\xd3\x20\x47\x8a\x7c\x96\x1e\x96\x22\x59\x92\x5a\x65\xfb\xf5\x05\x69\xbb\xf1\x76\x2f\x29\x10\x5e\xfc\x48\x0f\xe7\xcd\x70\x9e\x5d\x63\xf5\xfd\x96\xa8\xf1\x81\x15\xd9\x48\x1a\xc9\x21\x8d\x84\xad\x97\x6a\x24\x74\xee\x98\x16\x19\x08\xf7\x6e\xb6\x5a\x26\x76\x16\x6f\xb6\xdd\xfd\x5b\xcc\x56\x53\x80\xb3\x04\x17\x30\x [...]
 		},
 		"/builder-role-openshift.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-role-openshift.yaml",
 			modTime:          time.Time{},
-			uncompressedSize: 2132,
+			uncompressedSize: 2121,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xa4\x4b\x52\xac\xe5\xa6\xa7\xc2\x3d\xb9\x9b\xdd\xd6\x68\x60\x03\x2b\xa7\x41\x8e\x23\x69\x2c\x0d\x96\x22\x59\x92\x5a\xc5\xfd\xfa\x42\xb4\xdd\xb5\xe3\xa4\x4d\x80\x00\xd1\xc5\xa3\xe1\xf0\xcd\x7b\xf3\xc6\xca\x31\xfb\x76\x8f\xca\xf1\x46\x6a\x36\x81\x1b\x44\x8b\xd8\x31\x96\x8e\xea\x8e\x51\xda\x5d\x1c\xc9\x33\xee\xed\x60\x1a\x8a\x62\x0d\x5e\x2c\xcb\xfb\x97\x18\x4c\xc3\x1e\xd6\x30\x [...]
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x54\x4d\x8f\xdb\x36\x10\xbd\xf3\x57\x3c\x48\x97\xa4\x58\xcb\x4d\x4f\x85\x7b\x72\x93\xdd\xd6\x68\x60\x03\x2b\xa7\x41\x8e\x23\x69\x2c\x0d\x4c\x91\x2c\x49\xad\xe2\xfe\xfa\x42\xb4\xdd\xb5\xe3\xf4\x0b\x0d\x10\x5d\x3c\x1a\x0e\xdf\xbc\x37\x6f\xac\x1c\xb3\x2f\xf7\xa8\x1c\x6f\xa5\x66\x13\xb8\x41\xb4\x88\x1d\x63\xe9\xa8\xee\x18\xa5\xdd\xc5\x91\x3c\xe3\xc1\x0e\xa6\xa1\x28\xd6\xe0\xc5\xb2\x7c\x78\x89\xc1\x34\xec\x61\x0d\xc3\x [...]
 		},
 		"/builder-service-account.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "builder-service-account.yaml",


[camel-k] 06/14: #1199: fix lint

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 622d0a78b5b8606b3b33c4426a4741922bf95f7e
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Jan 28 01:27:58 2020 +0100

    #1199: fix lint
---
 pkg/cmd/install.go                                                   | 1 +
 pkg/cmd/run.go                                                       | 1 +
 pkg/controller/integrationplatform/integrationplatform_controller.go | 4 ++--
 pkg/event/manager.go                                                 | 1 +
 pkg/util/watch/watch.go                                              | 1 -
 5 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go
index 248d7d7..183f32b 100644
--- a/pkg/cmd/install.go
+++ b/pkg/cmd/install.go
@@ -418,6 +418,7 @@ func (o *installCmdOptions) printOutput(collection *kubernetes.Collection) error
 	return nil
 }
 
+// nolint:errcheck
 func (o *installCmdOptions) waitForPlatformReady(cmd *cobra.Command, platform *v1.IntegrationPlatform) error {
 	handler := func(i *v1.IntegrationPlatform) bool {
 		if i.Status.Phase == v1.IntegrationPlatformPhaseReady || i.Status.Phase == v1.IntegrationPlatformPhaseError {
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index bb7b6f3..e6dee28 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -297,6 +297,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 	return nil
 }
 
+// nolint:errcheck
 func (o *runCmdOptions) waitForIntegrationReady(cmd *cobra.Command, integration *v1.Integration) (*v1.IntegrationPhase, error) {
 	handler := func(i *v1.Integration) bool {
 		//
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 0f8668a..6412ba7 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -52,8 +52,8 @@ func Add(mgr manager.Manager) error {
 // newReconciler returns a new reconcile.Reconciler
 func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 	return &ReconcileIntegrationPlatform{
-		client: c,
-		scheme: mgr.GetScheme(),
+		client:   c,
+		scheme:   mgr.GetScheme(),
 		recorder: mgr.GetEventRecorderFor("camel-k-integration-platform-controller"),
 	}
 }
diff --git a/pkg/event/manager.go b/pkg/event/manager.go
index 9e4869a..6b85b4c 100644
--- a/pkg/event/manager.go
+++ b/pkg/event/manager.go
@@ -180,6 +180,7 @@ func NotifyBuildError(ctx context.Context, c client.Client, recorder record.Even
 	recorder.Eventf(p, corev1.EventTypeWarning, ReasonBuildError, "Cannot reconcile Build %s: %v", p.Name, err)
 }
 
+// nolint:lll
 func notifyIfPhaseUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, new runtime.Object, oldPhase, newPhase string, resourceType, name, reason string) {
 	// Update information about phase changes
 	if oldPhase != newPhase {
diff --git a/pkg/util/watch/watch.go b/pkg/util/watch/watch.go
index 289fc12..5d2229c 100644
--- a/pkg/util/watch/watch.go
+++ b/pkg/util/watch/watch.go
@@ -159,7 +159,6 @@ func HandleIntegrationEvents(ctx context.Context, integration *v1.Integration,
 	}
 }
 
-
 //
 // HandlePlatformStateChanges watches a platform resource and invoke the given handler when its status changes.
 //


[camel-k] 01/14: # This is a combination of 2 commits. # This is the 1st commit message:

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 ba6e43989d45ff4c350bf7a7081e6f6f70633487
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Mon Jan 27 12:53:26 2020 +0100

    # This is a combination of 2 commits.
    # This is the 1st commit message:
    
    #1199: use kubernetes events during reconciliation
    
    # This is the commit message #2:
    
    #1199: use kubernetes events during reconciliation
---
 .gitignore                                         |  3 +
 akamel-config.yaml                                 |  3 +
 pkg/apis/camel/v1/integration_types_support.go     | 10 ++-
 pkg/cmd/operator/operator.go                       | 21 ++++-
 pkg/cmd/reset.go                                   |  2 +-
 pkg/cmd/run.go                                     |  2 +-
 .../integration/integration_controller.go          | 19 +++--
 pkg/events/manager.go                              | 95 ++++++++++++++++++++++
 pkg/metadata/metadata.go                           |  2 +-
 pkg/trait/deployment.go                            |  4 +-
 pkg/trait/knative_service.go                       |  5 +-
 pkg/trait/rest-dsl.go                              |  2 +-
 pkg/{ => util}/gzip/compress.go                    |  0
 pkg/{ => util}/gzip/compress_test.go               |  0
 14 files changed, 152 insertions(+), 16 deletions(-)

diff --git a/.gitignore b/.gitignore
index d746591..3bc834d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,9 @@
 /kamel
 /license-check
 
+# Config files
+/kamel-config.yaml
+
 # Released Packages
 *.tar.gz
 
diff --git a/akamel-config.yaml b/akamel-config.yaml
new file mode 100755
index 0000000..1f20f9b
--- /dev/null
+++ b/akamel-config.yaml
@@ -0,0 +1,3 @@
+kamel:
+  install:
+    maven-repositories: '[https://repository.apache.org/content/repositories/orgapachecamel-1171]'
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 21b8c0e..5516986 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -18,6 +18,7 @@ limitations under the License.
 package v1
 
 import (
+	"fmt"
 	"strings"
 
 	corev1 "k8s.io/api/core/v1"
@@ -209,12 +210,17 @@ func (in *Integration) SetIntegrationPlatform(platform *IntegrationPlatform) {
 // SetIntegrationKit --
 func (in *Integration) SetIntegrationKit(kit *IntegrationKit) {
 	cs := corev1.ConditionTrue
-
+	message := kit.Name
 	if kit.Status.Phase != IntegrationKitPhaseReady {
 		cs = corev1.ConditionFalse
+		if kit.Status.Phase == IntegrationKitPhaseNone {
+			message = fmt.Sprintf("creating a new integration kit")
+		} else {
+			message = fmt.Sprintf("integration kit %s is in state %q", kit.Name, kit.Status.Phase)
+		}
 	}
 
-	in.Status.SetCondition(IntegrationConditionKitAvailable, cs, IntegrationConditionKitAvailableReason, kit.Name)
+	in.Status.SetCondition(IntegrationConditionKitAvailable, cs, IntegrationConditionKitAvailableReason, message)
 	in.Status.Kit = kit.Name
 	in.Status.Image = kit.Status.Image
 }
diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index f5e6c09..92229df 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -26,10 +26,14 @@ import (
 	"runtime"
 	"time"
 
+	"github.com/apache/camel-k/pkg/client"
+	camellog "github.com/apache/camel-k/pkg/util/log"
 	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
 	"github.com/operator-framework/operator-sdk/pkg/leader"
 	"github.com/operator-framework/operator-sdk/pkg/ready"
 	sdkVersion "github.com/operator-framework/operator-sdk/version"
+	typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+	"k8s.io/client-go/tools/record"
 
 	"sigs.k8s.io/controller-runtime/pkg/client/config"
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
@@ -43,6 +47,8 @@ import (
 )
 
 var log = logf.Log.WithName("cmd")
+
+// GitCommit --
 var GitCommit string
 
 func printVersion() {
@@ -98,8 +104,21 @@ func Run() {
 	}
 	defer r.Unset() // nolint: errcheck
 
+	// Configure an event broadcaster
+	c, err := client.NewClient(false)
+	if err != nil {
+		log.Error(err, "cannot initialize client")
+		os.Exit(1)
+	}
+	eventBroadcaster := record.NewBroadcaster()
+	eventBroadcaster.StartLogging(camellog.WithName("events").Infof)
+	eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: c.CoreV1().Events(namespace)})
+
 	// Create a new Cmd to provide shared dependencies and start components
-	mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
+	mgr, err := manager.New(cfg, manager.Options{
+		Namespace:        namespace,
+		EventBroadcaster: eventBroadcaster,
+	})
 	if err != nil {
 		log.Error(err, "")
 		os.Exit(1)
diff --git a/pkg/cmd/reset.go b/pkg/cmd/reset.go
index 4f6a381..e45f174 100644
--- a/pkg/cmd/reset.go
+++ b/pkg/cmd/reset.go
@@ -78,7 +78,7 @@ func (o *resetCmdOptions) reset(_ *cobra.Command, _ []string) {
 	}
 
 	if err = o.resetIntegrationPlatform(c); err != nil {
-		fmt.Print(err)
+		fmt.Println(err)
 		return
 	}
 
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 5214ba7..b529955 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -33,9 +33,9 @@ import (
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/client"
-	"github.com/apache/camel-k/pkg/gzip"
 	"github.com/apache/camel-k/pkg/trait"
 	"github.com/apache/camel-k/pkg/util"
+	"github.com/apache/camel-k/pkg/util/gzip"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	k8slog "github.com/apache/camel-k/pkg/util/kubernetes/log"
 	"github.com/apache/camel-k/pkg/util/sync"
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 63cff5e..80e1911 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -20,10 +20,12 @@ package integration
 import (
 	"context"
 
+	"github.com/apache/camel-k/pkg/events"
 	appsv1 "k8s.io/api/apps/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/client-go/tools/record"
 
 	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -58,8 +60,9 @@ func Add(mgr manager.Manager) error {
 // newReconciler returns a new reconcile.Reconciler
 func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
 	return &ReconcileIntegration{
-		client: c,
-		scheme: mgr.GetScheme(),
+		client:   c,
+		scheme:   mgr.GetScheme(),
+		recorder: mgr.GetEventRecorderFor("camel-k-integration-controller"),
 	}
 }
 
@@ -206,8 +209,9 @@ var _ reconcile.Reconciler = &ReconcileIntegration{}
 type ReconcileIntegration struct {
 	// This client, initialized using mgr.Client() above, is a split client
 	// that reads objects from the cache and writes to the apiserver
-	client client.Client
-	scheme *runtime.Scheme
+	client   client.Client
+	scheme   *runtime.Scheme
+	recorder record.EventRecorder
 }
 
 // Reconcile reads that state of the cluster for a Integration object and makes changes based on the state read
@@ -256,12 +260,14 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
+				events.NotifyIntegrationError(r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
-				if r, err := r.update(ctx, &instance, newTarget); err != nil {
-					return r, err
+				if res, err := r.update(ctx, &instance, newTarget); err != nil {
+					events.NotifyIntegrationError(r.recorder, &instance, newTarget, err)
+					return res, err
 				}
 
 				if newTarget.Status.Phase != target.Status.Phase {
@@ -275,6 +281,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			// handle one action at time so the resource
 			// is always at its latest state
+			events.NotifyIntegrationUpdated(r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/events/manager.go b/pkg/events/manager.go
new file mode 100644
index 0000000..5cd9a70
--- /dev/null
+++ b/pkg/events/manager.go
@@ -0,0 +1,95 @@
+/*
+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 events
+
+import (
+	"fmt"
+
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/client-go/tools/record"
+)
+
+const (
+	// ReasonIntegrationPhaseUpdated --
+	ReasonIntegrationPhaseUpdated = "IntegrationPhaseUpdated"
+	// ReasonIntegrationConditionChanged --
+	ReasonIntegrationConditionChanged = "IntegrationConditionChanged"
+	// ReasonIntegrationError
+	ReasonIntegrationError = "IntegrationError"
+)
+
+// NotifyIntegrationError automatically generates error events when the integration reconcile cycle phase has an error
+func NotifyIntegrationError(recorder record.EventRecorder, old, new *v1.Integration, err error) {
+	it := old
+	if new != nil {
+		it = new
+	}
+	if it == nil {
+		return
+	}
+	recorder.Eventf(it, corev1.EventTypeWarning, ReasonIntegrationError, "Cannot reconcile integration %s: %v", it.Name, err)
+}
+
+// NotifyIntegrationUpdated automatically generates events when the integration changes
+func NotifyIntegrationUpdated(recorder record.EventRecorder, old, new *v1.Integration) {
+	if new == nil {
+		return
+	}
+
+	// Update information about phase changes
+	if old == nil || old.Status.Phase != new.Status.Phase {
+		phase := new.Status.Phase
+		if phase == v1.IntegrationPhaseNone {
+			phase = "[none]"
+		}
+		recorder.Eventf(new, corev1.EventTypeNormal, ReasonIntegrationPhaseUpdated, "Integration %s in phase %s", new.Name, phase)
+	}
+
+	// Update information about changes in conditions
+	if new.Status.Phase != v1.IntegrationPhaseNone {
+		for _, cond := range getChangedConditions(old, new) {
+			head := ""
+			if cond.Status == corev1.ConditionFalse {
+				head = "No "
+			}
+			tail := ""
+			if cond.Message != "" {
+				tail = fmt.Sprintf(": %s", cond.Message)
+			}
+			recorder.Eventf(new, corev1.EventTypeNormal, ReasonIntegrationConditionChanged, "%s%s for integration %s%s", head, cond.Type, new.Name, tail)
+		}
+	}
+
+}
+
+func getChangedConditions(old, new *v1.Integration) (res []v1.IntegrationCondition) {
+	if old == nil {
+		old = &v1.Integration{}
+	}
+	if new == nil {
+		new = &v1.Integration{}
+	}
+	for _, newCond := range new.Status.Conditions {
+		oldCond := old.Status.GetCondition(newCond.Type)
+		if oldCond == nil || oldCond.Status != newCond.Status || oldCond.Message != newCond.Message {
+			res = append(res, newCond)
+		}
+	}
+	return res
+}
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index 6a6e916..9f9b53e 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -21,8 +21,8 @@ import (
 	"github.com/scylladb/go-set/strset"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/gzip"
 	"github.com/apache/camel-k/pkg/util/camel"
+	"github.com/apache/camel-k/pkg/util/gzip"
 	"github.com/apache/camel-k/pkg/util/log"
 
 	src "github.com/apache/camel-k/pkg/util/source"
diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go
index 4abf44c..088a721 100644
--- a/pkg/trait/deployment.go
+++ b/pkg/trait/deployment.go
@@ -18,6 +18,8 @@ limitations under the License.
 package trait
 
 import (
+	"fmt"
+
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -119,7 +121,7 @@ func (t *deploymentTrait) Apply(e *Environment) error {
 			v1.IntegrationConditionDeploymentAvailable,
 			corev1.ConditionTrue,
 			v1.IntegrationConditionDeploymentAvailableReason,
-			deployment.Name,
+			fmt.Sprintf("deployment name is %s", deployment.Name),
 		)
 
 		if e.IntegrationInPhase(v1.IntegrationPhaseRunning) {
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 5f10270..37f18f2 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -18,6 +18,7 @@ limitations under the License.
 package trait
 
 import (
+	"fmt"
 	"strconv"
 
 	corev1 "k8s.io/api/core/v1"
@@ -114,7 +115,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 			v1.IntegrationConditionKnativeServiceAvailable,
 			corev1.ConditionFalse,
 			v1.IntegrationConditionKnativeServiceNotAvailableReason,
-			"controller strategy: "+string(ControllerStrategyDeployment),
+			fmt.Sprintf("different controller strategy chosen (%s)", string(ControllerStrategyDeployment)),
 		)
 
 		// A controller is already present for the integration
@@ -183,7 +184,7 @@ func (t *knativeServiceTrait) Apply(e *Environment) error {
 		v1.IntegrationConditionKnativeServiceAvailable,
 		corev1.ConditionTrue,
 		v1.IntegrationConditionKnativeServiceAvailableReason,
-		ksvc.Name,
+		fmt.Sprintf("Knative service name is %s", ksvc.Name),
 	)
 
 	if e.IntegrationInPhase(v1.IntegrationPhaseRunning) {
diff --git a/pkg/trait/rest-dsl.go b/pkg/trait/rest-dsl.go
index ec3400f..d3992b2 100644
--- a/pkg/trait/rest-dsl.go
+++ b/pkg/trait/rest-dsl.go
@@ -31,8 +31,8 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/gzip"
 	"github.com/apache/camel-k/pkg/util/defaults"
+	"github.com/apache/camel-k/pkg/util/gzip"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/maven"
 )
diff --git a/pkg/gzip/compress.go b/pkg/util/gzip/compress.go
similarity index 100%
rename from pkg/gzip/compress.go
rename to pkg/util/gzip/compress.go
diff --git a/pkg/gzip/compress_test.go b/pkg/util/gzip/compress_test.go
similarity index 100%
rename from pkg/gzip/compress_test.go
rename to pkg/util/gzip/compress_test.go


[camel-k] 12/14: Fix #1233: start dev mode also when integration is already running

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 968b48c4df590be7753b335dfaf91b396d005802
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Fri Feb 21 17:05:29 2020 +0100

    Fix #1233: start dev mode also when integration is already running
---
 pkg/util/watch/watch.go | 45 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/pkg/util/watch/watch.go b/pkg/util/watch/watch.go
index 5d2229c..21b08ba 100644
--- a/pkg/util/watch/watch.go
+++ b/pkg/util/watch/watch.go
@@ -50,6 +50,7 @@ func HandleIntegrationStateChanges(ctx context.Context, integration *v1.Integrat
 	if err != nil {
 		return nil, err
 	}
+
 	watcher, err := dynamicClient.Watch(metav1.ListOptions{
 		FieldSelector:   "metadata.name=" + integration.Name,
 		ResourceVersion: integration.ObjectMeta.ResourceVersion,
@@ -63,6 +64,21 @@ func HandleIntegrationStateChanges(ctx context.Context, integration *v1.Integrat
 
 	var lastObservedState *v1.IntegrationPhase
 
+	var handlerWrapper = func(it *v1.Integration) bool {
+		if lastObservedState == nil || *lastObservedState != it.Status.Phase {
+			lastObservedState = &it.Status.Phase
+			if !handler(it) {
+				return false
+			}
+		}
+		return true
+	}
+
+	// Check completion before starting the watch
+	if !handlerWrapper(integration) {
+		return lastObservedState, nil
+	}
+
 	for {
 		select {
 		case <-ctx.Done():
@@ -85,11 +101,8 @@ func HandleIntegrationStateChanges(ctx context.Context, integration *v1.Integrat
 						return lastObservedState, nil
 					}
 
-					if lastObservedState == nil || *lastObservedState != copy.Status.Phase {
-						lastObservedState = &copy.Status.Phase
-						if !handler(copy) {
-							return lastObservedState, nil
-						}
+					if !handlerWrapper(copy) {
+						return lastObservedState, nil
 					}
 				}
 			}
@@ -189,6 +202,21 @@ func HandlePlatformStateChanges(ctx context.Context, platform *v1.IntegrationPla
 
 	var lastObservedState *v1.IntegrationPlatformPhase
 
+	var handlerWrapper = func(pl *v1.IntegrationPlatform) bool {
+		if lastObservedState == nil || *lastObservedState != pl.Status.Phase {
+			lastObservedState = &pl.Status.Phase
+			if !handler(pl) {
+				return false
+			}
+		}
+		return true
+	}
+
+	// Check completion before starting the watch
+	if !handlerWrapper(platform) {
+		return nil
+	}
+
 	for {
 		select {
 		case <-ctx.Done():
@@ -211,11 +239,8 @@ func HandlePlatformStateChanges(ctx context.Context, platform *v1.IntegrationPla
 						return nil
 					}
 
-					if lastObservedState == nil || *lastObservedState != copy.Status.Phase {
-						lastObservedState = &copy.Status.Phase
-						if !handler(copy) {
-							return nil
-						}
+					if !handlerWrapper(copy) {
+						return nil
 					}
 				}
 			}


[camel-k] 05/14: #1199: add cronjob conditions

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 fd88d0d9115cce2bd2cf82d13620781376048043
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Jan 28 01:21:46 2020 +0100

    #1199: add cronjob conditions
---
 deploy/builder-role-kubernetes.yaml    | 10 +++++++++-
 deploy/builder-role-openshift.yaml     | 10 +++++++++-
 pkg/apis/camel/v1/integration_types.go |  6 ++++++
 pkg/trait/cron.go                      | 25 +++++++++++++++++++++++++
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/deploy/builder-role-kubernetes.yaml b/deploy/builder-role-kubernetes.yaml
index 13a0853..5a18caf 100644
--- a/deploy/builder-role-kubernetes.yaml
+++ b/deploy/builder-role-kubernetes.yaml
@@ -44,10 +44,18 @@ rules:
 - apiGroups:
   - ""
   resources:
-  - events
   - configmaps
   - secrets
   verbs:
   - get
   - list
   - watch
+- apiGroups:
+  - ""
+  resources:
+  - events
+  verbs:
+  - create
+  - get
+  - list
+  - watch
diff --git a/deploy/builder-role-openshift.yaml b/deploy/builder-role-openshift.yaml
index 48bea4a..a0ab82b 100644
--- a/deploy/builder-role-openshift.yaml
+++ b/deploy/builder-role-openshift.yaml
@@ -44,7 +44,6 @@ rules:
 - apiGroups:
   - ""
   resources:
-  - events
   - configmaps
   - secrets
   verbs:
@@ -53,6 +52,15 @@ rules:
   - watch
 - apiGroups:
   - ""
+  resources:
+  - events
+  verbs:
+  - create
+  - get
+  - list
+  - watch
+- apiGroups:
+  - ""
   - "build.openshift.io"
   resources:
   - buildconfigs
diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go
index a818587..742c296 100644
--- a/pkg/apis/camel/v1/integration_types.go
+++ b/pkg/apis/camel/v1/integration_types.go
@@ -180,6 +180,8 @@ const (
 	IntegrationConditionServiceAvailable IntegrationConditionType = "ServiceAvailable"
 	// IntegrationConditionKnativeServiceAvailable --
 	IntegrationConditionKnativeServiceAvailable IntegrationConditionType = "KnativeServiceAvailable"
+	// IntegrationConditionCronJobAvailable --
+	IntegrationConditionCronJobAvailable IntegrationConditionType = "CronJobAvailable"
 	// IntegrationConditionExposureAvailable --
 	IntegrationConditionExposureAvailable IntegrationConditionType = "ExposureAvailable"
 	// IntegrationConditionPrometheusAvailable --
@@ -213,6 +215,10 @@ const (
 	IntegrationConditionKnativeServiceAvailableReason string = "KnativeServiceAvailable"
 	// IntegrationConditionKnativeServiceNotAvailableReason --
 	IntegrationConditionKnativeServiceNotAvailableReason string = "KnativeServiceNotAvailable"
+	// IntegrationConditionCronJobAvailableReason --
+	IntegrationConditionCronJobAvailableReason string = "CronJobAvailableReason"
+	// IntegrationConditionCronJobNotAvailableReason --
+	IntegrationConditionCronJobNotAvailableReason string = "CronJobNotAvailableReason"
 	// IntegrationConditionPrometheusAvailableReason --
 	IntegrationConditionPrometheusAvailableReason string = "PrometheusAvailable"
 	// IntegrationConditionJolokiaAvailableReason --
diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go
index b2b44d6..815aa66 100644
--- a/pkg/trait/cron.go
+++ b/pkg/trait/cron.go
@@ -115,6 +115,13 @@ func newCronTrait() Trait {
 
 func (t *cronTrait) Configure(e *Environment) (bool, error) {
 	if t.Enabled != nil && !*t.Enabled {
+		e.Integration.Status.SetCondition(
+			v1.IntegrationConditionCronJobAvailable,
+			corev1.ConditionFalse,
+			v1.IntegrationConditionCronJobNotAvailableReason,
+			"explicitly disabled",
+		)
+
 		return false, nil
 	}
 
@@ -125,6 +132,11 @@ func (t *cronTrait) Configure(e *Environment) (bool, error) {
 	if t.Auto == nil || *t.Auto {
 		globalCron, err := t.getGlobalCron(e)
 		if err != nil {
+			e.Integration.Status.SetErrorCondition(
+				v1.IntegrationConditionCronJobAvailable,
+				v1.IntegrationConditionCronJobNotAvailableReason,
+				err,
+			)
 			return false, err
 		}
 
@@ -177,6 +189,12 @@ func (t *cronTrait) Configure(e *Environment) (bool, error) {
 		return false, err
 	}
 	if strategy != ControllerStrategyCronJob {
+		e.Integration.Status.SetCondition(
+			v1.IntegrationConditionCronJobAvailable,
+			corev1.ConditionFalse,
+			v1.IntegrationConditionCronJobNotAvailableReason,
+			"controller strategy: "+string(strategy),
+		)
 		return false, nil
 	}
 
@@ -198,6 +216,13 @@ func (t *cronTrait) Apply(e *Environment) error {
 			e.Resources.AddAll(maps)
 			e.Resources.Add(cronJob)
 
+			e.Integration.Status.SetCondition(
+				v1.IntegrationConditionCronJobAvailable,
+				corev1.ConditionTrue,
+				v1.IntegrationConditionCronJobAvailableReason,
+				fmt.Sprintf("CronJob name is %s", cronJob.Name),
+			)
+
 			envvar.SetVal(&e.EnvVars, "CAMEL_K_CRON_OVERRIDE", t.Components)
 		}
 	}


[camel-k] 03/14: #1199: multicasting events of dependent resources to integration

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 e110c429afd948b84040d8cc0bb02b4a8c35b11e
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Mon Jan 27 16:31:27 2020 +0100

    #1199: multicasting events of dependent resources to integration
---
 deploy/platform-integration-kit-groovy.yaml        |  4 +-
 deploy/platform-integration-kit-java.yaml          |  4 +-
 deploy/platform-integration-kit-js.yaml            |  4 +-
 deploy/platform-integration-kit-knative.yaml       |  4 +-
 deploy/platform-integration-kit-kotlin.yaml        |  4 +-
 deploy/platform-integration-kit-main.yaml          |  4 +-
 deploy/platform-integration-kit-xml.yaml           |  4 +-
 deploy/platform-integration-kit-yaml.yaml          |  4 +-
 pkg/builder/s2i/publisher.go                       |  4 ++
 pkg/controller/build/build_controller.go           |  6 +-
 pkg/controller/build/schedule_pod.go               |  3 +
 pkg/controller/integration/build_kit.go            |  8 +--
 .../integration/integration_controller.go          |  6 +-
 pkg/controller/integrationkit/build.go             |  1 +
 .../integrationkit/integrationkit_controller.go    |  6 +-
 .../integrationplatform_controller.go              |  6 +-
 pkg/events/manager.go                              | 56 ++++++++++++----
 pkg/util/kubernetes/camel_labels.go                | 74 ++++++++++++++++++++++
 18 files changed, 157 insertions(+), 45 deletions(-)

diff --git a/deploy/platform-integration-kit-groovy.yaml b/deploy/platform-integration-kit-groovy.yaml
index f8e40f3..b525c58 100644
--- a/deploy/platform-integration-kit-groovy.yaml
+++ b/deploy/platform-integration-kit-groovy.yaml
@@ -21,8 +21,8 @@ metadata:
   name: groovy
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-java.yaml b/deploy/platform-integration-kit-java.yaml
index c9f9752..511ce4f 100644
--- a/deploy/platform-integration-kit-java.yaml
+++ b/deploy/platform-integration-kit-java.yaml
@@ -21,8 +21,8 @@ metadata:
   name: java
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-js.yaml b/deploy/platform-integration-kit-js.yaml
index e8dbef2..6187905 100644
--- a/deploy/platform-integration-kit-js.yaml
+++ b/deploy/platform-integration-kit-js.yaml
@@ -21,8 +21,8 @@ metadata:
   name: js
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-knative.yaml b/deploy/platform-integration-kit-knative.yaml
index 972fc8f..74fc176 100644
--- a/deploy/platform-integration-kit-knative.yaml
+++ b/deploy/platform-integration-kit-knative.yaml
@@ -21,8 +21,8 @@ metadata:
   name: knative
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-kotlin.yaml b/deploy/platform-integration-kit-kotlin.yaml
index 1be76e4..44f5819 100644
--- a/deploy/platform-integration-kit-kotlin.yaml
+++ b/deploy/platform-integration-kit-kotlin.yaml
@@ -21,8 +21,8 @@ metadata:
   name: kotlin
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-main.yaml b/deploy/platform-integration-kit-main.yaml
index 7a3a6cf..0b5cfb9 100644
--- a/deploy/platform-integration-kit-main.yaml
+++ b/deploy/platform-integration-kit-main.yaml
@@ -21,8 +21,8 @@ metadata:
   name: main
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-xml.yaml b/deploy/platform-integration-kit-xml.yaml
index 7e31773..ab1de23 100644
--- a/deploy/platform-integration-kit-xml.yaml
+++ b/deploy/platform-integration-kit-xml.yaml
@@ -21,8 +21,8 @@ metadata:
   name: xml
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/deploy/platform-integration-kit-yaml.yaml b/deploy/platform-integration-kit-yaml.yaml
index bf223a9..1b4b0f4 100644
--- a/deploy/platform-integration-kit-yaml.yaml
+++ b/deploy/platform-integration-kit-yaml.yaml
@@ -21,8 +21,8 @@ metadata:
   name: yaml
   labels:
     app: "camel-k"
-    camel.apache.org/kit.created.by.kind: Operator
-    camel.apache.org/kit.created.by.name: camel-k-operator
+    camel.apache.org/created.by.kind: Operator
+    camel.apache.org/created.by.name: camel-k-operator
     camel.apache.org/kit.type: platform
 spec:
   dependencies:
diff --git a/pkg/builder/s2i/publisher.go b/pkg/builder/s2i/publisher.go
index ae86de8..3165587 100644
--- a/pkg/builder/s2i/publisher.go
+++ b/pkg/builder/s2i/publisher.go
@@ -71,6 +71,8 @@ func publisher(ctx *builder.Context) error {
 		},
 	}
 
+	bc.Labels = kubernetes.MergeCamelCreatorLabels(ctx.Build.Meta.Labels, bc.Labels)
+
 	err := ctx.Client.Delete(ctx.C, &bc)
 	if err != nil && !apierrors.IsNotFound(err) {
 		return errors.Wrap(err, "cannot delete build config")
@@ -100,6 +102,8 @@ func publisher(ctx *builder.Context) error {
 		},
 	}
 
+	is.Labels = kubernetes.MergeCamelCreatorLabels(ctx.Build.Meta.Labels, is.Labels)
+
 	err = ctx.Client.Delete(ctx.C, &is)
 	if err != nil && !apierrors.IsNotFound(err) {
 		return errors.Wrap(err, "cannot delete image stream")
diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go
index ddf5da7..ecb2995 100644
--- a/pkg/controller/build/build_controller.go
+++ b/pkg/controller/build/build_controller.go
@@ -208,13 +208,13 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyBuildError(r.recorder, &instance, newTarget, err)
+				events.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyBuildError(r.recorder, &instance, newTarget, err)
+					events.NotifyBuildError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -231,7 +231,7 @@ func (r *ReconcileBuild) Reconcile(request reconcile.Request) (reconcile.Result,
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyBuildUpdated(r.recorder, &instance, newTarget)
+			events.NotifyBuildUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/build/schedule_pod.go b/pkg/controller/build/schedule_pod.go
index 08b773a..f26f92e 100644
--- a/pkg/controller/build/schedule_pod.go
+++ b/pkg/controller/build/schedule_pod.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"sync"
 
+	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/pkg/errors"
 
 	corev1 "k8s.io/api/core/v1"
@@ -129,6 +130,8 @@ func (action *schedulePodAction) newBuildPod(ctx context.Context, build *v1.Buil
 		},
 	}
 
+	pod.Labels = kubernetes.MergeCamelCreatorLabels(build.Labels, pod.Labels)
+
 	for _, task := range build.Spec.Tasks {
 		if task.Builder != nil {
 			// TODO: Move the retrieval of the operator image into the controller
diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go
index e561c9f..61c8c3f 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -107,10 +107,10 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integr
 	// Add some information for post-processing, this may need to be refactored
 	// to a proper data structure
 	platformKit.Labels = map[string]string{
-		"camel.apache.org/kit.type":               v1.IntegrationKitTypePlatform,
-		"camel.apache.org/kit.created.by.kind":    v1.IntegrationKind,
-		"camel.apache.org/kit.created.by.name":    integration.Name,
-		"camel.apache.org/kit.created.by.version": integration.ResourceVersion,
+		"camel.apache.org/kit.type":           v1.IntegrationKitTypePlatform,
+		"camel.apache.org/created.by.kind":    v1.IntegrationKind,
+		"camel.apache.org/created.by.name":    integration.Name,
+		"camel.apache.org/created.by.version": integration.ResourceVersion,
 		"camel.apache.org/runtime.version":        integration.Status.RuntimeVersion,
 		"camel.apache.org/runtime.provider":       string(integration.Status.RuntimeProvider),
 	}
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 80e1911..205004b 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -260,13 +260,13 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationError(r.recorder, &instance, newTarget, err)
+				events.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyIntegrationError(r.recorder, &instance, newTarget, err)
+					events.NotifyIntegrationError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -281,7 +281,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationUpdated(r.recorder, &instance, newTarget)
+			events.NotifyIntegrationUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go
index aa1f61d..bed746f 100644
--- a/pkg/controller/integrationkit/build.go
+++ b/pkg/controller/integrationkit/build.go
@@ -90,6 +90,7 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int
 			ObjectMeta: metav1.ObjectMeta{
 				Namespace: kit.Namespace,
 				Name:      kit.Name,
+				Labels:    kubernetes.FilterCamelCreatorLabels(kit.Labels),
 			},
 			Spec: v1.BuildSpec{
 				Tasks: env.BuildTasks,
diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go
index fc87130..c86947a 100644
--- a/pkg/controller/integrationkit/integrationkit_controller.go
+++ b/pkg/controller/integrationkit/integrationkit_controller.go
@@ -227,13 +227,13 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			newTarget, err := a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationKitError(r.recorder, &instance, newTarget, err)
+				events.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
 				return reconcile.Result{}, err
 			}
 
 			if newTarget != nil {
 				if res, err := r.update(ctx, &instance, newTarget); err != nil {
-					events.NotifyIntegrationKitError(r.recorder, &instance, newTarget, err)
+					events.NotifyIntegrationKitError(ctx, r.client, r.recorder, &instance, newTarget, err)
 					return res, err
 				}
 
@@ -248,7 +248,7 @@ func (r *ReconcileIntegrationKit) Reconcile(request reconcile.Request) (reconcil
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationKitUpdated(r.recorder, &instance, newTarget)
+			events.NotifyIntegrationKitUpdated(ctx, r.client, r.recorder, &instance, newTarget)
 			break
 		}
 	}
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 37fd592..1ad9a60 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -151,13 +151,13 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			target, err = a.Handle(ctx, target)
 			if err != nil {
-				events.NotifyIntegrationPlatformError(r.recorder, &instance, target, err)
+				events.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
 				return reconcile.Result{}, err
 			}
 
 			if target != nil {
 				if err := r.client.Status().Patch(ctx, target, k8sclient.MergeFrom(&instance)); err != nil {
-					events.NotifyIntegrationPlatformError(r.recorder, &instance, target, err)
+					events.NotifyIntegrationPlatformError(ctx, r.client, r.recorder, &instance, target, err)
 					return reconcile.Result{}, err
 				}
 
@@ -174,7 +174,7 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 
 			// handle one action at time so the resource
 			// is always at its latest state
-			events.NotifyIntegrationPlatformUpdated(r.recorder, &instance, target)
+			events.NotifyIntegrationPlatformUpdated(ctx, r.client, r.recorder, &instance, target)
 			break
 		}
 	}
diff --git a/pkg/events/manager.go b/pkg/events/manager.go
index 2a792eb..5622d27 100644
--- a/pkg/events/manager.go
+++ b/pkg/events/manager.go
@@ -18,12 +18,17 @@ limitations under the License.
 package events
 
 import (
+	"context"
 	"fmt"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/client"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/log"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/tools/record"
+	runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const (
@@ -54,10 +59,13 @@ const (
 	ReasonBuildConditionChanged = "BuildConditionChanged"
 	// ReasonBuildError --
 	ReasonBuildError = "BuildError"
+
+	// ReasonRelatedObjectChanged --
+	ReasonRelatedObjectChanged = "ReasonRelatedObjectChanged"
 )
 
 // NotifyIntegrationError automatically generates error events when the integration reconcile cycle phase has an error
-func NotifyIntegrationError(recorder record.EventRecorder, old, new *v1.Integration, err error) {
+func NotifyIntegrationError(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.Integration, err error) {
 	it := old
 	if new != nil {
 		it = new
@@ -69,7 +77,7 @@ func NotifyIntegrationError(recorder record.EventRecorder, old, new *v1.Integrat
 }
 
 // NotifyIntegrationUpdated automatically generates events when the integration changes
-func NotifyIntegrationUpdated(recorder record.EventRecorder, old, new *v1.Integration) {
+func NotifyIntegrationUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.Integration) {
 	if new == nil {
 		return
 	}
@@ -79,14 +87,14 @@ func NotifyIntegrationUpdated(recorder record.EventRecorder, old, new *v1.Integr
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration", new.Name, ReasonIntegrationPhaseUpdated)
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration", new.Name, ReasonIntegrationPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration", new.Name, ReasonIntegrationConditionChanged)
 	}
 }
 
 // NotifyIntegrationKitUpdated automatically generates events when an integration kit changes
-func NotifyIntegrationKitUpdated(recorder record.EventRecorder, old, new *v1.IntegrationKit) {
+func NotifyIntegrationKitUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.IntegrationKit) {
 	if new == nil {
 		return
 	}
@@ -96,14 +104,14 @@ func NotifyIntegrationKitUpdated(recorder record.EventRecorder, old, new *v1.Int
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration Kit", new.Name, ReasonIntegrationKitPhaseUpdated)
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Kit", new.Name, ReasonIntegrationKitPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationKitPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Kit", new.Name, ReasonIntegrationKitConditionChanged)
 	}
 }
 
 // NotifyIntegrationKitError automatically generates error events when the integration kit reconcile cycle phase has an error
-func NotifyIntegrationKitError(recorder record.EventRecorder, old, new *v1.IntegrationKit, err error) {
+func NotifyIntegrationKitError(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.IntegrationKit, err error) {
 	kit := old
 	if new != nil {
 		kit = new
@@ -115,7 +123,7 @@ func NotifyIntegrationKitError(recorder record.EventRecorder, old, new *v1.Integ
 }
 
 // NotifyIntegrationPlatformUpdated automatically generates events when an integration platform changes
-func NotifyIntegrationPlatformUpdated(recorder record.EventRecorder, old, new *v1.IntegrationPlatform) {
+func NotifyIntegrationPlatformUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.IntegrationPlatform) {
 	if new == nil {
 		return
 	}
@@ -125,14 +133,14 @@ func NotifyIntegrationPlatformUpdated(recorder record.EventRecorder, old, new *v
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Integration Platform", new.Name, ReasonIntegrationPlatformPhaseUpdated)
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Integration Platform", new.Name, ReasonIntegrationPlatformPhaseUpdated)
 	if new.Status.Phase != v1.IntegrationPlatformPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Integration Platform", new.Name, ReasonIntegrationPlatformConditionChanged)
 	}
 }
 
 // NotifyIntegrationPlatformError automatically generates error events when the integration Platform reconcile cycle phase has an error
-func NotifyIntegrationPlatformError(recorder record.EventRecorder, old, new *v1.IntegrationPlatform, err error) {
+func NotifyIntegrationPlatformError(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.IntegrationPlatform, err error) {
 	p := old
 	if new != nil {
 		p = new
@@ -144,7 +152,7 @@ func NotifyIntegrationPlatformError(recorder record.EventRecorder, old, new *v1.
 }
 
 // NotifyBuildUpdated automatically generates events when a build changes
-func NotifyBuildUpdated(recorder record.EventRecorder, old, new *v1.Build) {
+func NotifyBuildUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.Build) {
 	if new == nil {
 		return
 	}
@@ -154,14 +162,14 @@ func NotifyBuildUpdated(recorder record.EventRecorder, old, new *v1.Build) {
 		oldPhase = string(old.Status.Phase)
 		oldConditions = old.Status.GetConditions()
 	}
-	notifyIfPhaseUpdated(recorder, new, oldPhase, string(new.Status.Phase), "Build", new.Name, ReasonBuildPhaseUpdated)
+	notifyIfPhaseUpdated(ctx, c, recorder, new, oldPhase, string(new.Status.Phase), "Build", new.Name, ReasonBuildPhaseUpdated)
 	if new.Status.Phase != v1.BuildPhaseNone {
 		notifyIfConditionUpdated(recorder, new, oldConditions, new.Status.GetConditions(), "Build", new.Name, ReasonBuildConditionChanged)
 	}
 }
 
 // NotifyBuildError automatically generates error events when the build reconcile cycle phase has an error
-func NotifyBuildError(recorder record.EventRecorder, old, new *v1.Build, err error) {
+func NotifyBuildError(ctx context.Context, c client.Client, recorder record.EventRecorder, old, new *v1.Build, err error) {
 	p := old
 	if new != nil {
 		p = new
@@ -172,7 +180,7 @@ func NotifyBuildError(recorder record.EventRecorder, old, new *v1.Build, err err
 	recorder.Eventf(p, corev1.EventTypeWarning, ReasonBuildError, "Cannot reconcile Build %s: %v", p.Name, err)
 }
 
-func notifyIfPhaseUpdated(recorder record.EventRecorder, new runtime.Object, oldPhase, newPhase string, resourceType, name, reason string) {
+func notifyIfPhaseUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, new runtime.Object, oldPhase, newPhase string, resourceType, name, reason string) {
 	// Update information about phase changes
 	if oldPhase != newPhase {
 		phase := newPhase
@@ -180,6 +188,10 @@ func notifyIfPhaseUpdated(recorder record.EventRecorder, new runtime.Object, old
 			phase = "[none]"
 		}
 		recorder.Eventf(new, corev1.EventTypeNormal, reason, "%s %s in phase %s", resourceType, name, phase)
+
+		if creatorRef, creator := getCreatorObject(ctx, c, new); creatorRef != nil && creator != nil {
+			recorder.Eventf(creator, corev1.EventTypeNormal, ReasonRelatedObjectChanged, "%s %s dependent resource %s (%s) changed phase to %s", creatorRef.Kind, creatorRef.Name, name, resourceType, phase)
+		}
 	}
 }
 
@@ -212,3 +224,21 @@ func getCommonChangedConditions(old, new []v1.ResourceCondition) (res []v1.Resou
 	}
 	return res
 }
+
+func getCreatorObject(ctx context.Context, c client.Client, obj runtime.Object) (ref *corev1.ObjectReference, creator runtime.Object) {
+	if ref := kubernetes.GetCamelCreator(obj); ref != nil {
+		if ref.Kind == "Integration" {
+			it := v1.NewIntegration(ref.Namespace, ref.Name)
+			key := runtimeclient.ObjectKey{
+				Namespace: ref.Namespace,
+				Name:      ref.Name,
+			}
+			if err := c.Get(ctx, key, &it); err != nil {
+				log.Infof("Cannot get information about the Integration creating resource %v: %v", ref, err)
+				return nil, nil
+			}
+			return ref, &it
+		}
+	}
+	return nil, nil
+}
diff --git a/pkg/util/kubernetes/camel_labels.go b/pkg/util/kubernetes/camel_labels.go
new file mode 100644
index 0000000..cc31559
--- /dev/null
+++ b/pkg/util/kubernetes/camel_labels.go
@@ -0,0 +1,74 @@
+/*
+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 kubernetes
+
+import (
+	"strings"
+
+	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	v1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+)
+
+// CamelCreatorLabelPrefix --
+const (
+	CamelCreatorLabelPrefix = "camel.apache.org/created.by"
+
+	CamelCreatorLabelKind = CamelCreatorLabelPrefix + ".kind"
+	CamelCreatorLabelName = CamelCreatorLabelPrefix + ".name"
+)
+
+// FilterCamelCreatorLabels is used to inherit the creator information among resources
+func FilterCamelCreatorLabels(source map[string]string) map[string]string {
+	res := make(map[string]string)
+	for k, v := range source {
+		if strings.HasPrefix(k, CamelCreatorLabelPrefix) {
+			res[k] = v
+		}
+	}
+	return res
+}
+
+// MergeCamelCreatorLabels is used to inject the creator information from another set of labels
+func MergeCamelCreatorLabels(source map[string]string, target map[string]string) map[string]string {
+	if target == nil {
+		target = make(map[string]string)
+	}
+	for k, v := range FilterCamelCreatorLabels(source) {
+		target[k] = v
+	}
+	return target
+}
+
+// GetCamelCreator returns the Camel creator object referenced by this runtime object, if present
+func GetCamelCreator(obj runtime.Object) *v1.ObjectReference {
+	if m, ok := obj.(metav1.Object); ok {
+		kind := m.GetLabels()[CamelCreatorLabelKind]
+		name := m.GetLabels()[CamelCreatorLabelName]
+		if kind != "" && name != "" {
+			return &v1.ObjectReference{
+				Kind:       kind,
+				Namespace:  m.GetNamespace(),
+				Name:       name,
+				APIVersion: camelv1.SchemeGroupVersion.String(),
+			}
+		}
+	}
+	return nil
+}


[camel-k] 07/14: 1199: fix cronjob conditions and message

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 6e994c0f27b1d7484ddc2995705b04ca80886bb5
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Jan 28 01:39:09 2020 +0100

    1199: fix cronjob conditions and message
---
 pkg/trait/cron.go            | 27 +++++++++++++++++++++------
 pkg/trait/knative_service.go |  4 ++--
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go
index 815aa66..4445438 100644
--- a/pkg/trait/cron.go
+++ b/pkg/trait/cron.go
@@ -180,21 +180,36 @@ func (t *cronTrait) Configure(e *Environment) (bool, error) {
 
 	// Fallback strategy can be implemented in any other controller
 	if t.Fallback != nil && *t.Fallback {
+		if e.InPhase(v1.IntegrationKitPhaseReady, v1.IntegrationPhaseDeploying) {
+			e.Integration.Status.SetCondition(
+				v1.IntegrationConditionCronJobAvailable,
+				corev1.ConditionFalse,
+				v1.IntegrationConditionCronJobNotAvailableReason,
+				"fallback strategy selected",
+			)
+		}
 		return true, nil
 	}
 
 	// CronJob strategy requires common schedule
 	strategy, err := e.DetermineControllerStrategy(t.Ctx, t.Client)
 	if err != nil {
-		return false, err
-	}
-	if strategy != ControllerStrategyCronJob {
-		e.Integration.Status.SetCondition(
+		e.Integration.Status.SetErrorCondition(
 			v1.IntegrationConditionCronJobAvailable,
-			corev1.ConditionFalse,
 			v1.IntegrationConditionCronJobNotAvailableReason,
-			"controller strategy: "+string(strategy),
+			err,
 		)
+		return false, err
+	}
+	if strategy != ControllerStrategyCronJob {
+		if e.InPhase(v1.IntegrationKitPhaseReady, v1.IntegrationPhaseDeploying) {
+			e.Integration.Status.SetCondition(
+				v1.IntegrationConditionCronJobAvailable,
+				corev1.ConditionFalse,
+				v1.IntegrationConditionCronJobNotAvailableReason,
+				fmt.Sprintf("different controller strategy used (%s)", string(strategy)),
+			)
+		}
 		return false, nil
 	}
 
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 37f18f2..9c9e671 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -115,7 +115,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 			v1.IntegrationConditionKnativeServiceAvailable,
 			corev1.ConditionFalse,
 			v1.IntegrationConditionKnativeServiceNotAvailableReason,
-			fmt.Sprintf("different controller strategy chosen (%s)", string(ControllerStrategyDeployment)),
+			fmt.Sprintf("different controller strategy used (%s)", string(ControllerStrategyDeployment)),
 		)
 
 		// A controller is already present for the integration
@@ -137,7 +137,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
 			v1.IntegrationConditionKnativeServiceAvailable,
 			corev1.ConditionFalse,
 			v1.IntegrationConditionKnativeServiceNotAvailableReason,
-			"controller strategy: "+string(strategy),
+			fmt.Sprintf("different controller strategy used (%s)", string(strategy)),
 		)
 
 		return false, nil


[camel-k] 11/14: Fix #1199: fix lint

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 2ea63212b43c2bdabe2ed9c2cc3a057377c8d47e
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Fri Feb 21 11:46:13 2020 +0100

    Fix #1199: fix lint
---
 pkg/cmd/operator/operator.go            | 1 +
 pkg/controller/integration/build_kit.go | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index 1347e1d..6f43b16 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -114,6 +114,7 @@ func Run() {
 
 	// Configure event broadcaster
 	var eventBroadcaster record.EventBroadcaster
+	// nolint: gocritic
 	if ok, err := kubernetes.CheckPermission(c, corev1.GroupName, "events", namespace, "", "create"); err != nil {
 		log.Error(err, "cannot check permissions for configuring event broadcaster")
 	} else if !ok {
diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go
index 61c8c3f..a3e4fe6 100644
--- a/pkg/controller/integration/build_kit.go
+++ b/pkg/controller/integration/build_kit.go
@@ -111,8 +111,8 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integr
 		"camel.apache.org/created.by.kind":    v1.IntegrationKind,
 		"camel.apache.org/created.by.name":    integration.Name,
 		"camel.apache.org/created.by.version": integration.ResourceVersion,
-		"camel.apache.org/runtime.version":        integration.Status.RuntimeVersion,
-		"camel.apache.org/runtime.provider":       string(integration.Status.RuntimeProvider),
+		"camel.apache.org/runtime.version":    integration.Status.RuntimeVersion,
+		"camel.apache.org/runtime.provider":   string(integration.Status.RuntimeProvider),
 	}
 
 	// Set the kit to have the same characteristics as the integrations