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

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

commit 01d435e314cfeb75e64189514847f1358954e86e
Author: phantomjinx <p.g.richard...@phantomjinx.co.uk>
AuthorDate: Wed Sep 15 14:38:18 2021 +0100

    feature(#1979): New Kustomize-based installer
    
    * script/platform-check.sh
    * cmd/util/platform-check
     * Determines the type of cluster user currently is accessing, namely
       openshift or kubernetes
    
    * vfs-gen
     * Adds extra filters for ignoring files that should not be in resources
    
    * config/...
     * Tidies up directory and resources
     * Moves openshift-only resources into a kustomize-handled directory of
       their own - easier to manage
     * Adds scorecard tests for use in bundle
     * Prometheus monitoring to bundle
      * This breaks installation of the operator via OLM due to attempts to
        apply PromethusRule fail with no CRD found for monitoring.coreos.com/v1
      * True for e2e tests using kind but not on Openshift
      * Prometheus rules should be installed separately where users are sure the
        environment supports them
    
    * install/...
     * Adds kustomize installer provisioning
     * make example: installing example camel-k integration
     * make operator: installing camel-k operator
     * make platform: installing camel-k integration platform
     * make setup-cluster: installing cluster-wide CRD & RBAC resources only
     * make setup: installing RBAC resources & calls setup-cluster
     * Makefile provides sciptable auto-configuration of kustomize files
     * kustomize can be executed over directories manually
    
    * pkg/...
     * Fixes typo in schema_types.go - causes warning in bundle generation
     * Updates resources names and paths
    
    * script/Makefile
     * Originally, considered allowing overriding of IMAGE_NAME & VERSION but
       this 'loses' the default values which are required for the
      `kustomize set image ...` command.
     * Revert overriding of IMAGE_NAME & VERSION
     * Allows easy updating of ancillary tools versions & downloads them if
       not available
     * Adds CUSTOM_IMAGE & CUSTOM_VERSION that default to IMAGE_NAME & VERSION
       but can be overridden, whilst also preserving original values
    
    * PROJECT
     * Updates PROJECT to version 3 due to use of operator-sdk 1.5.0
---
 .gitignore                                         |   8 +
 PROJECT                                            |   2 +-
 cmd/util/platform-check/main.go                    |  68 +++++
 cmd/util/vfs-gen/main.go                           |  23 ++
 config/crd/kustomization.yaml                      |  21 +-
 config/default/kustomization.yaml                  |  87 ------
 config/manager/kustomization.yaml                  |   3 +
 config/manifests/kustomization.yaml                |  12 +-
 config/prometheus/kustomization.yaml               |   2 +
 config/rbac/kustomization.yaml                     |  15 +-
 .../openshift}/kustomization.yaml                  |  10 +
 ...tor-cluster-role-console-binding-openshift.yaml |   3 +-
 .../operator-cluster-role-console-openshift.yaml   |   0
 .../operator-role-binding-openshift.yaml           |   0
 .../{ => openshift}/operator-role-openshift.yaml   |   0
 ...tor-role-kubernetes.yaml => operator-role.yaml} |   0
 config/rbac/user-cluster-role.yaml                 |   2 +-
 .../user-global-kamelet-viewer-role-binding.yaml   |   4 +
 config/rbac/user-global-kamelet-viewer-role.yaml   |   4 +
 config/samples/kustomization.yaml                  |   5 +
 .../kustomization.yaml => scorecard/.vfsignore}    |   2 +-
 config/scorecard/bases/config.yaml                 |   7 +
 config/scorecard/kustomization.yaml                |  17 ++
 config/scorecard/patches/basic.config.yaml         |  10 +
 config/scorecard/patches/olm.config.yaml           |  20 ++
 e2e/support/test_support.go                        |   2 +-
 install/Makefile                                   | 338 +++++++++++++++++++++
 .../example}/kustomization.yaml                    |   7 +-
 .../operator}/kustomization.yaml                   |  37 ++-
 .../operator/patch-image-pull-policy-always.yaml   |  10 +
 .../operator/patch-node-selector.yaml              |  25 +-
 .../operator/patch-ports.yaml                      |  12 +-
 .../operator/patch-resource-requirements.yaml      |  29 +-
 .../operator/patch-toleration.yaml                 |  24 +-
 .../operator/patch-watch-namespace-global.yaml     |   6 +-
 .../platform}/kustomization.yaml                   |   9 +
 install/platform/patch-integration-platform.yaml   | 133 ++++++++
 install/release/Makefile                           |  60 ++++
 install/script/Makefile                            |   1 +
 install/script/check_platform.sh                   |   1 +
 .../setup-cluster}/kustomization.yaml              |   8 +-
 .../setup}/kustomization.yaml                      |   3 +
 install/setup/patch-role-to-clusterrole.yaml       |   3 +
 .../patch-rolebinding-to-clusterrolebinding.yaml   |   9 +
 pkg/apis/camel/v1alpha1/jsonschema_types.go        |   2 +-
 pkg/install/cluster.go                             |   6 +-
 pkg/install/operator.go                            |   8 +-
 pkg/resources/resources.go                         |  87 +++---
 .../kustomization.yaml => script/.vfsignore        |   2 +-
 script/Makefile                                    | 120 ++++++--
 script/check_platform.sh                           |  89 ++++++
 script/set_version.sh                              |  11 +-
 52 files changed, 1113 insertions(+), 254 deletions(-)

diff --git a/.gitignore b/.gitignore
index b6b2195..6a7118a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
 # Binary files
 /kamel
 /license-check
+/**/platform-check
 
 # Config files
 /kamel-config.yaml
@@ -153,3 +154,10 @@ mvnw text eol=lf
 .history
 
 # End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
+
+### config kustomize ###
+config/**/*.gen.tmpl
+config/**/*.gen.yaml
+config/**/*.gen.json
+
+release/*-installer*
diff --git a/PROJECT b/PROJECT
index a1cee1e..349993f 100644
--- a/PROJECT
+++ b/PROJECT
@@ -24,6 +24,6 @@ resources:
 - group: camel
   kind: Kamelet
   version: v1alpha1
-version: 3-alpha
+version: "3"
 plugins:
   go.sdk.operatorframework.io/v2-alpha: {}
diff --git a/cmd/util/platform-check/main.go b/cmd/util/platform-check/main.go
new file mode 100644
index 0000000..1aca5bc
--- /dev/null
+++ b/cmd/util/platform-check/main.go
@@ -0,0 +1,68 @@
+/*
+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 main
+
+import (
+       "fmt"
+       "os"
+       "strings"
+
+       "k8s.io/client-go/kubernetes"
+       "k8s.io/client-go/rest"
+       "sigs.k8s.io/controller-runtime/pkg/client/config"
+)
+
+func main() {
+       fmt.Println(platformId())
+}
+
+func platformId() string {
+       client := ApiClient()
+       _, apiResourceLists, err := 
client.Discovery().ServerGroupsAndResources()
+       exitOnError(err)
+
+       for _, apiResList := range apiResourceLists {
+               // Should be version independant just in case image api is ever 
upgraded
+               if strings.Contains(apiResList.GroupVersion, 
"image.openshift.io") {
+                       return "openshift"
+               }
+       }
+
+       return "kubernetes"
+}
+
+func exitOnError(err error) {
+       if err != nil {
+               fmt.Println("ERROR:", err)
+               os.Exit(1)
+       }
+}
+
+func RestConfig() (c *rest.Config) {
+       restConfig, err := config.GetConfig()
+       exitOnError(err)
+
+       return restConfig
+}
+
+func ApiClient() kubernetes.Interface {
+       apiClient, err := kubernetes.NewForConfig(RestConfig())
+       exitOnError(err)
+
+       return apiClient
+}
diff --git a/cmd/util/vfs-gen/main.go b/cmd/util/vfs-gen/main.go
index 6ad7060..17f2189 100644
--- a/cmd/util/vfs-gen/main.go
+++ b/cmd/util/vfs-gen/main.go
@@ -92,8 +92,13 @@ func main() {
        // Filter un-interesting files
        //
        fs = filter.Skip(fs, filter.FilesWithExtensions(".go"))
+       fs = filter.Skip(fs, func(path string, fi os.FileInfo) bool {
+               return strings.HasSuffix(path, ".gen.yaml") || 
strings.HasSuffix(path, ".gen.json")
+       })
        fs = filter.Skip(fs, NamedFilesFilter("kustomization.yaml"))
+       fs = filter.Skip(fs, NamedFilesFilter("Makefile"))
        fs = filter.Skip(fs, NamedFilesFilter("auto-generated.txt"))
+       fs = filter.Skip(fs, BigFilesFilter(1048576)) // 1M
        fs = filter.Skip(fs, func(path string, fi os.FileInfo) bool {
                for _, ex := range exclusions {
                        if strings.HasPrefix(path, ex) {
@@ -163,6 +168,24 @@ func NamedFilesFilter(names ...string) func(path string, 
fi os.FileInfo) bool {
        }
 }
 
+//
+// If file is bigger than maximum size (in bytes) then exclude
+//
+func BigFilesFilter(size int) func(path string, fi os.FileInfo) bool {
+       return func(path string, fi os.FileInfo) bool {
+               if fi.IsDir() {
+                       return false
+               }
+
+               if fi.Size() > int64(size) {
+                       log.Printf("Warning: File %s is skipped due to being %d 
bytes (greater than maximum %d bytes)", path, fi.Size(), size)
+                       return true
+               }
+
+               return false
+       }
+}
+
 func calcExclusions(root string, dirNames []string) []string {
        var exclusions []string
 
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 1dc5488..d26003e 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -14,10 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
 
-# This kustomization.yaml is not intended to be run by itself,
-# since it depends on service name and namespace that are out of this 
kustomize package.
-# It should be run by config/default
 resources:
 - bases/camel.apache.org_builds.yaml
 - bases/camel.apache.org_camelcatalogs.yaml
@@ -26,19 +25,3 @@ resources:
 - bases/camel.apache.org_integrations.yaml
 - bases/camel.apache.org_kameletbindings.yaml
 - bases/camel.apache.org_kamelets.yaml
-# +kubebuilder:scaffold:crdkustomizeresource
-
-patchesStrategicMerge:
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] 
prefix.
-# patches here are for enabling the conversion webhook for each CRD
-#- patches/webhook_in_memcacheds.yaml
-# +kubebuilder:scaffold:crdkustomizewebhookpatch
-
-# [CERTMANAGER] To enable webhook, uncomment all the sections with 
[CERTMANAGER] prefix.
-# patches here are for enabling the CA injection for each CRD
-#- patches/cainjection_in_memcacheds.yaml
-# +kubebuilder:scaffold:crdkustomizecainjectionpatch
-
-# the following config is for teaching kustomize how to do kustomization for 
CRDs.
-#configurations:
-#- kustomizeconfig.yaml
diff --git a/config/default/kustomization.yaml 
b/config/default/kustomization.yaml
deleted file mode 100644
index 23ae005..0000000
--- a/config/default/kustomization.yaml
+++ /dev/null
@@ -1,87 +0,0 @@
-# ---------------------------------------------------------------------------
-# 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.
-# ---------------------------------------------------------------------------
-
-# Adds namespace to all resources.
-#namespace:
-
-# Value of this field is prepended to the
-# names of all resources, e.g. a deployment named
-# "wordpress" becomes "alices-wordpress".
-# Note that it should also match with the prefix (text before '-') of the 
namespace
-# field above.
-#namePrefix: memcached-operator-
-
-# Labels to add to all resources and selectors.
-commonLabels:
-  app: camel-k
-
-bases:
-- ../crd
-- ../rbac
-- ../manager
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] 
prefix including the one in
-# crd/kustomization.yaml
-#- ../webhook
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 
'CERTMANAGER'. 'WEBHOOK' components are required.
-#- ../certmanager
-# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 
'PROMETHEUS'.
-- ../prometheus
-
-patchesStrategicMerge:
-  # Protect the /metrics endpoint by putting it behind auth.
-  # If you want your controller-manager to expose the /metrics
-  # endpoint w/o any authn/z, please comment the following line.
-#- manager_auth_proxy_patch.yaml
-
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] 
prefix including the one in
-# crd/kustomization.yaml
-#- manager_webhook_patch.yaml
-
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 
'CERTMANAGER'.
-# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA 
injection in the admission webhooks.
-# 'CERTMANAGER' needs to be enabled to use ca injection
-#- webhookcainjection_patch.yaml
-
-# the following config is for teaching kustomize how to do var substitution
-vars:
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 
'CERTMANAGER' prefix.
-#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
-#  objref:
-#    kind: Certificate
-#    group: cert-manager.io
-#    version: v1alpha2
-#    name: serving-cert # this name should match the one in certificate.yaml
-#  fieldref:
-#    fieldpath: metadata.namespace
-#- name: CERTIFICATE_NAME
-#  objref:
-#    kind: Certificate
-#    group: cert-manager.io
-#    version: v1alpha2
-#    name: serving-cert # this name should match the one in certificate.yaml
-#- name: SERVICE_NAMESPACE # namespace of the service
-#  objref:
-#    kind: Service
-#    version: v1
-#    name: webhook-service
-#  fieldref:
-#    fieldpath: metadata.namespace
-#- name: SERVICE_NAME
-#  objref:
-#    kind: Service
-#    version: v1
-#    name: webhook-service
diff --git a/config/manager/kustomization.yaml 
b/config/manager/kustomization.yaml
index e6eeabc..895978a 100644
--- a/config/manager/kustomization.yaml
+++ b/config/manager/kustomization.yaml
@@ -15,6 +15,9 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
 resources:
 - operator-deployment.yaml
 - operator-service-account.yaml
diff --git a/config/manifests/kustomization.yaml 
b/config/manifests/kustomization.yaml
index 3dba3bd..7842251 100644
--- a/config/manifests/kustomization.yaml
+++ b/config/manifests/kustomization.yaml
@@ -14,9 +14,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+# Labels to add to all resources and selectors.
+commonLabels:
+  app: camel-k
 
 resources:
-- ../default
+- ../manager
+- ../crd
 - ../samples
 - ../scorecard
-- ./bases/camel-k.clusterserviceversion.yaml
+- ../rbac
+- ../rbac/openshift
diff --git a/config/prometheus/kustomization.yaml 
b/config/prometheus/kustomization.yaml
index 4cf497f..a14ee15 100644
--- a/config/prometheus/kustomization.yaml
+++ b/config/prometheus/kustomization.yaml
@@ -16,3 +16,5 @@
 # ---------------------------------------------------------------------------
 
 resources:
+- operator-pod-monitor.yaml
+- operator-prometheus-rule.yaml
diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml
index a1f09b3..4b84f1c 100644
--- a/config/rbac/kustomization.yaml
+++ b/config/rbac/kustomization.yaml
@@ -15,22 +15,27 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# rbac resources applicable for all kubernetes platforms
+#
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
 resources:
+- user-global-kamelet-viewer-role.yaml
+- user-global-kamelet-viewer-role-binding.yaml
+- user-cluster-role.yaml
 - operator-role-events.yaml
 - operator-role-knative.yaml
-- operator-role-kubernetes.yaml
+- operator-role.yaml
 - operator-role-leases.yaml
-- operator-role-openshift.yaml
 - operator-role-service-binding.yaml
 - operator-role-podmonitors.yaml
 - operator-role-strimzi.yaml
 - operator-role-binding-events.yaml
 - operator-role-binding-knative.yaml
 - operator-role-binding-leases.yaml
-- operator-role-binding-openshift.yaml
 - operator-role-binding-service-binding.yaml
 - operator-role-binding-podmonitors.yaml
 - operator-role-binding-strimzi.yaml
 - operator-role-binding.yaml
-- operator-cluster-role-console-openshift.yaml
-- operator-cluster-role-console-binding-openshift.yaml
diff --git a/config/prometheus/kustomization.yaml 
b/config/rbac/openshift/kustomization.yaml
similarity index 76%
copy from config/prometheus/kustomization.yaml
copy to config/rbac/openshift/kustomization.yaml
index 4cf497f..2813c7a 100644
--- a/config/prometheus/kustomization.yaml
+++ b/config/rbac/openshift/kustomization.yaml
@@ -15,4 +15,14 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# rbac resources applicable for only openshift platforms
+#
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
 resources:
+- operator-cluster-role-console-binding-openshift.yaml
+- operator-cluster-role-console-openshift.yaml
+- operator-role-openshift.yaml
+- operator-role-binding-openshift.yaml
diff --git a/config/rbac/operator-cluster-role-console-binding-openshift.yaml 
b/config/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml
similarity index 94%
rename from config/rbac/operator-cluster-role-console-binding-openshift.yaml
rename to 
config/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml
index c900f9e..fef037a 100644
--- a/config/rbac/operator-cluster-role-console-binding-openshift.yaml
+++ b/config/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml
@@ -24,7 +24,8 @@ metadata:
 subjects:
 - kind: ServiceAccount
   name: camel-k-operator
+  namespace: placeholder
 roleRef:
   kind: ClusterRole
-  name: camel-k-operator-openshift
+  name: camel-k-operator-console-openshift
   apiGroup: rbac.authorization.k8s.io
diff --git a/config/rbac/operator-cluster-role-console-openshift.yaml 
b/config/rbac/openshift/operator-cluster-role-console-openshift.yaml
similarity index 100%
rename from config/rbac/operator-cluster-role-console-openshift.yaml
rename to config/rbac/openshift/operator-cluster-role-console-openshift.yaml
diff --git a/config/rbac/operator-role-binding-openshift.yaml 
b/config/rbac/openshift/operator-role-binding-openshift.yaml
similarity index 100%
copy from config/rbac/operator-role-binding-openshift.yaml
copy to config/rbac/openshift/operator-role-binding-openshift.yaml
diff --git a/config/rbac/operator-role-openshift.yaml 
b/config/rbac/openshift/operator-role-openshift.yaml
similarity index 100%
rename from config/rbac/operator-role-openshift.yaml
rename to config/rbac/openshift/operator-role-openshift.yaml
diff --git a/config/rbac/operator-role-kubernetes.yaml 
b/config/rbac/operator-role.yaml
similarity index 100%
rename from config/rbac/operator-role-kubernetes.yaml
rename to config/rbac/operator-role.yaml
diff --git a/config/rbac/user-cluster-role.yaml 
b/config/rbac/user-cluster-role.yaml
index c37b6ff..1a901d5 100644
--- a/config/rbac/user-cluster-role.yaml
+++ b/config/rbac/user-cluster-role.yaml
@@ -18,7 +18,7 @@
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
-  name: camel-k:edit
+  name: camel-k-edit
   labels:
     app: "camel-k"
     # Add these permissions to the "admin" and "edit" default roles.
diff --git a/config/rbac/user-global-kamelet-viewer-role-binding.yaml 
b/config/rbac/user-global-kamelet-viewer-role-binding.yaml
index 62fd38a..f87cf8b 100644
--- a/config/rbac/user-global-kamelet-viewer-role-binding.yaml
+++ b/config/rbac/user-global-kamelet-viewer-role-binding.yaml
@@ -15,6 +15,10 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# RoleBinding installed in the operator namespace
+# to allow access to operator installed kamelets
+#
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
diff --git a/config/rbac/user-global-kamelet-viewer-role.yaml 
b/config/rbac/user-global-kamelet-viewer-role.yaml
index 80bc061..52d78ab 100644
--- a/config/rbac/user-global-kamelet-viewer-role.yaml
+++ b/config/rbac/user-global-kamelet-viewer-role.yaml
@@ -15,6 +15,10 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# Role installed in the operator namespace
+# to allow access to operator installed kamelets
+#
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
diff --git a/config/samples/kustomization.yaml 
b/config/samples/kustomization.yaml
index 1791327..1c7e1bb 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -15,6 +15,11 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# * patches/integration-platform-patch.yaml
+# customizes the integration platform custom resource
+# Edit the patch manually to add required configuration
+#
 resources:
 - bases/camel_v1_integrationplatform.yaml
 - bases/camel_v1_integration.yaml
diff --git a/config/prometheus/kustomization.yaml b/config/scorecard/.vfsignore
similarity index 95%
copy from config/prometheus/kustomization.yaml
copy to config/scorecard/.vfsignore
index 4cf497f..7fcceda 100644
--- a/config/prometheus/kustomization.yaml
+++ b/config/scorecard/.vfsignore
@@ -15,4 +15,4 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-resources:
+# This dir and subdirs are not included in VFS
diff --git a/config/scorecard/bases/config.yaml 
b/config/scorecard/bases/config.yaml
new file mode 100644
index 0000000..c770478
--- /dev/null
+++ b/config/scorecard/bases/config.yaml
@@ -0,0 +1,7 @@
+apiVersion: scorecard.operatorframework.io/v1alpha3
+kind: Configuration
+metadata:
+  name: config
+stages:
+- parallel: true
+  tests: []
diff --git a/config/scorecard/kustomization.yaml 
b/config/scorecard/kustomization.yaml
index 3baaf37..7fbd507 100644
--- a/config/scorecard/kustomization.yaml
+++ b/config/scorecard/kustomization.yaml
@@ -14,3 +14,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+
+resources:
+- bases/config.yaml
+patchesJson6902:
+- path: patches/basic.config.yaml
+  target:
+    group: scorecard.operatorframework.io
+    version: v1alpha3
+    kind: Configuration
+    name: config
+- path: patches/olm.config.yaml
+  target:
+    group: scorecard.operatorframework.io
+    version: v1alpha3
+    kind: Configuration
+    name: config
+# +kubebuilder:scaffold:patchesJson6902
diff --git a/config/scorecard/patches/basic.config.yaml 
b/config/scorecard/patches/basic.config.yaml
new file mode 100644
index 0000000..e7fa305
--- /dev/null
+++ b/config/scorecard/patches/basic.config.yaml
@@ -0,0 +1,10 @@
+- op: add
+  path: /stages/0/tests/-
+  value:
+    entrypoint:
+    - scorecard-test
+    - basic-check-spec
+    image: quay.io/operator-framework/scorecard-test:master
+    labels:
+      suite: basic
+      test: basic-check-spec-test
diff --git a/config/scorecard/patches/olm.config.yaml 
b/config/scorecard/patches/olm.config.yaml
new file mode 100644
index 0000000..44fbf37
--- /dev/null
+++ b/config/scorecard/patches/olm.config.yaml
@@ -0,0 +1,20 @@
+- op: add
+  path: /stages/0/tests/-
+  value:
+    entrypoint:
+    - scorecard-test
+    - olm-bundle-validation
+    image: quay.io/operator-framework/scorecard-test:master
+    labels:
+      suite: olm
+      test: olm-bundle-validation-test
+- op: add
+  path: /stages/0/tests/-
+  value:
+    entrypoint:
+    - scorecard-test
+    - olm-crds-have-validation
+    image: quay.io/operator-framework/scorecard-test:master
+    labels:
+      suite: olm
+      test: olm-crds-have-validation-test
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 3752897..1caf64d 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -1148,7 +1148,7 @@ func CreateOperatorRole(ns string) (err error) {
                // This should ideally be removed from the common RBAC manifest.
                customizer = install.RemoveIngressRoleCustomizer
        }
-       err = install.Resource(TestContext, TestClient(), ns, true, customizer, 
"/rbac/operator-role-kubernetes.yaml")
+       err = install.Resource(TestContext, TestClient(), ns, true, customizer, 
"/rbac/operator-role.yaml")
        if err != nil {
                return err
        }
diff --git a/install/Makefile b/install/Makefile
new file mode 100644
index 0000000..8d321c6
--- /dev/null
+++ b/install/Makefile
@@ -0,0 +1,338 @@
+# 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.
+
+#
+# Allows for resources to be loaded from outside the root location of
+# the kustomize config file. Ensures that resource don't need to be
+# copied around the file system.
+#
+# See https://kubectl.docs.kubernetes.io/faq/kustomize
+#
+KOPTIONS := --load-restrictor LoadRestrictionsNone
+
+#
+# Include the main camel-k Makefile containing
+# basic common recipes like kustomize and vars
+# like VERSION
+#
+include script/Makefile
+
+#
+# Vars that can be overridden by external env vars
+#
+DRY_RUN ?= false
+NAMESPACE ?= camel-k
+
+# Global: [true|false]
+# - On setup: will promote roles and bindings to cluster-level
+# - On operator: set namespace to all using WATCH_NAMESPACE env var
+GLOBAL ?= false
+# Always Pull Images: [true|false]
+ALWAYS_PULL_IMAGES ?= false
+# Monitoring: [true|false]
+# - On operator: will add the prometheus resources to install
+MONITORING ?= false
+# Monitoring Port: integer
+MONITORING_PORT ?= 8080
+# Health Port: integer
+HEALTH_PORT ?= 8081
+
+CONFIG := ../config
+RBAC_OS := $(CONFIG)/rbac/openshift
+RBAC_GLOBAL := global
+OPERATOR := operator
+PLACEHOLDER := placeholder
+YAML := yaml
+
+# Setup patches
+ROLE_TO_CROLE_PATCH := patch-role-to-clusterrole
+ROLEBIN_TO_CROLEBIN_PATCH := patch-rolebinding-to-clusterrolebinding
+# Operator patches
+PORTS_PATCH := patch-ports
+IMAGE_PULL_POLICY_PATCH := patch-image-pull-policy-always
+WATCH_NAMESPACE_PATCH := patch-watch-namespace-global
+# Platform patches
+INT_PLATFORM_PATCH := platform/patch-integration-platform
+
+#
+# Macro for editing kustomization to define
+# the image reference
+#
+# Parameter: directory of the kustomization.yaml
+#
+define set-kustomize-image
+       $(if $(filter $(IMAGE_NAME),$(CUSTOM_IMAGE):$(CUSTOM_VERSION)),,\
+               @cd $(1) && $(KUSTOMIZE) edit set image 
$(IMAGE_NAME)=$(CUSTOM_IMAGE):$(CUSTOM_VERSION))
+endef
+
+#
+# Macro for editing kustomization to define
+# the namespace
+#
+# Parameter: directory of the kustomization.yaml
+#
+define set-kustomize-namespace
+       @cd $(1) && $(KUSTOMIZE) edit set namespace $(NAMESPACE)
+endef
+
+#
+# Add or remove a patch on a kustomization.yaml
+# targetting a kind of resource
+#
+# Parameters:
+# * directory of the kustomization.yaml
+# * [add, remove]
+# * path of patch
+# * kind of resources, eg. Deployment, Role
+#
+define add-remove-kind-patch
+       @(cd $(1) && \
+               $(KUSTOMIZE) edit $(2) patch --path $(3) --kind $(4))
+endef
+
+#
+# Macro for adding / removing the prometheus resources for monitoring
+#
+define add-remove-operator-monitoring
+       cd $(1) && \
+               $(KUSTOMIZE) edit $(2) resource ../$(CONFIG)/prometheus
+endef
+
+.PHONY: have-platform check_admin setup-cluster .setup-kubernetes 
.setup-openshift setup
+
+#
+# Determine the platform of the cluster based on
+# either the use of querying through a go-client
+# or using an installed client, ie. oc or kubectl
+#
+find-platform:
+ifndef PLATFORM
+PLATFORM=$(shell script/check_platform.sh)
+endif
+
+#
+# Checks if the cluster platform has been defined correctly either by the user
+# or by the platform_check script.
+#
+have-platform: find-platform
+ifeq ($(PLATFORM),openshift)
+       @echo Platform identified as 'openshift'
+else ifeq ($(PLATFORM),kubernetes)
+       @echo Platform identified as 'kubernetes'
+else
+       @echo "****"
+       @echo "**** ERROR: Cannot continue as cluster platform cannot be 
identified ****"
+       @echo "****"
+       @exit 1
+endif
+
+#
+# Checks if the cluster user has the necessary privileges to be a cluster-admin
+# In this case if the user can list the CRDs then probably a cluster-admin
+#
+check-admin: kubectl
+       @output=$$(kubectl get crd 2>&1) || (echo "****" && echo "**** ERROR: 
Cannot continue as user is not a Cluster-Admin ****" && echo "****"; exit 1)
+
+#
+# Setup the cluster installation by installing crds and cluster roles.
+#
+# Will either call setup-cluster-openshift (then setup-cluster-kubernetes) or
+# setup-cluster-kubernetes depending on the identity of the cluster
+#
+# Cluster-admin privileges are required.
+#
+# PARAMETERS:
+#   NAMESPACE: Sets the namespace for the resources
+#   PLATFORM:  Override the discovered platform, if required
+#   DRY_RUN:     true - Prints the resources to be applied instead of applying 
them
+#
+setup-cluster: check-admin have-platform kustomize kubectl
+# Set the namespace in the setup-cluster kustomization yaml
+       @$(call set-kustomize-namespace,$@)
+ifeq ($(PLATFORM), openshift)
+       @for res in $(RBAC_OS)/operator-cluster*; do \
+               (cd $@ && $(KUSTOMIZE) edit add resource ../$$res); \
+       done
+endif
+#
+# Build the resources
+# Post-process ClusterRoleBindings to fix the namespace in the refs (not yet 
handled by kustomize)
+# Either apply to the cluster or output to CLI
+#
+ifeq ($(DRY_RUN), false)
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | \
+               sed 's/$(PLACEHOLDER)/$(NAMESPACE)/' | \
+               kubectl apply -f -
+else
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | \
+               sed 's/$(PLACEHOLDER)/$(NAMESPACE)/'
+endif
+
+#
+# Setup the installation by installing roles and granting
+# privileges for the installing operator.
+#
+# Cluster-admin privileges are required.
+#
+# PARAMETERS:
+#   NAMESPACE: Sets the namespace for the resources
+#   GLOBAL:    Converts all roles & bindings to cluster-level [true|false]
+#   PLATFORM:  Override the discovered platform, if required
+#   DRY_RUN:     true - Prints the resources to be applied instead of applying 
them
+#
+setup: setup-cluster
+# Set the namespace in the setup kustomization yaml
+       @$(call set-kustomize-namespace,$@)
+# If GLOBAL then add the conversion patches for all roles and rolebindings
+ifeq ($(GLOBAL),true)
+       @$(call 
add-remove-kind-patch,setup,add,$(ROLE_TO_CROLE_PATCH).$(YAML),Role)
+       @$(call 
add-remove-kind-patch,setup,add,$(ROLEBIN_TO_CROLEBIN_PATCH).$(YAML),RoleBinding)
+else
+       @$(call 
add-remove-kind-patch,setup,remove,$(ROLE_TO_CROLE_PATCH).$(YAML),Role)
+       @$(call 
add-remove-kind-patch,setup,remove,$(ROLEBIN_TO_CROLEBIN_PATCH).$(YAML),RoleBinding)
+endif
+#
+# Build the resources
+# Post-process RoleBindings to fix the namespace in the refs (not yet handled 
by kustomize)
+# Either apply to the cluster or output to CLI
+#
+ifeq ($(DRY_RUN), false)
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | \
+               sed 's/$(PLACEHOLDER)/$(NAMESPACE)/' | \
+               kubectl apply -f -
+else
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | \
+               sed 's/$(PLACEHOLDER)/$(NAMESPACE)/'
+endif
+
+.PHONY: operator .operator-port-patch .operator-can-monitor
+
+#
+# Customizes the port patch
+#
+.operator-port-patch:
+       @sed -i 's/--monitoring-port=.*/--monitoring-port=$(MONITORING_PORT)/' 
$(OPERATOR)/$(PORTS_PATCH).$(YAML)
+       @sed -i '/path:.*\/containerPort/,/- op/{s/value: .*/value: 
$(MONITORING_PORT)/}' $(OPERATOR)/$(PORTS_PATCH).$(YAML)
+       @sed -i 's/--health-port=.*/--health-port=$(HEALTH_PORT)/' 
$(OPERATOR)/$(PORTS_PATCH).$(YAML)
+       @sed -i '/path:.*\/httpGet\/port/,/- op/{s/value: .*/value: 
$(HEALTH_PORT)/}' $(OPERATOR)/$(PORTS_PATCH).$(YAML)
+
+.operator-can-monitor: kubectl
+       @output=$$(kubectl get crd prometheusrules.monitoring.coreos.com 2>&1) 
|| (echo "****" && echo "**** ERROR: Montoring not available as Prometheus CRDs 
not installed in cluster ****" && echo "****"; exit 1)
+
+#
+# Install the operator deployment and related resources
+#
+# Cluster-admin privileges are required.
+#
+# PARAMETERS:
+#   NAMESPACE:          Set the namespace to install the operator into
+#   PLATFORM:           Override the discovered platform, if required
+#   GLOBAL:             Sets the operator to watch all namespaces for custom 
resources [true|false]
+#   CUSTOM_IMAGE:       Set a custom operator image name
+#   CUSTOM_VERSION:     Set a custom operator image version/tag
+#   ALWAYS_PULL_IMAGES: Sets whether to always pull the operator image 
[true|false]
+#   MONITORING:         Adds the prometheus monitoring resources
+#   MONITORING_PORT:    Set a custom monitoring port
+#   HEALTH_PORT:        Set a custom health port
+#   DRY_RUN:            Prints the resources to be applied instead of applying 
them
+#
+operator: check-admin have-platform kustomize kubectl .operator-port-patch
+ifeq ($(MONITORING), true)
+       @$(MAKE) -s .operator-can-monitor
+       @$(call add-remove-operator-monitoring,$@,add)
+else
+       @$(call add-remove-operator-monitoring,$@,remove)
+endif
+# Set the namespace in the setup kustomization yaml
+       @$(call set-kustomize-namespace,$@)
+# Set the image reference of the kustomization
+       @$(call set-kustomize-image,$@)
+# Set the WATCH NAMESPACE env var depending on GLOBAL var
+ifeq ($(GLOBAL), true)
+       @$(call 
add-remove-kind-patch,$@,add,$(WATCH_NAMESPACE_PATCH).$(YAML),Deployment)
+else
+       @$(call 
add-remove-kind-patch,$@,remove,$(WATCH_NAMESPACE_PATCH).$(YAML),Deployment)
+endif
+# Set the ALWAYS_PULL_IMAGES config depending on var
+ifeq ($(ALWAYS_PULL_IMAGES),true)
+       @$(call 
add-remove-kind-patch,$@,add,$(IMAGE_PULL_POLICY_PATCH).$(YAML),Deployment)
+else
+       @$(call 
add-remove-kind-patch,$@,remove,$(IMAGE_PULL_POLICY_PATCH).$(YAML),Deployment)
+endif
+# Set the PORTS depending on vars
+ifneq ($(MONITORING_PORT), 8080)
+       @$(call add-remove-kind-patch,$@,add,$(PORTS_PATCH).$(YAML),Deployment)
+else ifneq ($(HEALTH_PORT), 8081)
+       @$(call add-remove-kind-patch,$@,add,$(PORTS_PATCH).$(YAML),Deployment)
+endif
+ifeq ($(DRY_RUN), false)
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | kubectl apply -f -
+else
+       @$(KUSTOMIZE) build $(KOPTIONS) $@
+endif
+
+.PHONY: platform .platform-openshift-patch .platform-kubernetes-patch
+
+#
+# Customizes the samples patches for kubernetes
+#
+.platform-kubernetes-patch:
+       @sed -i 's/.*profile:.*/  profile: Kubernetes/' 
$(INT_PLATFORM_PATCH).$(YAML)
+
+#
+# Customizes the samples patches for openshift
+#
+.platform-openshift-patch:
+       @sed -i 's/.*profile:.*/  profile: Openshift/' 
$(INT_PLATFORM_PATCH).$(YAML)
+
+#
+# Install the integration platform
+#
+# Cluster-admin privileges are required.
+#
+# PARAMETERS:
+#   NAMESPACE: Set the namespace to install the operator into
+#   PLATFORM:  Override the discovered platform, if required
+#   DRY_RUN:   Prints the resources to be applied instead of applying them 
[true,false]
+#
+platform: have-platform kustomize kubectl
+# Cannot be a dependency as PLATFORM could contain 'ERROR: '
+       @$(MAKE) .platform-$(PLATFORM)-patch
+# Set the namespace in the setup kustomization yaml
+       @$(call set-kustomize-namespace,$@)
+ifeq ($(DRY_RUN), false)
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | kubectl apply -f -
+else
+       @$(KUSTOMIZE) build $(KOPTIONS) $@
+endif
+
+.PHONY: example
+
+#
+# Installs the example integration
+#
+# PARAMETERS:
+#   NAMESPACE: Set the namespace to install the example into
+#   PLATFORM:  Override the discovered platform, if required
+#   DRY_RUN:   Prints the resources to be applied instead of applying them 
[true, false]
+#
+example: kubectl
+# Set the namespace in the setup kustomization yaml
+       @$(call set-kustomize-namespace,$@)
+ifeq ($(DRY_RUN), false)
+       @$(KUSTOMIZE) build $(KOPTIONS) $@ | kubectl apply -f -
+else
+       @$(KUSTOMIZE) build $(KOPTIONS) $@
+endif
diff --git a/config/manifests/kustomization.yaml 
b/install/example/kustomization.yaml
similarity index 88%
copy from config/manifests/kustomization.yaml
copy to install/example/kustomization.yaml
index 3dba3bd..6c0d51d 100644
--- a/config/manifests/kustomization.yaml
+++ b/install/example/kustomization.yaml
@@ -14,9 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
 
 resources:
-- ../default
-- ../samples
-- ../scorecard
-- ./bases/camel-k.clusterserviceversion.yaml
+- ../../config/samples/bases/camel_v1_integration.yaml
diff --git a/config/manifests/kustomization.yaml 
b/install/operator/kustomization.yaml
similarity index 50%
copy from config/manifests/kustomization.yaml
copy to install/operator/kustomization.yaml
index 3dba3bd..9467eee 100644
--- a/config/manifests/kustomization.yaml
+++ b/install/operator/kustomization.yaml
@@ -15,8 +15,37 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# Add patches for modifying the deployment
+#
+# * patch-image-pull-policy-always.yaml
+#   modifies the image pull policy property to "Always"
+#
+# * patch-monitoring-port.yaml
+#   modifies the monitoring port
+#
+# * patch-health-port.yaml
+#   modifies the health port
+#
+# * patch-watch-namespace-global.yaml
+#   modifies the WATCH_NAMESPACE env var to wildcard for all namespaces
+#
+# * patch-toleration.yaml
+#   modifies the tolerations configuraion of the deployment
+#   Edit the patch manually to add the required keys
+#
+# * patch-nodes-selector.yaml
+#   modifies the nodeSelector configuration of the deployment
+#   to bind the deployment to a particular labelled group of nodes
+#   Edit the patch manually to add the required configuration
+#
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
 resources:
-- ../default
-- ../samples
-- ../scorecard
-- ./bases/camel-k.clusterserviceversion.yaml
+- ../../config/manager
+
+patchesStrategicMerge:
+- patch-toleration.yaml
+- patch-node-selector.yaml
+- patch-resource-requirements.yaml
diff --git a/install/operator/patch-image-pull-policy-always.yaml 
b/install/operator/patch-image-pull-policy-always.yaml
new file mode 100644
index 0000000..4ee2b00
--- /dev/null
+++ b/install/operator/patch-image-pull-policy-always.yaml
@@ -0,0 +1,10 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: camel-k-operator
+spec:
+  template:
+    spec:
+      containers:
+        - name: camel-k-operator
+          imagePullPolicy: Always
diff --git a/config/rbac/user-global-kamelet-viewer-role.yaml 
b/install/operator/patch-node-selector.yaml
similarity index 81%
copy from config/rbac/user-global-kamelet-viewer-role.yaml
copy to install/operator/patch-node-selector.yaml
index 80bc061..ab28902 100644
--- a/config/rbac/user-global-kamelet-viewer-role.yaml
+++ b/install/operator/patch-node-selector.yaml
@@ -15,18 +15,15 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
+apiVersion: apps/v1
+kind: Deployment
 metadata:
-  name: camel-k-kamelet-viewer
-  labels:
-    app: "camel-k"
-rules:
-- apiGroups:
-  - "camel.apache.org"
-  resources:
-  - kamelets
-  verbs:
-  - get
-  - list
-  - watch
+  name: camel-k-operator
+spec:
+  template:
+    spec:
+      nodeSelector:
+#
+# Add labels for choosing which nodes to assign the deployment
+# eg.
+#        - diskType: ssd
diff --git a/config/prometheus/kustomization.yaml 
b/install/operator/patch-ports.yaml
similarity index 75%
copy from config/prometheus/kustomization.yaml
copy to install/operator/patch-ports.yaml
index 4cf497f..37fc500 100644
--- a/config/prometheus/kustomization.yaml
+++ b/install/operator/patch-ports.yaml
@@ -15,4 +15,14 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-resources:
+- op: add
+  path: /spec/template/spec/containers/0/args
+  value:
+  - --monitoring-port=8080
+  - --health-port=8081
+- op: replace
+  path: /spec/template/spec/containers/0/ports/0/containerPort
+  value: 8080
+- op: replace
+  path: /spec/template/spec/containers/0/livenessProbe/httpGet/port
+  value: 8081
diff --git a/config/rbac/operator-role-binding-openshift.yaml 
b/install/operator/patch-resource-requirements.yaml
similarity index 68%
copy from config/rbac/operator-role-binding-openshift.yaml
copy to install/operator/patch-resource-requirements.yaml
index 54dbe28..4daafbc 100644
--- a/config/rbac/operator-role-binding-openshift.yaml
+++ b/install/operator/patch-resource-requirements.yaml
@@ -15,16 +15,23 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
+apiVersion: apps/v1
+kind: Deployment
 metadata:
-  name: camel-k-operator-openshift
-  labels:
-    app: "camel-k"
-subjects:
-- kind: ServiceAccount
   name: camel-k-operator
-roleRef:
-  kind: Role
-  name: camel-k-operator-openshift
-  apiGroup: rbac.authorization.k8s.io
+spec:
+  template:
+    spec:
+      containers:
+        - name: camel-k-operator
+          resources:
+            #
+            # Add custom requirements on hardware resource allocation
+            # for the operator deployment
+            #
+            requests:
+              # memory: "64Mi"
+              # cpu: "250m"
+            limits:
+              # memory: "128Mi"
+              # cpu: "500m"
diff --git a/config/rbac/operator-role-binding-openshift.yaml 
b/install/operator/patch-toleration.yaml
similarity index 79%
rename from config/rbac/operator-role-binding-openshift.yaml
rename to install/operator/patch-toleration.yaml
index 54dbe28..71b7f12 100644
--- a/config/rbac/operator-role-binding-openshift.yaml
+++ b/install/operator/patch-toleration.yaml
@@ -15,16 +15,18 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
+apiVersion: apps/v1
+kind: Deployment
 metadata:
-  name: camel-k-operator-openshift
-  labels:
-    app: "camel-k"
-subjects:
-- kind: ServiceAccount
   name: camel-k-operator
-roleRef:
-  kind: Role
-  name: camel-k-operator-openshift
-  apiGroup: rbac.authorization.k8s.io
+spec:
+  template:
+    spec:
+      tolerations:
+#
+# Add tolerations for configuring the deployment
+# eg.
+#        - key: "key1"
+#          operator: "Equal"
+#          value: "value1"
+#          effect: "NoSchedule"
diff --git a/config/prometheus/kustomization.yaml 
b/install/operator/patch-watch-namespace-global.yaml
similarity index 86%
copy from config/prometheus/kustomization.yaml
copy to install/operator/patch-watch-namespace-global.yaml
index 4cf497f..626fa2b 100644
--- a/config/prometheus/kustomization.yaml
+++ b/install/operator/patch-watch-namespace-global.yaml
@@ -15,4 +15,8 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-resources:
+- op: remove
+  path: /spec/template/spec/containers/0/env/0/valueFrom
+- op: add
+  path: /spec/template/spec/containers/0/env/0/value
+  value: '""'
diff --git a/config/prometheus/kustomization.yaml 
b/install/platform/kustomization.yaml
similarity index 77%
copy from config/prometheus/kustomization.yaml
copy to install/platform/kustomization.yaml
index 4cf497f..c4c77e0 100644
--- a/config/prometheus/kustomization.yaml
+++ b/install/platform/kustomization.yaml
@@ -15,4 +15,13 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
+#
+# * patch-integration-platform.yaml
+# customizes the integration platform custom resource
+# Edit the patch manually to add required configuration
+#
 resources:
+- ../../config/samples/bases/camel_v1_integrationplatform.yaml
+
+patchesStrategicMerge:
+- patch-integration-platform.yaml
diff --git a/install/platform/patch-integration-platform.yaml 
b/install/platform/patch-integration-platform.yaml
new file mode 100644
index 0000000..0f60cd2
--- /dev/null
+++ b/install/platform/patch-integration-platform.yaml
@@ -0,0 +1,133 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+apiVersion: camel.apache.org/v1
+kind: IntegrationPlatform
+metadata:
+  name: camel-k
+spec:
+  #
+  # The profile to be implemented by default
+  # ie. OpenShift, Kubernetes, Knative
+  #
+  profile: Openshift
+  #
+  #
+  # Options propagated to integrations
+  #
+  configuration:
+  #  repository: maven-repository
+  #
+  #
+  # Options of the image build process
+  #
+  build:
+  #
+  # Build strategy for integrations
+  # ie. routine, pod
+  #
+  #  buildStrategy: routine | pod
+  #
+  #
+  # Build publish strategy for integrations
+  # ie. Buildah, Kaniko, S2I, Spectrum
+  #
+  #  publishStrategy: Buildah | Kaniko | S2I | Spectrum
+  #
+  # Set the camel-k runtime version
+  #
+  #  runtimeVersion: 1.4.0
+  #
+  # Set the base Image used to run integrations
+  #
+  #  baseImage: base-image:1.0.0
+  #
+  # Build timeout
+  #
+  #  timeout:
+  #    duration: 30
+  #
+    #
+    # Properties for applying to camel integrations
+    #
+    properties:
+    #    key1: value1
+    #    key2: value2
+    #
+    #
+    # Configuration for a custom maven repository
+    #
+    maven:
+    #
+    # Location of the local Maven repository
+    #
+    #  localRepository: my.repository.url
+    #
+    # Configure a source of Maven settings (configmap|secret:name[/key])
+    #  settings:
+    #    configMapKeyRef:
+    #      key: settings.xml
+    #      name: maven-settings
+    #
+    #
+    # Secret name and key, containing the CA certificate(s) used to connect
+    # to remote Maven repositories.
+    #
+    # Can contain X.509 certificates, and PKCS#7 formatted certificate chains.
+    # A JKS formatted keystore is automatically created to store the CA 
certificate(s),
+    # and configured to be used as a trusted certificate(s) by the Maven 
commands.
+    # Note that the root CA certificates are also imported into the created 
keystore.
+    #
+    #  caSecret:
+    #    key: tls.crt
+    #    name: tls-secret
+    #
+    #
+    # Configures a custom registry
+    # eg. DigitalOcean, Docker Hub, Github, Gcr.io, IBM Container Registry
+    # Refer to 
https://camel.apache.org/camel-k/latest/installation/registry/registry.html
+    #
+    registry:
+    # The address of the registry
+    # eg. registry.digitalocean.com, docker.pkg.github.com
+    #
+    #  address: registry-host.io
+    #
+    #
+    # The identifier of the organization
+    # eg. github-user/repository
+    #
+    #  organization: your-user-id-or-org
+    #
+    #
+    # As an alternative, a secret can be added to the namespace containing 
credentials,
+    # eg. for use with connecting to Docker Hub
+    #
+    #  secret: the-push-kubernetes-secret-name
+    #
+    # Should connection to registry be secure
+    #
+    #  insecure: true | false
+  kamelet: {}
+  resources: {}
+status:
+  build:
+    maven:
+      settings: {}
+    registry: {}
+  kamelet: {}
+  resources: {}
diff --git a/install/release/Makefile b/install/release/Makefile
new file mode 100644
index 0000000..c35ba2a
--- /dev/null
+++ b/install/release/Makefile
@@ -0,0 +1,60 @@
+# 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.
+
+#
+# Include the main camel-k Makefile containing
+# basic common recipes like kustomize and vars
+# like VERSION
+#
+
+.PHONY: $(SUBDIRS)
+
+INSTALLDIR := $(RELEASE_NAME)-installer
+CONFIG := ../../config
+INSTALL := ../../install
+CMDUTIL := cmd/util
+
+RELEASE := $(CONFIG) $(INSTALL)
+
+default: release
+
+check-vars:
+ifndef RELEASE_VERSION
+       $(error RELEASE_VERSION is not set)
+endif
+ifndef RELEASE_NAME
+       $(error RELEASE_NAME is not set)
+endif
+
+create:
+       #@ Make a new build directory
+       @mkdir -p $(INSTALLDIR)
+       #@ Copy directories into build directory
+       @for rel in $(RELEASE); do \
+               relname=$$(basename $$rel); \
+               for dir in `find $$rel -mindepth 1 -maxdepth 1 \( ! -iname 
"*release*" \)`; do \
+                       mkdir -p "$(INSTALLDIR)/$$relname"; \
+                       cp -rfL $$dir $(INSTALLDIR)/$$relname/; \
+               done \
+       done
+       #@ Copy the platform-check go source since its built and run during 
install
+       @mkdir -p $(INSTALLDIR)/$(CMDUTIL) && \
+               cp -rf ../../$(CMDUTIL)/platform-check $(INSTALLDIR)/$(CMDUTIL)/
+
+release: check-vars create
+       #@tar zcvf $(INSTALLDIR)-$(RELEASE_VERSION).tar.gz $(INSTALLDIR)
+
+clean:
+       @rm -rf *-installer *.tar.gz
diff --git a/install/script/Makefile b/install/script/Makefile
new file mode 120000
index 0000000..d89e34f
--- /dev/null
+++ b/install/script/Makefile
@@ -0,0 +1 @@
+../../script/Makefile
\ No newline at end of file
diff --git a/install/script/check_platform.sh b/install/script/check_platform.sh
new file mode 120000
index 0000000..329d246
--- /dev/null
+++ b/install/script/check_platform.sh
@@ -0,0 +1 @@
+../../script/check_platform.sh
\ No newline at end of file
diff --git a/config/manifests/kustomization.yaml 
b/install/setup-cluster/kustomization.yaml
similarity index 88%
copy from config/manifests/kustomization.yaml
copy to install/setup-cluster/kustomization.yaml
index 3dba3bd..88d4747 100644
--- a/config/manifests/kustomization.yaml
+++ b/install/setup-cluster/kustomization.yaml
@@ -14,9 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
 
 resources:
-- ../default
-- ../samples
-- ../scorecard
-- ./bases/camel-k.clusterserviceversion.yaml
+- ../../config/crd
+- ../../config/rbac/user-cluster-role.yaml
diff --git a/config/prometheus/kustomization.yaml 
b/install/setup/kustomization.yaml
similarity index 91%
copy from config/prometheus/kustomization.yaml
copy to install/setup/kustomization.yaml
index 4cf497f..9b3c34e 100644
--- a/config/prometheus/kustomization.yaml
+++ b/install/setup/kustomization.yaml
@@ -14,5 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
 
 resources:
+- ../../config/rbac
diff --git a/install/setup/patch-role-to-clusterrole.yaml 
b/install/setup/patch-role-to-clusterrole.yaml
new file mode 100644
index 0000000..c4e0064
--- /dev/null
+++ b/install/setup/patch-role-to-clusterrole.yaml
@@ -0,0 +1,3 @@
+- op: replace
+  path: /kind
+  value: ClusterRole
diff --git a/install/setup/patch-rolebinding-to-clusterrolebinding.yaml 
b/install/setup/patch-rolebinding-to-clusterrolebinding.yaml
new file mode 100644
index 0000000..830703b
--- /dev/null
+++ b/install/setup/patch-rolebinding-to-clusterrolebinding.yaml
@@ -0,0 +1,9 @@
+- op: replace
+  path: /kind
+  value: ClusterRoleBinding
+- op: replace
+  path: /roleRef/kind
+  value: ClusterRole
+- op: add
+  path: /subjects/0/namespace
+  value: placeholder
diff --git a/pkg/apis/camel/v1alpha1/jsonschema_types.go 
b/pkg/apis/camel/v1alpha1/jsonschema_types.go
index 038307b..5e90f4f 100644
--- a/pkg/apis/camel/v1alpha1/jsonschema_types.go
+++ b/pkg/apis/camel/v1alpha1/jsonschema_types.go
@@ -143,6 +143,6 @@ type JSONSchemaURL string
 
 // ExternalDocumentation allows referencing an external resource for extended 
documentation.
 type ExternalDocumentation struct {
-       Description string `json:"description,omitempty""`
+       Description string `json:"description,omitempty"`
        URL         string `json:"url,omitempty"`
 }
diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go
index 3cd37ea..b0893d9 100644
--- a/pkg/install/cluster.go
+++ b/pkg/install/cluster.go
@@ -152,7 +152,7 @@ func SetupClusterWideResourcesOrCollect(ctx 
context.Context, clientProvider clie
        }
 
        // Installing ClusterRoles
-       ok, err := isClusterRoleInstalled(ctx, c, "camel-k:edit")
+       ok, err := isClusterRoleInstalled(ctx, c, "camel-k-edit")
        if err != nil {
                return err
        }
@@ -168,12 +168,12 @@ func SetupClusterWideResourcesOrCollect(ctx 
context.Context, clientProvider clie
                return err
        }
        if isOpenShift {
-               ok, err := isClusterRoleInstalled(ctx, c, 
"camel-k-operator-openshift")
+               ok, err := isClusterRoleInstalled(ctx, c, 
"camel-k-operator-console-openshift")
                if err != nil {
                        return err
                }
                if !ok || collection != nil {
-                       err := installResource(ctx, c, collection, 
"/rbac/operator-cluster-role-console-openshift.yaml")
+                       err := installResource(ctx, c, collection, 
"/rbac/openshift/operator-cluster-role-console-openshift.yaml")
                        if err != nil {
                                return err
                        }
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 1c78fbe..b3b68a3 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -288,7 +288,7 @@ func installOpenShiftClusterRoleConsoleBinding(ctx 
context.Context, c client.Cli
        existing, err := c.RbacV1().ClusterRoleBindings().Get(ctx, 
"camel-k-operator-console-openshift", metav1.GetOptions{})
        if k8serrors.IsNotFound(err) {
                existing = nil
-               obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), 
resources.ResourceAsString("/rbac/operator-cluster-role-console-binding-openshift.yaml"))
+               obj, err := kubernetes.LoadResourceFromYaml(c.GetScheme(), 
resources.ResourceAsString("/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml"))
                if err != nil {
                        return err
                }
@@ -345,15 +345,15 @@ func installOpenShiftClusterRoleConsoleBinding(ctx 
context.Context, c client.Cli
 
 func installOpenShiftRoles(ctx context.Context, c client.Client, namespace 
string, customizer ResourceCustomizer, collection *kubernetes.Collection, force 
bool) error {
        return ResourcesOrCollect(ctx, c, namespace, collection, force, 
customizer,
-               "/rbac/operator-role-openshift.yaml",
-               "/rbac/operator-role-binding-openshift.yaml",
+               "/rbac/openshift/operator-role-openshift.yaml",
+               "/rbac/openshift/operator-role-binding-openshift.yaml",
        )
 }
 
 func installKubernetesRoles(ctx context.Context, c client.Client, namespace 
string, customizer ResourceCustomizer, collection *kubernetes.Collection, force 
bool) error {
        return ResourcesOrCollect(ctx, c, namespace, collection, force, 
customizer,
                "/manager/operator-service-account.yaml",
-               "/rbac/operator-role-kubernetes.yaml",
+               "/rbac/operator-role.yaml",
                "/rbac/operator-role-binding.yaml",
        )
 }
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 70d3da7..ea0fc45 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -163,10 +163,6 @@ var assets = func() http.FileSystem {
 
                        compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5c\x7d\x4f\xe3\x3a\xba\xff\xbf\x9f\xe2\x11\x1c\x69\x18\x89\x94\x96\xc2\x9c\x99\xde\x3f\x10\x07\x86\xbd\xbd\x87\x03\x88\xc2\xae\xce\x85\x59\xc9\x4d\x9e\xb6\x5e\x12\x3b\x6b\x3b\x14\xf6\xc0\x77\xbf\xb2\x9d\xa4\xe9\x4b\x12\xb7\x14\xf6\xe8\x6a\x2d\x8d\xa6\x49\xec\x9f\x9f\x37\x3f\x7e\xc9\x8f\x6c\x83\xb7\xb9\xd2\xd8\x86\x73\xea\x23\x93\x18\x80\xe2\xa0\xc6\x08\xc7\x31\xf1\xc7\x08\x7d\x3e\x54\x13\x22\x10\xce\x78\xc2\x02\x
 [...]
                },
-               "/default": &vfsgen۰DirInfo{
-                       name:    "default",
-                       modTime: time.Time{},
-               },
                "/manager": &vfsgen۰DirInfo{
                        name:    "manager",
                        modTime: time.Time{},
@@ -207,20 +203,38 @@ var assets = func() http.FileSystem {
                        name:    "rbac",
                        modTime: time.Time{},
                },
-               "/rbac/operator-cluster-role-console-binding-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
+               "/rbac/openshift": &vfsgen۰DirInfo{
+                       name:    "openshift",
+                       modTime: time.Time{},
+               },
+               
"/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"operator-cluster-role-console-binding-openshift.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 1247,
+                       uncompressedSize: 1280,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x93\x41\x8f\xdb\x36\x10\x85\xef\xfc\x15\x0f\xd6\x25\x01\xd6\x72\xdb\x53\xe1\x9e\x9c\xcd\x6e\x2b\x34\xb0\x01\xcb\x69\x90\x23\x4d\x8d\xa5\xe9\x52\x1c\x75\x48\xad\xb2\xfd\xf5\x05\x65\xbb\x71\x10\x24\xa7\xf0\x26\x89\x9c\xf7\x3d\xbe\xa7\x02\xcb\x1f\xb7\x4c\x81\x77\xec\x28\x44\x6a\x90\x04\xa9\x23\x6c\x06\xeb\x3a\x42\x2d\xa7\x34\x59\x25\x3c\xca\x18\x1a\x9b\x58\x02\x5e\x6d\xea\xc7\xd7\x18\x43\x43\x0a\x09\x04\x51\xf4\xa2\x
 [...]
+                       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\xb6\xa7\xc2\x3d\x39\x9b\xdd\x56\x68\x60\x03\x96\xd3\x20\x47\x9a\x1a\x4b\xd3\xa5\x38\xea\x90\x5a\xc5\xfd\xfa\x82\xb2\xdd\x6c\x10\xb4\x40\x80\xf0\x26\x71\x66\xde\x7b\xf3\x1e\x0b\x2c\xbf\xdf\x31\x05\xde\xb1\xa3\x10\xa9\x41\x12\xa4\x8e\xb0\x19\xac\xeb\x08\xb5\x9c\xd2\x64\x95\xf0\x28\x63\x68\x6c\x62\x09\x78\xb5\xa9\x1f\x5f\x63\x0c\x0d\x29\x24\x10\x44\xd1\x8b\x
 [...]
                },
-               "/rbac/operator-cluster-role-console-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
+               "/rbac/openshift/operator-cluster-role-console-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"operator-cluster-role-console-openshift.yaml",
                        modTime:          time.Time{},
                        uncompressedSize: 1262,
 
                        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\xb5\x6d\x4f\x85\x7b\x72\x37\xbb\xad\xd0\xc0\x06\x56\x4e\x83\x1c\x69\x6a\x2c\x0d\x96\xe2\xa8\x43\x6a\x95\xed\xd7\x17\xa4\xed\x64\x17\xbd\x86\x17\x8d\xa8\xc7\x37\xef\xf1\x8d\x2a\xac\x7f\xdc\x32\x15\x3e\xb2\xa3\x10\xa9\x43\x12\xa4\x81\xb0\x9d\xac\x1b\x08\xad\x9c\xd2\x62\x95\xf0\x20\x73\xe8\x6c\x62\x09\x78\xb7\x6d\x1f\xde\x63\x0e\x1d\x29\x24\x10\x44\x31\x8a\x92\x
 [...]
                },
+               "/rbac/openshift/operator-role-binding-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
+                       name:             
"operator-role-binding-openshift.yaml",
+                       modTime:          time.Time{},
+                       uncompressedSize: 1225,
+
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xab\x46\x14\xdd\xcf\xaf\x38\x32\x9b\xf7\x24\x1b\xb7\x5d\x55\xee\x8a\x97\xd8\x2d\x6a\x64\x4b\xc6\x69\x94\xe5\x78\xb8\xc0\xad\x61\x2e\x9d\x19\x42\xdc\x5f\x5f\x0d\xb6\x9b\x44\x55\xab\x2e\x32\x2b\x10\x97\xf3\x71\xcf\x99\x04\x8b\xcf\x3b\x2a\xc1\x03\x1b\xb2\x9e\x4a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xa4\x0a\xa3\x76\x84\x8d\x0c\xb6\xd4\x81\xc5\xe2\x4b\x56\x6c\xbe\x62\xb0\x25\x39\x88\x25\x88\x43\x27\x8e\x54\x
 [...]
+               },
+               "/rbac/openshift/operator-role-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
+                       name:             "operator-role-openshift.yaml",
+                       modTime:          time.Time{},
+                       uncompressedSize: 1975,
+
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x53\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\xc9\x6e\x6b\x34\xb0\x81\x95\xd3\x20\x47\x7a\x44\x4b\xc4\x8e\x86\xea\xcc\x68\x95\xed\xd7\x17\x33\xb6\x13\x6f\xdd\x6d\x2e\x01\xa2\x8b\x68\xf2\x89\x7c\x8f\x8f\x2e\x31\xff\x76\x4f\x51\xe2\x9d\x18\x76\x81\x1b\x44\x45\xec\x18\xab\x81\x4c\xc7\xa8\xf5\x10\x27\xf2\x8c\x3b\x1d\x5d\x43\x51\xd4\xe1\xd5\xaa\xbe\x7b\x8d\xd1\x35\xec\xa1\x8e\xa1\x1e\x
 [...]
+               },
                "/rbac/operator-role-binding-events.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "operator-role-binding-events.yaml",
                        modTime:          time.Time{},
@@ -242,13 +256,6 @@ var assets = func() http.FileSystem {
 
                        compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x93\x41\x8f\xdb\x36\x10\x85\xef\xfc\x15\x0f\xd6\x25\x01\xd6\x72\xdb\x53\xe1\x9e\x9c\xcd\x6e\x2b\x34\xb0\x01\xcb\x69\x90\xe3\x98\x1a\x4b\xd3\xa5\x38\x2a\x49\xad\xe2\xfe\xfa\x82\xb2\xdd\xdd\xa0\x68\xd1\x43\x78\x13\x34\x7a\xf3\x3d\xbe\xa7\x02\xcb\x6f\x77\x4c\x81\x0f\x62\xd9\x47\x6e\x90\x14\xa9\x63\x6c\x06\xb2\x1d\xa3\xd6\x53\x9a\x28\x30\x1e\x75\xf4\x0d\x25\x51\x8f\x37\x9b\xfa\xf1\x2d\x46\xdf\x70\x80\x7a\x86\x06\xf4\x
 [...]
                },
-               "/rbac/operator-role-binding-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
-                       name:             
"operator-role-binding-openshift.yaml",
-                       modTime:          time.Time{},
-                       uncompressedSize: 1225,
-
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xab\x46\x14\xdd\xcf\xaf\x38\x32\x9b\xf7\x24\x1b\xb7\x5d\x55\xee\x8a\x97\xd8\x2d\x6a\x64\x4b\xc6\x69\x94\xe5\x78\xb8\xc0\xad\x61\x2e\x9d\x19\x42\xdc\x5f\x5f\x0d\xb6\x9b\x44\x55\xab\x2e\x32\x2b\x10\x97\xf3\x71\xcf\x99\x04\x8b\xcf\x3b\x2a\xc1\x03\x1b\xb2\x9e\x4a\x04\x41\x68\x08\x59\xaf\x4d\x43\x28\xa4\x0a\xa3\x76\x84\x8d\x0c\xb6\xd4\x81\xc5\xe2\x4b\x56\x6c\xbe\x62\xb0\x25\x39\x88\x25\x88\x43\x27\x8e\x54\x
 [...]
-               },
                "/rbac/operator-role-binding-podmonitors.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"operator-role-binding-podmonitors.yaml",
                        modTime:          time.Time{},
@@ -291,13 +298,6 @@ var assets = func() http.FileSystem {
 
                        compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xac\x4b\x52\xac\xe5\xb6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\x63\x6a\x2c\x0d\x4c\x91\xea\x90\xb2\xb2\xfd\xfa\x42\xb2\xdc\x78\xb1\x45\x4f\x8b\xf2\xa2\x11\xf9\xf4\xe6\x3d\xbe\x51\x86\xe5\xdb\x2d\x93\xe1\xa3\x58\xf6\x91\x2b\xa4\x80\xd4\x30\x36\x1d\xd9\x86\x51\x86\x63\x1a\x48\x19\x8f\xa1\xf7\x15\x25\x09\x1e\xef\x36\xe5\xe3\x7b\xf4\xbe\x62\x45\xf0\x8c\xa0\x68\x
 [...]
                },
-               "/rbac/operator-role-kubernetes.yaml": 
&vfsgen۰CompressedFileInfo{
-                       name:             "operator-role-kubernetes.yaml",
-                       modTime:          time.Time{},
-                       uncompressedSize: 2349,
-
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x55\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x6e\x11\xdb\x6d\x4f\x85\x7b\x72\x77\x93\xd6\xe8\xc2\x06\x22\x6f\x17\x7b\xa4\xa8\xb1\x3c\x0d\xc5\x61\x49\x2a\x8a\xfb\xf5\x05\x29\x7b\xd7\x59\x27\x40\x0e\x41\x5b\x5d\x3c\xa4\x46\x6f\xde\x9b\x79\x26\x4b\x4c\x5f\xef\x29\x4a\x7c\x60\x4d\x36\x50\x83\x28\x88\x7b\xc2\xd2\x29\xbd\x27\x54\xb2\x8b\x83\xf2\x84\x1b\xe9\x6d\xa3\x22\x8b\xc5\x9b\x65\x75\xf3\x16\xbd\x6d\xc8\x43\x2c\x
 [...]
-               },
                "/rbac/operator-role-leases.yaml": &vfsgen۰CompressedFileInfo{
                        name:             "operator-role-leases.yaml",
                        modTime:          time.Time{},
@@ -305,13 +305,6 @@ var assets = func() http.FileSystem {
 
                        compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x6f\xdb\x46\x10\xbd\xef\xaf\x78\x10\x2f\x09\x60\xd1\x6d\x4f\x85\x7a\x52\x1d\xbb\x25\x1a\x48\x80\xa9\x34\xc8\x71\xb5\x1c\x91\x03\x2f\x77\xb6\xb3\x4b\x33\xee\xaf\x2f\x96\x92\x12\x1b\xbd\x86\xa7\xd1\xea\xf1\x7d\xec\x1b\x56\x58\xff\xb8\xc7\x54\xf8\xc8\x8e\x42\xa2\x0e\x59\x90\x07\xc2\x36\x5a\x37\x10\x5a\x39\xe5\xd9\x2a\xe1\x41\xa6\xd0\xd9\xcc\x12\xf0\x6e\xdb\x3e\xbc\xc7\x14\x3a\x52\x48\x20\x88\x62\x14\x25\x53\x
 [...]
                },
-               "/rbac/operator-role-openshift.yaml": 
&vfsgen۰CompressedFileInfo{
-                       name:             "operator-role-openshift.yaml",
-                       modTime:          time.Time{},
-                       uncompressedSize: 1975,
-
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x53\xc1\x8e\xdb\x46\x0c\xbd\xeb\x2b\x1e\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\xc9\x6e\x6b\x34\xb0\x81\x95\xd3\x20\x47\x7a\x44\x4b\xc4\x8e\x86\xea\xcc\x68\x95\xed\xd7\x17\x33\xb6\x13\x6f\xdd\x6d\x2e\x01\xa2\x8b\x68\xf2\x89\x7c\x8f\x8f\x2e\x31\xff\x76\x4f\x51\xe2\x9d\x18\x76\x81\x1b\x44\x45\xec\x18\xab\x81\x4c\xc7\xa8\xf5\x10\x27\xf2\x8c\x3b\x1d\x5d\x43\x51\xd4\xe1\xd5\xaa\xbe\x7b\x8d\xd1\x35\xec\xa1\x8e\xa1\x1e\x
 [...]
-               },
                "/rbac/operator-role-podmonitors.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             "operator-role-podmonitors.yaml",
                        modTime:          time.Time{},
@@ -333,26 +326,33 @@ var assets = func() http.FileSystem {
 
                        compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x6e\xdb\x46\x10\xbd\xef\x57\x3c\x88\x97\x04\xb0\xa8\xb6\xa7\x42\x3d\xa9\x8e\xdd\x12\x0d\x24\xc0\x54\x1a\xe4\x38\x22\x47\xe4\x40\xe4\x0e\x3b\xbb\x34\xe3\x7c\x7d\xb1\x14\x55\x3b\xe8\x35\x7b\xe1\x0e\xf8\xf8\xe6\xbd\x79\xc3\x0c\xeb\x1f\x77\x5c\x86\x8f\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\xef\x76\xe5\xe3\x7b\x8c\xbe\x66\x83\x7a\x86\x1a\x7a\x35\x76\x
 [...]
                },
+               "/rbac/operator-role.yaml": &vfsgen۰CompressedFileInfo{
+                       name:             "operator-role.yaml",
+                       modTime:          time.Time{},
+                       uncompressedSize: 2349,
+
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x55\xc1\x6e\xe3\x36\x10\xbd\xeb\x2b\x1e\xac\xcb\x6e\x11\xdb\x6d\x4f\x85\x7b\x72\x77\x93\xd6\xe8\xc2\x06\x22\x6f\x17\x7b\xa4\xa8\xb1\x3c\x0d\xc5\x61\x49\x2a\x8a\xfb\xf5\x05\x29\x7b\xd7\x59\x27\x40\x0e\x41\x5b\x5d\x3c\xa4\x46\x6f\xde\x9b\x79\x26\x4b\x4c\x5f\xef\x29\x4a\x7c\x60\x4d\x36\x50\x83\x28\x88\x7b\xc2\xd2\x29\xbd\x27\x54\xb2\x8b\x83\xf2\x84\x1b\xe9\x6d\xa3\x22\x8b\xc5\x9b\x65\x75\xf3\x16\xbd\x6d\xc8\x43\x2c\x
 [...]
+               },
                "/rbac/user-cluster-role.yaml": &vfsgen۰CompressedFileInfo{
                        name:             "user-cluster-role.yaml",
                        modTime:          time.Time{},
                        uncompressedSize: 1315,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xa4\x4b\x52\xac\xe5\xb6\xa7\x42\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x50\xf4\x40\x8b\x63\x69\xb0\x14\xa9\x0e\xa9\x55\xb6\x5f\x5f\x90\xb6\x37\x5e\x14\x3d\x04\x08\x6f\x24\x87\x6f\xde\x9b\xf7\x58\x62\xf5\xed\x96\x2a\xf1\x9e\x3b\x72\x81\x0c\xa2\x47\x1c\x08\x9b\x49\x77\x03\xa1\xf5\xc7\xb8\x68\x21\xdc\xfb\xd9\x19\x1d\xd9\x3b\xbc\xd9\xb4\xf7\x6f\x31\x3b\x43\x02\xef\x08\x5e\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xc1\x8e\xdb\x36\x10\xbd\xf3\x2b\x1e\xa4\x4b\x52\xac\xe5\xb6\xa7\x42\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x50\xf4\x40\x8b\x63\x69\xb0\x14\xa9\x0e\xa9\x55\xb6\x5f\x5f\x90\xb6\x37\x5e\x14\x3d\x04\x08\x6f\x24\x87\x6f\xde\x9b\xf7\x58\x62\xf5\xed\x96\x2a\xf1\x9e\x3b\x72\x81\x0c\xa2\x47\x1c\x08\x9b\x49\x77\x03\xa1\xf5\xc7\xb8\x68\x21\xdc\xfb\xd9\x19\x1d\xd9\x3b\xbc\xd9\xb4\xf7\x6f\x31\x3b\x43\x02\xef\x08\x5e\x
 [...]
                },
                "/rbac/user-global-kamelet-viewer-role-binding.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"user-global-kamelet-viewer-role-binding.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 1250,
+                       uncompressedSize: 1353,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\xcd\x6e\xda\x4c\x14\xdd\xcf\x53\x1c\xe1\x4d\x22\x81\xf9\xbe\xae\x2a\x77\x45\x12\x68\xad\x46\x20\x61\xd2\x28\xcb\x8b\x7d\xb1\x6f\xb1\x67\xdc\x99\x71\x1c\xfa\xf4\xd5\x18\xc8\x8f\x2a\xb5\xaa\x94\xd9\x20\x34\x77\xce\xcf\x3d\xc7\x11\x26\xef\x77\x54\x84\x5b\xc9\x59\x3b\x2e\xe0\x0d\x7c\xc5\x98\xb5\x94\x57\x8c\xcc\xec\x7c\x4f\x96\xb1\x30\x9d\x2e\xc8\x8b\xd1\xb8\x98\x65\x8b\x4b\x74\xba\x60\x0b\xa3\x19\xc6\xa2\x31\x96\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\xdb\x6d\x4f\x85\x7b\x72\x36\xbb\xad\xd0\xc0\x06\x2c\xa7\x41\x8e\x63\x6a\x2c\x4d\x4d\x71\x54\x92\x5a\xc5\xfd\xf5\x05\xb5\x76\xbc\x41\x81\x16\x01\x56\x37\x81\xc3\xf7\x31\xef\xb1\xc0\xfc\xf5\x3e\x53\xe0\x83\x58\xf6\x91\x6b\x24\x45\x6a\x19\xeb\x9e\x6c\xcb\xa8\xf4\x98\x46\x0a\x8c\x47\x1d\x7c\x4d\x49\xd4\xe3\xcd\xba\x7a\x7c\x8b\xc1\xd7\x1c\xa0\x9e\xa1\x01\x9d\x06\x
 [...]
                },
                "/rbac/user-global-kamelet-viewer-role.yaml": 
&vfsgen۰CompressedFileInfo{
                        name:             
"user-global-kamelet-viewer-role.yaml",
                        modTime:          time.Time{},
-                       uncompressedSize: 1166,
+                       uncompressedSize: 1262,
 
-                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4f\x6f\xfa\x46\x14\xbc\xef\xa7\x18\xe1\x4b\x22\x81\x69\x7b\xaa\xe8\x89\x26\xd0\x5a\x8d\x40\xc2\xa4\x51\x8e\x8b\xfd\xb0\x9f\x58\xef\xba\x6f\xd7\x38\xf4\xd3\x57\x6b\x4c\x43\xf4\xbb\x66\x2f\xeb\x3f\xe3\x37\x33\x3b\xe3\x04\xb3\xef\x5b\x2a\xc1\x0b\x17\x64\x3d\x95\x08\x0e\xa1\x26\x2c\x5b\x5d\xd4\x84\xdc\x1d\x43\xaf\x85\xb0\x76\x9d\x2d\x75\x60\x67\xf1\xb0\xcc\xd7\x8f\xe8\x6c\x49\x02\x67\x09\x4e\xd0\x38\x21\x95\xa0\x
 [...]
+                       compressedContent: 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x53\x4d\x8f\xdb\x36\x14\xbc\xf3\x57\x0c\xac\x4b\x02\xac\xe5\xb6\xa7\xc2\x3d\xb9\x9b\xdd\x56\x68\x60\x03\x2b\xa7\x41\x8e\xcf\xd4\xb3\xf4\x60\x8a\x4f\x25\xa9\x55\xb6\xbf\xbe\xa0\x2c\x67\x37\xe8\x35\xbc\xf8\x43\xa3\x79\x33\x6f\x86\x05\xd6\x3f\xee\x98\x02\x1f\xc5\xb2\x8f\xdc\x20\x29\x52\xc7\xd8\x0d\x64\x3b\x46\xad\xe7\x34\x51\x60\x3c\xea\xe8\x1b\x4a\xa2\x1e\xef\x76\xf5\xe3\x7b\x8c\xbe\xe1\x00\xf5\x0c\x0d\xe8\x35\xb0\x
 [...]
                },
                "/samples": &vfsgen۰DirInfo{
                        name:    "samples",
@@ -411,10 +411,6 @@ var assets = func() http.FileSystem {
 
                        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\x38\x72\xd3\xa3\x7b\x72\x1c\x1b\x11\x92\xda\xc0\xca\xe9\x62\x8f\x63\x69\x2c\x0d\x4c\x91\x2c\x49\x59\xeb\xbf\x2f\x28\xdb\x5d\x1b\x2d\x8a\x1e\x56\x27\x8a\x1c\xce\x7b\x6f\xde\x63\x86\x4f\xef\xf7\xa9\x0c\x3f\xa4\x62\x13\xb8\x46\xb4\x88\x2d\x63\xe1\xa8\x6a\x19\xa5\x3d\xc4\x81\x3c\x63\x6d\x7b\x53\x53\x14\x6b\xf0\x61\x51\xae\x3f\xa2\x37\x35\x7b\x58\xc3\xb0\x1e\x9d\xf5\x
 [...]
                },
-               "/scorecard": &vfsgen۰DirInfo{
-                       name:    "scorecard",
-                       modTime: time.Time{},
-               },
                "/templates": &vfsgen۰DirInfo{
                        name:    "templates",
                        modTime: time.Time{},
@@ -488,12 +484,10 @@ var assets = func() http.FileSystem {
                fs["/builder"].(os.FileInfo),
                fs["/camel-catalog-1.9.0.yaml"].(os.FileInfo),
                fs["/crd"].(os.FileInfo),
-               fs["/default"].(os.FileInfo),
                fs["/manager"].(os.FileInfo),
                fs["/prometheus"].(os.FileInfo),
                fs["/rbac"].(os.FileInfo),
                fs["/samples"].(os.FileInfo),
-               fs["/scorecard"].(os.FileInfo),
                fs["/templates"].(os.FileInfo),
                fs["/traits.yaml"].(os.FileInfo),
        }
@@ -533,28 +527,31 @@ var assets = func() http.FileSystem {
                fs["/prometheus/operator-prometheus-rule.yaml"].(os.FileInfo),
        }
        fs["/rbac"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
-               
fs["/rbac/operator-cluster-role-console-binding-openshift.yaml"].(os.FileInfo),
-               
fs["/rbac/operator-cluster-role-console-openshift.yaml"].(os.FileInfo),
+               fs["/rbac/openshift"].(os.FileInfo),
                fs["/rbac/operator-role-binding-events.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-binding-knative.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-binding-leases.yaml"].(os.FileInfo),
-               fs["/rbac/operator-role-binding-openshift.yaml"].(os.FileInfo),
                
fs["/rbac/operator-role-binding-podmonitors.yaml"].(os.FileInfo),
                
fs["/rbac/operator-role-binding-service-binding.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-binding-strimzi.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-binding.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-events.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-knative.yaml"].(os.FileInfo),
-               fs["/rbac/operator-role-kubernetes.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-leases.yaml"].(os.FileInfo),
-               fs["/rbac/operator-role-openshift.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-podmonitors.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-service-binding.yaml"].(os.FileInfo),
                fs["/rbac/operator-role-strimzi.yaml"].(os.FileInfo),
+               fs["/rbac/operator-role.yaml"].(os.FileInfo),
                fs["/rbac/user-cluster-role.yaml"].(os.FileInfo),
                
fs["/rbac/user-global-kamelet-viewer-role-binding.yaml"].(os.FileInfo),
                fs["/rbac/user-global-kamelet-viewer-role.yaml"].(os.FileInfo),
        }
+       fs["/rbac/openshift"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
+               
fs["/rbac/openshift/operator-cluster-role-console-binding-openshift.yaml"].(os.FileInfo),
+               
fs["/rbac/openshift/operator-cluster-role-console-openshift.yaml"].(os.FileInfo),
+               
fs["/rbac/openshift/operator-role-binding-openshift.yaml"].(os.FileInfo),
+               
fs["/rbac/openshift/operator-role-openshift.yaml"].(os.FileInfo),
+       }
        fs["/samples"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
                fs["/samples/bases"].(os.FileInfo),
        }
diff --git a/config/prometheus/kustomization.yaml b/script/.vfsignore
similarity index 95%
copy from config/prometheus/kustomization.yaml
copy to script/.vfsignore
index 4cf497f..7fcceda 100644
--- a/config/prometheus/kustomization.yaml
+++ b/script/.vfsignore
@@ -15,4 +15,4 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-resources:
+# This dir and subdirs are not included in VFS
diff --git a/script/Makefile b/script/Makefile
index 4a74b79..ab86c22 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -21,15 +21,36 @@ RUNTIME_VERSION := 1.9.0
 BUILDAH_VERSION := 1.14.0
 KANIKO_VERSION := 0.17.1
 INSTALL_DEFAULT_KAMELETS := true
+CONTROLLER_GEN_VERSION := v0.4.1
+OPERATOR_SDK_VERSION := v1.5.0
+KUSTOMIZE_VERSION := v4.1.2
 BASE_IMAGE := adoptopenjdk/openjdk11:slim
 LOCAL_REPOSITORY := /tmp/artifacts/m2
-IMAGE_NAME ?= docker.io/apache/camel-k
-METADATA_IMAGE_NAME := $(IMAGE_NAME)-metadata
+IMAGE_NAME := docker.io/apache/camel-k
+
+#
+# Situations when user wants to override
+# the image name and version
+# - used in kustomize install
+# - used in making bundle
+# - need to preserve original image and version as used in other files
+#
+CUSTOM_IMAGE ?= $(IMAGE_NAME)
+CUSTOM_VERSION ?= $(VERSION)
+
+METADATA_IMAGE_NAME := $(CUSTOM_IMAGE)-metadata
+BUNDLE_IMAGE_NAME ?= $(CUSTOM_IMAGE)-bundle
 RELEASE_GIT_REMOTE := upstream
 GIT_COMMIT := $(shell git rev-list -1 HEAD)
 LINT_GOGC := 10
 LINT_DEADLINE := 10m
 
+
+# olm bundle vars
+CHANNELS ?= $(OPERATOR_VERSION)
+DEFAULT_CHANNEL ?= $(OPERATOR_VERSION)
+PACKAGE := camel-k
+
 # Used to push pre-release artifacts
 STAGING_IMAGE_NAME := docker.io/camelk/camel-k
 
@@ -98,7 +119,7 @@ codegen:
        @echo "" >> $(VERSIONFILE)
        @echo "const (" >> $(VERSIONFILE)
        @echo "  // Version -- " >> $(VERSIONFILE)
-       @echo "  Version = \"$(VERSION)\"" >> $(VERSIONFILE)
+       @echo "  Version = \"$(CUSTOM_VERSION)\"" >> $(VERSIONFILE)
        @echo "" >> $(VERSIONFILE)
        @echo "  // DefaultRuntimeVersion -- " >> $(VERSIONFILE)
        @echo "  DefaultRuntimeVersion = \"$(RUNTIME_VERSION)\"" >> 
$(VERSIONFILE)
@@ -116,7 +137,7 @@ codegen:
        @echo "  LocalRepository = \"$(LOCAL_REPOSITORY)\"" >> $(VERSIONFILE)
        @echo "" >> $(VERSIONFILE)
        @echo "  // ImageName -- " >> $(VERSIONFILE)
-       @echo "  ImageName = \"$(IMAGE_NAME)\"" >> $(VERSIONFILE)
+       @echo "  ImageName = \"$(CUSTOM_IMAGE)\"" >> $(VERSIONFILE)
        @echo "" >> $(VERSIONFILE)
        @echo "  // installDefaultKamelets -- " >> $(VERSIONFILE)
        @echo "  installDefaultKamelets = $(INSTALL_DEFAULT_KAMELETS)" >> 
$(VERSIONFILE)
@@ -160,6 +181,7 @@ test-integration: build
        go test -timeout 60m -v ./e2e/common/languages -tags=integration && \
        go test -timeout 60m -v ./e2e/common/traits -tags=integration
 
+
 test-knative: build
        STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \
        go test -timeout 60m -v ./e2e/knative -tags=integration
@@ -176,6 +198,10 @@ test-kamel-cli: build
        STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \
        go test -timeout 60m -v ./e2e/common/cli -tags=integration
 
+test-kustomize: build
+       STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \
+       go test -timeout 60m -v ./e2e/common/kustomize -tags=integration
+
 test-quarkus-native: build
        STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \
        go test -timeout 60m -v ./e2e/native -tags=integration
@@ -247,6 +273,9 @@ lint-fix:
 check-licenses:
        ./script/check_licenses.sh
 
+check-platform:
+       ./script/check_platform.sh
+
 maven-overlay:
        mkdir -p build/_maven_overlay
        ./script/maven_overlay.sh build/_maven_overlay
@@ -259,7 +288,7 @@ ifneq ($(shell uname -s 2>/dev/null || echo Unknown),Linux)
 else
        cp kamel build/_output/bin
 endif
-       docker build -t $(IMAGE_NAME):$(VERSION) -f build/Dockerfile .
+       docker build -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile .
 
 images-dev: bundle-kamelets test package-artifacts maven-overlay
        mkdir -p build/_maven_output
@@ -269,35 +298,35 @@ ifneq ($(shell uname -s 2>/dev/null || echo 
Unknown),Linux)
 else
        cp kamel build/_output/bin
 endif
-       docker build -t $(IMAGE_NAME):$(VERSION) -f build/Dockerfile .
+       docker build -t $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -f build/Dockerfile .
 
 images-push:
-       docker push $(IMAGE_NAME):$(VERSION)
+       docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION)
 
 images-push-staging:
-       docker tag $(IMAGE_NAME):$(VERSION) $(STAGING_IMAGE_NAME):$(VERSION)
-       docker push $(STAGING_IMAGE_NAME):$(VERSION)
+       docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION) 
$(STAGING_IMAGE_NAME):$(CUSTOM_VERSION)
+       docker push $(STAGING_IMAGE_NAME):$(CUSTOM_VERSION)
 
 get-version:
-       @echo $(VERSION)
+       @echo $(CUSTOM_VERSION)
 
 get-last-released-version:
        @echo $(LAST_RELEASED_VERSION)
 
 set-version:
-       ./script/set_version.sh $(VERSION) $(IMAGE_NAME)
+       ./script/set_version.sh $(CUSTOM_VERSION) $(CUSTOM_IMAGE)
 
 set-module-version:
-       ./script/set_go_modules_version.sh $(VERSION)
+       ./script/set_go_modules_version.sh $(CUSTOM_VERSION)
 
 git-tag:
-       ./script/git_tag.sh $(VERSION) $(RELEASE_GIT_REMOTE)
+       ./script/git_tag.sh $(CUSTOM_VERSION) $(RELEASE_GIT_REMOTE)
 
 cross-compile:
-       ./script/cross_compile.sh $(VERSION) '$(GOFLAGS)'
+       ./script/cross_compile.sh $(CUSTOM_VERSION) '$(GOFLAGS)'
 
 package-examples:
-       ./script/package_examples.sh $(VERSION)
+       ./script/package_examples.sh $(CUSTOM_VERSION)
 
 package-artifacts:
        ./script/package_maven_artifacts.sh $(RUNTIME_VERSION) 
$(PACKAGE_ARTIFACTS_STRATEGY) $(STAGING_RUNTIME_REPO)
@@ -312,7 +341,7 @@ release-helm:
        ./script/release_helm.sh
 
 install-crc:
-       ./script/install_crc.sh $(VERSION)
+       ./script/install_crc.sh $(CUSTOM_VERSION)
 install-minikube:
        ./script/install_minikube.sh
 
@@ -329,7 +358,7 @@ ifeq (, $(shell which controller-gen))
        CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
        cd $$CONTROLLER_GEN_TMP_DIR ;\
        go mod init tmp ;\
-       go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1 ;\
+       go get 
sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION) ;\
        rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
        }
 CONTROLLER_GEN=$(GOBIN)/controller-gen
@@ -337,6 +366,13 @@ else
 CONTROLLER_GEN=$(shell which controller-gen)
 endif
 
+.PHONY: kubectl kustomize operator-sdk
+
+kubectl:
+ifeq (, $(shell which kubectl))
+$(error "No kubectl found in PATH. Please install and re-run")
+endif
+
 kustomize:
 ifeq (, $(shell which kustomize))
        @{ \
@@ -344,7 +380,7 @@ ifeq (, $(shell which kustomize))
        KUSTOMIZE_GEN_TMP_DIR=$$(mktemp -d) ;\
        cd $$KUSTOMIZE_GEN_TMP_DIR ;\
        go mod init tmp ;\
-       go get sigs.k8s.io/kustomize/kustomize/v3@v3.5.4 ;\
+       go get sigs.k8s.io/kustomize/kustomize/v4@$(KUSTOMIZE_VERSION) ;\
        rm -rf $$KUSTOMIZE_GEN_TMP_DIR ;\
        }
 KUSTOMIZE=$(GOBIN)/kustomize
@@ -352,6 +388,21 @@ else
 KUSTOMIZE=$(shell which kustomize)
 endif
 
+operator-sdk:
+ifeq (, $(shell which operator-sdk))
+       @{ \
+       set -e ;\
+       curl \
+               -L 
https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_linux_amd64
 \
+               -o operator-sdk ;\
+       chmod +x operator-sdk ;\
+       mv operator-sdk $(GOBIN)/ ;\
+       }
+OPERATOR_SDK=$(GOBIN)/operator-sdk
+else
+OPERATOR_SDK=$(shell which operator-sdk)
+endif
+
 .PHONY: generate-crd $(BUNDLE_CAMEL_APIS) bundle bundle-build
 
 # - Have to copy pkg/apis since it is a module in its own right
@@ -360,32 +411,49 @@ endif
 # - No way to add a licence header to the CRD other then post-script
 BUNDLE_CAMEL_APIS = v1 v1alpha1
 
-$(BUNDLE_CAMEL_APIS):
+$(BUNDLE_CAMEL_APIS): operator-sdk
        @# Clean up api directory, copy over fresh version
        rm -rf api_$@ && cp -rf pkg/apis api_$@
        @# Remove the camel directory and re-copy only the required api
        rm -rf api_$@/camel/* && cp -rf pkg/apis/camel/$@ api_$@/camel/
        @# operator-sdk generate ... cannot execute across separate modules so 
need to temporarily move api
-       operator-sdk generate kustomize manifests --apis-dir $(addprefix api_, 
$@) -q
+       $(OPERATOR_SDK) generate kustomize manifests --apis-dir $(addprefix 
api_, $@) -q
        @# Adds the licence header to the csv file.
        ./script/add_license.sh config/manifests/bases ./script/headers/yaml.txt
        ./script/add_createdAt.sh config/manifests/bases
        @# Clean up temporary working api directories
        rm -rf api_*
 
-bundle: generate-crd $(BUNDLE_CAMEL_APIS) kustomize
+# Options for 'bundle-build'
+ifneq ($(origin CHANNELS), undefined)
+BUNDLE_CHANNELS := --channels=$(CHANNELS)
+endif
+ifneq ($(origin DEFAULT_CHANNEL), undefined)
+BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL)
+endif
+ifneq ($(origin PACKAGE), undefined)
+BUNDLE_PACKAGE := --package=$(PACKAGE)
+endif
+BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) 
$(BUNDLE_PACKAGE)
+
+bundle: set-version generate-crd $(BUNDLE_CAMEL_APIS) kustomize operator-sdk
+       @# Sets the operator image to the preferred image:tag
+       @cd config/manifests && $(KUSTOMIZE) edit set image 
$(IMAGE_NAME)=$(CUSTOM_IMAGE):$(CUSTOM_VERSION)
        @# Build kustomize manifests
-       $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle 
--overwrite --version $(OPERATOR_VERSION) $(BUNDLE_METADATA_OPTS)
+       @$(KUSTOMIZE) build config/manifests | \
+               $(OPERATOR_SDK) generate bundle \
+                       -q --overwrite --version $(OPERATOR_VERSION) \
+                       --kustomize-dir config/manifests $(BUNDLE_METADATA_OPTS)
        @# Move the dockerfile into the bundle directory
 ifeq ($(shell uname -s 2>/dev/null || echo Unknown),Darwin)
-       mv bundle.Dockerfile bundle/Dockerfile && sed -i '' 's/bundle\///g' 
bundle/Dockerfile
+       @mv bundle.Dockerfile bundle/Dockerfile && sed -i '' 's/bundle\///g' 
bundle/Dockerfile
 else
-       mv bundle.Dockerfile bundle/Dockerfile && sed -i 's/bundle\///g' 
bundle/Dockerfile
+       @mv bundle.Dockerfile bundle/Dockerfile && sed -i 's/bundle\///g' 
bundle/Dockerfile
 endif
        @# Adds the licence headers to the csv file
        ./script/add_license.sh bundle/manifests ./script/headers/yaml.txt
-       operator-sdk bundle validate ./bundle
+       $(OPERATOR_SDK) bundle validate ./bundle
 
 # Build the bundle image.
 bundle-build: bundle
-       cd bundle && docker build -f Dockerfile -t $(METADATA_IMAGE_NAME) .
+       cd bundle && docker build -f Dockerfile -t $(BUNDLE_IMAGE_NAME) .
diff --git a/script/check_platform.sh b/script/check_platform.sh
new file mode 100755
index 0000000..2b43f18
--- /dev/null
+++ b/script/check_platform.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+# 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.
+
+check_platform() {
+       set +e
+  echo $(./platform-check)
+       set -e
+}
+
+is_binary_available() {
+
+  client="${1}"
+
+  # Check path first if it already exists
+  set +e
+  which "${client}" &>/dev/null
+  if [ $? -eq 0 ]; then
+    set -e
+    echo "OK"
+    return
+  fi
+
+  set -e
+
+  # Error, no oc found
+  echo "ERROR: No '${client}' binary found in path."
+}
+
+location=$(dirname $0)
+rootdir=$location/../
+
+cd $rootdir
+if [ -d "./cmd/util/platform-check" ]; then
+
+       hasgo=$(is_binary_available "go")
+       if [ "${hasgo}" == "OK" ]; then
+               go build ./cmd/util/platform-check/
+               if [ $? == 0 ]; then
+                       go_result=$(check_platform)
+               else
+                       go_result="ERROR: failed to build platform-check binary"
+               fi
+
+       else
+               go_result="ERROR: cannot build platform-check"
+       fi
+
+else
+       go_result="ERROR: platform-check is not available"
+fi
+
+if [ -z "${go_result##*ERROR*}" ]; then
+       #
+       # Fallback to finding using the client binary
+       #
+       client="oc"
+       hasclient=$(is_binary_available "${client}")
+       if [ "${hasclient}" != "OK" ]; then
+         client="kubectl"
+         hasclient=$(is_binary_available "${client}")
+         if [ "${hasclient}" != "OK" ]; then
+           echo "ERROR: No kube client installed."
+           exit 1
+         fi
+       fi
+
+       api=$("${client}" api-versions | grep openshift)
+       if [ $? -eq 0 ]; then
+         echo "openshift"
+       else
+         echo "kubernetes"
+       fi
+else
+  echo "${go_result}"
+fi
diff --git a/script/set_version.sh b/script/set_version.sh
index d906948..ff61ab6 100755
--- a/script/set_version.sh
+++ b/script/set_version.sh
@@ -27,30 +27,29 @@ version=$1
 image_name=${2:-docker.io\/apache\/camel-k}
 sanitized_image_name=${image_name//\//\\\/}
 
-
 for f in $(find $location/../config/manager -type f -name "*.yaml");
 do
   if [[ "$OSTYPE" == "linux-gnu"* ]]; then
-    sed -i -r 
"s/docker.io\/apache\/camel-k:([0-9]+[a-zA-Z0-9\-\.].*).*/${sanitized_image_name}:${version}/"
 $f
+    sed -i -r "s/image: .*/image: ${sanitized_image_name}:${version}/" $f
   elif [[ "$OSTYPE" == "darwin"* ]]; then
     # Mac OSX
-    sed -i '' -E 
"s/docker.io\/apache\/camel-k:([0-9]+[a-zA-Z0-9\-\.].*).*/${sanitized_image_name}:${version}/"
 $f
+    sed -i '' -E "s/image: .*/image: ${sanitized_image_name}:${version}/" $f
   fi
 done
 
 for f in $(find $location/../config/manifests/bases -type f -name "*.yaml");
 do
   if [[ "$OSTYPE" == "linux-gnu"* ]]; then
-    sed -i -r 
"s/docker.io\/apache\/camel-k:([0-9]+[a-zA-Z0-9\-\.].*).*/${sanitized_image_name}:${version}/"
 $f
+    sed -i -r "s/containerImage: .*/containerImage: 
${sanitized_image_name}:${version}/" $f
   elif [[ "$OSTYPE" == "darwin"* ]]; then
     # Mac OSX
-    sed -i '' -E 
"s/docker.io\/apache\/camel-k:([0-9]+[a-zA-Z0-9\-\.].*).*/${sanitized_image_name}:${version}/"
 $f
+    sed -i '' -E "s/containerImage: .*/containerImage: 
${sanitized_image_name}:${version}/" $f
   fi
 done
 
 # Update helm chart
 if [[ "$OSTYPE" == "linux-gnu"* ]]; then
-  sed -i -r 
"s/docker.io\/apache\/camel-k:([0-9]+[a-zA-Z0-9\-\.].*).*/${sanitized_image_name}:${version}/"
 $location/../helm/camel-k/values.yaml
+  sed -i -r "s/image: .*/image: ${sanitized_image_name}:${version}/" 
$location/../helm/camel-k/values.yaml
   sed -i -r "s/appVersion:\s([0-9]+[a-zA-Z0-9\-\.].*).*/appVersion: 
${version}/" $location/../helm/camel-k/Chart.yaml
 elif [[ "$OSTYPE" == "darwin"* ]]; then
   # Mac OSX

Reply via email to