Repository: apache/camel-k
Pull request #3432 (2022-07-11 08:08:11)

feat(build): Golang 1.17
<!-- Description -->

With this PR we requires Golang 1.17 minimum version for build. Codegen tools are always installed in order to make sure to use the expected version (instead of using the cached one that may become obsolete).

Supersede #3426 


<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
feat(build): Golang 1.17
```


squakez: I've made some important change to how we interact with codegen tools. Now we install them in order to make sure we use the proper version. Thanks for your suggestions @tadayosi, feel free to have a further look now.

Patch:
diff --git a/.github/actions/kamel-config-cluster-ocp3/action.yml b/.github/actions/kamel-config-cluster-ocp3/action.yml
index 613d22bf2..6f26853d6 100644
--- a/.github/actions/kamel-config-cluster-ocp3/action.yml
+++ b/.github/actions/kamel-config-cluster-ocp3/action.yml
@@ -199,7 +199,7 @@ runs:
       if: ${{ env.CLUSTER_OCP3_CONFIGURED != 'true' }}
       run: |
         echo "::set-output name=cluster-image-registry-pull-host::"
-        echo "::set-output name=cluster-image-registry-pull-host::"
+        echo "::set-output name=cluster-image-registry-push-host::"
         echo "::set-output name=cluster-image-registry-insecure::$(echo true)"
         echo "::set-output name=cluster-has-olm::$(echo false)"
         echo "::set-output name=cluster-image-namespace::$(echo apache)"
diff --git a/.github/actions/kamel-prepare-env/action.yml b/.github/actions/kamel-prepare-env/action.yml
index 45871e10b..0204dfd4e 100644
--- a/.github/actions/kamel-prepare-env/action.yml
+++ b/.github/actions/kamel-prepare-env/action.yml
@@ -75,7 +75,7 @@ runs:
       uses: actions/setup-go@v2 # Version 2 adds GOBIN to PATH
       if: ${{ env.KAMEL_PREPARE_ENV != 'true' }}
       with:
-        go-version: 1.16.x
+        go-version: 1.17.x
 
     - name: (Re-)install kustomize
       shell: bash
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 217b404c5..0c3bf48f8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -64,6 +64,5 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Execute Build Tests
       uses: ./.github/actions/e2e-build
diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml
index 1c9e5f8b3..8050a3a6d 100644
--- a/.github/workflows/builder.yml
+++ b/.github/workflows/builder.yml
@@ -75,7 +75,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Convert input parameters to env vars
       shell: bash
       run: |
diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml
index 4bdfb51d4..bbc948a91 100644
--- a/.github/workflows/common.yml
+++ b/.github/workflows/common.yml
@@ -75,7 +75,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Convert input parameters to env vars
       shell: bash
       run: |
diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml
index a3a44f334..70ef4eef1 100644
--- a/.github/workflows/install.yml
+++ b/.github/workflows/install.yml
@@ -74,7 +74,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Convert input parameters to env vars
       shell: bash
       run: |
diff --git a/.github/workflows/knative.yml b/.github/workflows/knative.yml
index 0c3c5c5a5..3009fd942 100644
--- a/.github/workflows/knative.yml
+++ b/.github/workflows/knative.yml
@@ -71,7 +71,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Convert input parameters to env vars
       shell: bash
       run: |
diff --git a/.github/workflows/openshift.yml b/.github/workflows/openshift.yml
index a9d2eee10..006989704 100644
--- a/.github/workflows/openshift.yml
+++ b/.github/workflows/openshift.yml
@@ -44,6 +44,21 @@ on:
       - 'NOTICE'
   workflow_dispatch:
     inputs:
+      pre-built-kamel-image:
+        description: 'Kamel image url for skipping building of kamel stages. Used for debugging'
+        required: false
+      skip-problematic:
+        description: 'Whether tests marked as problematic should be skipped - false by default (sets CAMEL_K_TEST_SKIP_PROBLEMATIC)'
+        required: false
+        default: false
+      test-filters:
+        description: |
+          List of comma-separated key/value pairs to filter the tests in this test suite:
+            TEST_INTEGRATION_COMMON_RUN,        TEST_INTEGRATION_COMMON_BUILD_RUN, TEST_INTEGRATION_COMMON_CONFIG_RUN,
+            TEST_INTEGRATION_COMMON_LANG_RUN,   TEST_INTEGRATION_COMMON_TRAITS_RUN
+            TEST_SERVICE_RUN,                   TEST_REGISTRY_MAVEN_WAGON_RUN
+          eg. TEST_INTEGRATION_COMMON_RUN=TestBasic will only run tests prefixed with 'TestBasic'
+        required: false
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
@@ -60,7 +75,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - id: prepare-env
       name: Prepare Test Environment
       uses: ./.github/actions/kamel-prepare-env
@@ -92,9 +106,10 @@ jobs:
     - name: Run IT 1
       run: |
         # Then run integration tests
+        export CAMEL_K_CLUSTER_OCP3=true
+
         make test-integration
         make test-builder
-        make test-quarkus-native
 
     - id: change-context
       name: Change the Kamel Cluster Context to Admin
@@ -105,4 +120,7 @@ jobs:
     - name: Run IT 2
       run: |
         # Then run integration tests
+        export CAMEL_K_CLUSTER_OCP3=true
+
+        make test-quarkus-native
         make test-install
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a572ea178..785bc57ed 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -30,9 +30,9 @@ jobs:
       with:
         version: "11"
     - name: Install Go
-      uses: actions/setup-go@v1
+      uses: actions/setup-go@v2
       with:
-        go-version: 1.16.x
+        go-version: 1.17.x
     - name: Checkout code
       uses: actions/checkout@v2
     - name: Cache modules
diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade.yml
index 09eec212a..01fd3cba3 100644
--- a/.github/workflows/upgrade.yml
+++ b/.github/workflows/upgrade.yml
@@ -71,7 +71,6 @@ jobs:
       with:
         persist-credentials: false
         submodules: recursive
-
     - name: Convert input parameters to env vars
       shell: bash
       run: |
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
index b635a8470..33c7927a0 100644
--- a/.github/workflows/validate.yml
+++ b/.github/workflows/validate.yml
@@ -38,9 +38,9 @@ jobs:
       - name: Check out code
         uses: actions/checkout@v2
       - name: Install Go
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          go-version: 1.16.x
+          go-version: 1.17.x
       - name: golangci-lint
         uses: golangci/golangci-lint-action@v2
         env:
diff --git a/.github/workflows/verify-generate.yml b/.github/workflows/verify-generate.yml
index ed66309c2..00ea3cb9c 100644
--- a/.github/workflows/verify-generate.yml
+++ b/.github/workflows/verify-generate.yml
@@ -60,10 +60,9 @@ jobs:
       - name: Check out code
         uses: actions/checkout@v2
       - name: Install Go
-        uses: actions/setup-go@v1
+        uses: actions/setup-go@v2
         with:
-          # make generate requires Go >=1.17
-          go-version: 1.17.x
+          go-version: 1.17.x        
       - name: Test generate
         shell: bash
         run: make generate
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 641a451c2..dca640af9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
 
 **Closed issues:**
 
+- `make generate-doc` outputs non-deterministic `resources/traits.yaml` [\#3431](https://github.com/apache/camel-k/issues/3431)
 - Camel K integration Prometheus Trait label autocreation with Integration Platform not working [\#3415](https://github.com/apache/camel-k/issues/3415)
 - Migrate from batch/v1beta1 to batch/v1 [\#3393](https://github.com/apache/camel-k/issues/3393)
 - RBAC missing permissions for channels and inmemorychannels in messaging.knative.dev [\#3390](https://github.com/apache/camel-k/issues/3390)
diff --git a/go.mod b/go.mod
index 4ee008a89..ab996c419 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/apache/camel-k
 
-go 1.16
+go 1.17
 
 require (
 	github.com/Masterminds/semver v1.5.0
@@ -64,6 +64,104 @@ require (
 	sigs.k8s.io/controller-runtime v0.10.3
 )
 
+require (
+	cloud.google.com/go/compute v1.6.1 // indirect
+	contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect
+	contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect
+	github.com/Azure/go-autorest v14.2.0+incompatible // indirect
+	github.com/Azure/go-autorest/autorest v0.11.24 // indirect
+	github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
+	github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
+	github.com/Azure/go-autorest/logger v0.2.1 // indirect
+	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
+	github.com/Microsoft/go-winio v0.5.1 // indirect
+	github.com/Microsoft/hcsshim v0.8.23 // indirect
+	github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211221011931-643d94fcab96 // indirect
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
+	github.com/blendle/zapdriver v1.3.1 // indirect
+	github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
+	github.com/cloudevents/sdk-go/sql/v2 v2.8.0 // indirect
+	github.com/cloudevents/sdk-go/v2 v2.8.0 // indirect
+	github.com/containerd/continuity v0.1.0 // indirect
+	github.com/containerd/stargz-snapshotter/estargz v0.10.1 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/docker/cli v20.10.12+incompatible // indirect
+	github.com/docker/distribution v2.7.1+incompatible // indirect
+	github.com/docker/docker v20.10.12+incompatible // indirect
+	github.com/docker/docker-credential-helpers v0.6.4 // indirect
+	github.com/docker/go-units v0.4.0 // indirect
+	github.com/evanphx/json-patch/v5 v5.6.0 // indirect
+	github.com/fsnotify/fsnotify v1.5.4 // indirect
+	github.com/go-kit/log v0.2.0 // indirect
+	github.com/go-logfmt/logfmt v0.5.1 // indirect
+	github.com/go-logr/zapr v0.4.0 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
+	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/btree v1.0.1 // indirect
+	github.com/google/go-cmp v0.5.8 // indirect
+	github.com/google/go-containerregistry v0.8.1-0.20220120151853-ac864e57b117 // indirect
+	github.com/google/go-querystring v1.0.0 // indirect
+	github.com/google/gofuzz v1.2.0 // indirect
+	github.com/googleapis/gnostic v0.5.5 // indirect
+	github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
+	github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
+	github.com/hashicorp/golang-lru v0.5.4 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/imdario/mergo v0.3.12 // indirect
+	github.com/inconshreveable/mousetrap v1.0.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/kelseyhightower/envconfig v1.4.0 // indirect
+	github.com/klauspost/compress v1.13.6 // indirect
+	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
+	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+	github.com/moby/spdystream v0.2.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/opencontainers/go-digest v1.0.0 // indirect
+	github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 // indirect
+	github.com/opencontainers/runc v1.0.2 // indirect
+	github.com/pelletier/go-toml v1.9.5 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
+	github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/prometheus/procfs v0.7.3 // indirect
+	github.com/prometheus/statsd_exporter v0.21.0 // indirect
+	github.com/rickb777/date v1.13.0 // indirect
+	github.com/rickb777/plural v1.2.1 // indirect
+	github.com/robfig/cron/v3 v3.0.1 // indirect
+	github.com/spf13/afero v1.8.2 // indirect
+	github.com/spf13/cast v1.5.0 // indirect
+	github.com/spf13/jwalterweatherman v1.1.0 // indirect
+	github.com/subosito/gotenv v1.3.0 // indirect
+	github.com/vbatts/tar-split v0.11.2 // indirect
+	go.opencensus.io v0.23.0 // indirect
+	go.uber.org/atomic v1.9.0 // indirect
+	golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
+	golang.org/x/mod v0.5.1 // indirect
+	golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
+	golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+	golang.org/x/text v0.3.7 // indirect
+	golang.org/x/tools v0.1.8 // indirect
+	golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
+	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
+	google.golang.org/api v0.81.0 // indirect
+	google.golang.org/appengine v1.6.7 // indirect
+	google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
+	google.golang.org/grpc v1.46.2 // indirect
+	google.golang.org/protobuf v1.28.0 // indirect
+	gopkg.in/ini.v1 v1.66.4 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+	k8s.io/component-base v0.22.5 // indirect
+	k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
+	knative.dev/networking v0.0.0-20220120043934-ec785540a732 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
+	sigs.k8s.io/yaml v1.3.0 // indirect
+)
+
 replace (
 	github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm
 	github.com/go-logr/logr => github.com/go-logr/logr v0.4.0
diff --git a/go.sum b/go.sum
index 5bc79daf9..b8d46c9f6 100644
--- a/go.sum
+++ b/go.sum
@@ -2083,7 +2083,6 @@ k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8
 k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo=
 k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
 k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
-k8s.io/code-generator v0.22.5 h1:jn+mYXI5q7rzo7Bz/n8xZIgbe61SeXlIjU5jA8jLVps=
 k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk=
 k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
 k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k=
diff --git a/install/Makefile b/install/Makefile
index f9aa2708f..d5e4ed862 100644
--- a/install/Makefile
+++ b/install/Makefile
@@ -155,6 +155,16 @@ endif
 check-admin: kubectl
 	@output=$$(kubectl get crd 2>&1) || (echo "****" && echo "**** ERROR: Cannot continue as user is not a Cluster-Admin ****" && echo "****"; exit 1)
 
+crd-api-support: kubectl
+ifndef CRD_SUPPORT
+CRD_SUPPORT=$(shell script/check_crd_api_support.sh)
+endif
+
+check-crd-api-support: crd-api-support
+ifneq ($(CRD_SUPPORT),OK)
+	$(error *** CRD API FAILURE: $(CRD_SUPPORT) ****)
+endif
+
 #
 # Setup the cluster installation by installing crds and cluster roles.
 #
@@ -168,7 +178,7 @@ check-admin: kubectl
 #   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
+setup-cluster: check-admin check-crd-api-support have-platform kustomize kubectl
 # Set the namespace in the setup-cluster kustomization yaml
 	@$(call set-kustomize-namespace,$@)
 ifeq ($(PLATFORM), openshift)
@@ -270,7 +280,7 @@ endif
 #   LOGGING_LEVEL:      Set the level of logging [info|debug]
 #   DRY_RUN:            Prints the resources to be applied instead of applying them
 #
-operator: check-admin have-platform kustomize kubectl .operator-port-patch .operator-log-level-patch
+operator: check-admin have-platform check-crd-api-support kustomize kubectl .operator-port-patch .operator-log-level-patch
 ifeq ($(MONITORING), true)
 	@$(MAKE) -s .operator-can-monitor
 	@$(call add-remove-operator-monitoring,$@,add)
diff --git a/install/script/check_crd_api_support.sh b/install/script/check_crd_api_support.sh
new file mode 120000
index 000000000..3d144aabd
--- /dev/null
+++ b/install/script/check_crd_api_support.sh
@@ -0,0 +1,1 @@
+../../script/check_crd_api_support.sh
\ No newline at end of file
diff --git a/pkg/apis/camel/go.mod b/pkg/apis/camel/go.mod
index 19796442d..d825b8b33 100644
--- a/pkg/apis/camel/go.mod
+++ b/pkg/apis/camel/go.mod
@@ -1,9 +1,28 @@
 module github.com/apache/camel-k/pkg/apis/camel
 
-go 1.16
+go 1.17
 
 require (
 	github.com/stretchr/testify v1.7.0
 	k8s.io/api v0.22.5
 	k8s.io/apimachinery v0.22.5
 )
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/go-logr/logr v0.4.0 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/google/go-cmp v0.5.5 // indirect
+	github.com/google/gofuzz v1.1.0 // indirect
+	github.com/json-iterator/go v1.1.11 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
+	golang.org/x/text v0.3.6 // indirect
+	gopkg.in/inf.v0 v0.9.1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	k8s.io/klog/v2 v2.9.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
+)
diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go
index 5b6fd9130..50316a081 100644
--- a/pkg/apis/camel/v1/integration_types_support.go
+++ b/pkg/apis/camel/v1/integration_types_support.go
@@ -105,14 +105,7 @@ func (in *IntegrationSpec) AddDependency(dependency string) {
 	if in.Dependencies == nil {
 		in.Dependencies = make([]string, 0)
 	}
-	newDep := dependency
-	if strings.HasPrefix(newDep, "camel-quarkus-") {
-		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus-")
-	} else if strings.HasPrefix(newDep, "camel-quarkus:") {
-		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus:")
-	} else if strings.HasPrefix(newDep, "camel-") {
-		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-")
-	}
+	newDep := NormalizeDependency(dependency)
 	for _, d := range in.Dependencies {
 		if d == newDep {
 			return
@@ -121,6 +114,22 @@ func (in *IntegrationSpec) AddDependency(dependency string) {
 	in.Dependencies = append(in.Dependencies, newDep)
 }
 
+// NormalizeDependency converts different forms of camel dependencies
+// -- `camel-xxx`, `camel-quarkus-xxx`, and `camel-quarkus:xxx` --
+// into the unified form `camel:xxx`.
+func NormalizeDependency(dependency string) string {
+	newDep := dependency
+	switch {
+	case strings.HasPrefix(newDep, "camel-quarkus-"):
+		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus-")
+	case strings.HasPrefix(newDep, "camel-quarkus:"):
+		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-quarkus:")
+	case strings.HasPrefix(newDep, "camel-"):
+		newDep = "camel:" + strings.TrimPrefix(dependency, "camel-")
+	}
+	return newDep
+}
+
 // GetConfigurationProperty returns a configuration property
 func (in *IntegrationSpec) GetConfigurationProperty(property string) string {
 	for _, confSpec := range in.Configuration {
diff --git a/pkg/client/camel/go.mod b/pkg/client/camel/go.mod
index fb7ea4a71..9e5ed510a 100644
--- a/pkg/client/camel/go.mod
+++ b/pkg/client/camel/go.mod
@@ -1,13 +1,43 @@
 module github.com/apache/camel-k/pkg/client/camel
 
-go 1.16
+go 1.17
 
 require (
 	github.com/apache/camel-k/pkg/apis/camel v0.0.0
 	k8s.io/api v0.22.5
 	k8s.io/apimachinery v0.22.5
 	k8s.io/client-go v0.22.5
-	k8s.io/code-generator v0.22.5 // indirect
+)
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/evanphx/json-patch v4.11.0+incompatible // indirect
+	github.com/go-logr/logr v0.4.0 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/go-cmp v0.5.5 // indirect
+	github.com/google/gofuzz v1.1.0 // indirect
+	github.com/googleapis/gnostic v0.5.5 // indirect
+	github.com/json-iterator/go v1.1.11 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
+	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
+	golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
+	golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
+	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+	google.golang.org/appengine v1.6.5 // indirect
+	google.golang.org/protobuf v1.26.0 // indirect
+	gopkg.in/inf.v0 v0.9.1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	k8s.io/klog/v2 v2.9.0 // indirect
+	k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect
+	k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
+	sigs.k8s.io/yaml v1.2.0 // indirect
 )
 
 // Local modules
diff --git a/pkg/client/camel/go.sum b/pkg/client/camel/go.sum
index 68d9bc66c..5042fd6e3 100644
--- a/pkg/client/camel/go.sum
+++ b/pkg/client/camel/go.sum
@@ -46,7 +46,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
@@ -60,15 +59,11 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
 github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
-github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -130,7 +125,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -146,7 +140,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -186,12 +179,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -233,8 +224,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -257,7 +246,6 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -273,7 +261,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -301,9 +288,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -352,11 +337,8 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -451,13 +433,8 @@ k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s=
 k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
 k8s.io/client-go v0.22.5 h1:I8Zn/UqIdi2r02aZmhaJ1hqMxcpfJ3t5VqvHtctHYFo=
 k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
-k8s.io/code-generator v0.22.5 h1:jn+mYXI5q7rzo7Bz/n8xZIgbe61SeXlIjU5jA8jLVps=
-k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk=
 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw=
-k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
-k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
 k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80=
diff --git a/pkg/cmd/local.go b/pkg/cmd/local.go
index cac6e51d5..1a480490f 100644
--- a/pkg/cmd/local.go
+++ b/pkg/cmd/local.go
@@ -20,25 +20,57 @@ package cmd
 import (
 	"fmt"
 
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/spf13/cobra"
 )
 
 // newCmdLocal -- Add local kamel subcommand with several other subcommands of its own.
-func newCmdLocal(rootCmdOptions *RootCmdOptions) *cobra.Command {
+func newCmdLocal(rootCmdOptions *RootCmdOptions) (*cobra.Command, *LocalCmdOptions) {
+	options := LocalCmdOptions{
+		RootCmdOptions: rootCmdOptions,
+	}
+
 	cmd := cobra.Command{
-		Use:   "local [sub-command]",
-		Short: "Perform integration actions locally.",
-		Long:  `Perform integration actions locally given a set of input integration files.`,
+		Use:               "local [sub-command]",
+		Short:             "Perform integration actions locally.",
+		Long:              `Perform integration actions locally given a set of input integration files.`,
+		PersistentPreRunE: options.persistentPreRun,
 		Annotations: map[string]string{
 			offlineCommandLabel: "true",
 		},
 	}
 
-	cmd.AddCommand(cmdOnly(newCmdLocalBuild(rootCmdOptions)))
-	cmd.AddCommand(cmdOnly(newCmdLocalInspect(rootCmdOptions)))
-	cmd.AddCommand(cmdOnly(newCmdLocalRun(rootCmdOptions)))
+	cmd.PersistentFlags().StringArrayVarP(&options.Dependencies, "dependency", "d", nil, usageDependency)
+
+	// hidden flags for compatibility with kamel run
+	cmd.PersistentFlags().StringArrayVarP(&options.Traits, "trait", "t", nil, "")
+	if err := cmd.PersistentFlags().MarkHidden("trait"); err != nil {
+		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
+	}
+
+	cmd.AddCommand(cmdOnly(newCmdLocalBuild(&options)))
+	cmd.AddCommand(cmdOnly(newCmdLocalInspect(&options)))
+	cmd.AddCommand(cmdOnly(newCmdLocalRun(&options)))
+
+	return &cmd, &options
+}
+
+type LocalCmdOptions struct {
+	*RootCmdOptions
+	Dependencies []string `mapstructure:"dependencies"`
+	Traits       []string `mapstructure:"traits"`
+}
+
+func (o *LocalCmdOptions) persistentPreRun(cmd *cobra.Command, args []string) error {
+	// pre-process dependencies
+	for i, dependency := range o.Dependencies {
+		o.Dependencies[i] = v1.NormalizeDependency(dependency)
+	}
+
+	// validate traits
+	warnTraitUsages(cmd, o.Traits)
 
-	return &cmd
+	return nil
 }
 
 func warnTraitUsages(cmd *cobra.Command, traits []string) {
diff --git a/pkg/cmd/local_build.go b/pkg/cmd/local_build.go
index 222c510de..5c0d72cd4 100644
--- a/pkg/cmd/local_build.go
+++ b/pkg/cmd/local_build.go
@@ -26,9 +26,9 @@ import (
 	"github.com/apache/camel-k/pkg/util"
 )
 
-func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localBuildCmdOptions) {
+func newCmdLocalBuild(localCmdOptions *LocalCmdOptions) (*cobra.Command, *localBuildCmdOptions) {
 	options := localBuildCmdOptions{
-		RootCmdOptions: rootCmdOptions,
+		LocalCmdOptions: localCmdOptions,
 	}
 
 	cmd := cobra.Command{
@@ -37,7 +37,7 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localBui
 		Long:    `Build integration images locally for containerized integrations.`,
 		PreRunE: decode(&options),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := options.validate(cmd, args); err != nil {
+			if err := options.validate(args); err != nil {
 				return err
 			}
 			if err := options.init(args); err != nil {
@@ -64,50 +64,38 @@ func newCmdLocalBuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localBui
 	cmd.Flags().String("integration-directory", "", "Directory to hold local integration files.")
 	cmd.Flags().StringArray("property-file", nil, "Add a property file to the integration.")
 	cmd.Flags().StringArrayP("property", "p", nil, "Add a Camel property to the integration.")
-	cmd.Flags().StringArrayP("dependency", "d", nil, "Add an additional dependency")
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
-	// hidden flags for compatibility with kamel run
-	cmd.Flags().StringArrayP("trait", "t", nil, "")
-	if err := cmd.Flags().MarkHidden("trait"); err != nil {
-		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
-	}
-
 	return &cmd, &options
 }
 
 type localBuildCmdOptions struct {
-	*RootCmdOptions
-	BaseImage              bool     `mapstructure:"base-image"`
-	DependenciesOnly       bool     `mapstructure:"dependencies-only"`
-	ContainerRegistry      string   `mapstructure:"container-registry"`
-	Image                  string   `mapstructure:"image"`
-	IntegrationDirectory   string   `mapstructure:"integration-directory"`
-	AdditionalDependencies []string `mapstructure:"dependencies"`
-	Properties             []string `mapstructure:"properties"`
-	PropertyFiles          []string `mapstructure:"property-files"`
-	MavenRepositories      []string `mapstructure:"maven-repositories"`
-	Traits                 []string `mapstructure:"traits"`
+	*LocalCmdOptions
+	BaseImage            bool     `mapstructure:"base-image"`
+	DependenciesOnly     bool     `mapstructure:"dependencies-only"`
+	ContainerRegistry    string   `mapstructure:"container-registry"`
+	Image                string   `mapstructure:"image"`
+	IntegrationDirectory string   `mapstructure:"integration-directory"`
+	Properties           []string `mapstructure:"properties"`
+	PropertyFiles        []string `mapstructure:"property-files"`
+	MavenRepositories    []string `mapstructure:"maven-repositories"`
 }
 
-func (command *localBuildCmdOptions) validate(cmd *cobra.Command, args []string) error {
+func (command *localBuildCmdOptions) validate(args []string) error {
 	// Validate integration files.
 	if len(args) > 0 {
-		err := validateIntegrationFiles(args)
-		if err != nil {
+		if err := validateIntegrationFiles(args); err != nil {
 			return err
 		}
 	}
 
 	// Validate additional dependencies specified by the user.
-	err := validateAdditionalDependencies(command.AdditionalDependencies)
-	if err != nil {
+	if err := validateDependencies(command.Dependencies); err != nil {
 		return err
 	}
 
 	// Validate properties file.
-	err = validateFiles(command.PropertyFiles)
-	if err != nil {
+	if err := validateFiles(command.PropertyFiles); err != nil {
 		return err
 	}
 
@@ -136,8 +124,6 @@ func (command *localBuildCmdOptions) validate(cmd *cobra.Command, args []string)
 		return errors.New("to output dependencies the integration directory flag must be set")
 	}
 
-	warnTraitUsages(cmd, command.Traits)
-
 	return nil
 }
 
@@ -176,7 +162,7 @@ func (command *localBuildCmdOptions) run(cmd *cobra.Command, args []string) erro
 	var dependenciesList, propertyFilesList []string
 	routeFiles := args
 	if !command.BaseImage {
-		dependencies, err := getDependencies(command.Context, args, command.AdditionalDependencies, command.MavenRepositories, true)
+		dependencies, err := GetDependencies(command.Context, args, command.Dependencies, command.MavenRepositories, true)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/cmd/local_inspect.go b/pkg/cmd/local_inspect.go
index e4e6c95cf..54fca9862 100644
--- a/pkg/cmd/local_inspect.go
+++ b/pkg/cmd/local_inspect.go
@@ -23,9 +23,9 @@ import (
 	"github.com/spf13/cobra"
 )
 
-func newCmdLocalInspect(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localInspectCmdOptions) {
+func newCmdLocalInspect(localCmdOptions *LocalCmdOptions) (*cobra.Command, *localInspectCmdOptions) {
 	options := localInspectCmdOptions{
-		RootCmdOptions: rootCmdOptions,
+		LocalCmdOptions: localCmdOptions,
 	}
 
 	cmd := cobra.Command{
@@ -36,7 +36,7 @@ top level dependencies only. When --all-dependencies is enabled, the transitive
 will be generated by calling Maven and then printed in the selected output format.`,
 		PreRunE: decode(&options),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := options.validate(cmd, args); err != nil {
+			if err := options.validate(args); err != nil {
 				return err
 			}
 			if err := options.init(); err != nil {
@@ -57,41 +57,28 @@ will be generated by calling Maven and then printed in the selected output forma
 	}
 
 	cmd.Flags().Bool("all-dependencies", false, "Enable computation of transitive dependencies.")
-	cmd.Flags().StringArrayP("dependency", "d", nil, additionalDependencyUsageMessage)
 	cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
-	// hidden flags for compatibility with kamel run
-	cmd.Flags().StringArrayP("trait", "t", nil, "")
-	if err := cmd.Flags().MarkHidden("trait"); err != nil {
-		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
-	}
-
 	return &cmd, &options
 }
 
 type localInspectCmdOptions struct {
-	*RootCmdOptions
-	AllDependencies        bool     `mapstructure:"all-dependencies"`
-	OutputFormat           string   `mapstructure:"output"`
-	AdditionalDependencies []string `mapstructure:"dependencies"`
-	MavenRepositories      []string `mapstructure:"maven-repositories"`
-	Traits                 []string `mapstructure:"traits"`
+	*LocalCmdOptions
+	AllDependencies   bool     `mapstructure:"all-dependencies"`
+	OutputFormat      string   `mapstructure:"output"`
+	MavenRepositories []string `mapstructure:"maven-repositories"`
 }
 
-func (command *localInspectCmdOptions) validate(cmd *cobra.Command, args []string) error {
-	err := validateIntegrationFiles(args)
-	if err != nil {
+func (command *localInspectCmdOptions) validate(args []string) error {
+	if err := validateIntegrationFiles(args); err != nil {
 		return err
 	}
 
-	err = validateAdditionalDependencies(command.AdditionalDependencies)
-	if err != nil {
+	if err := validateDependencies(command.Dependencies); err != nil {
 		return err
 	}
 
-	warnTraitUsages(cmd, command.Traits)
-
 	return nil
 }
 
@@ -100,7 +87,7 @@ func (command *localInspectCmdOptions) init() error {
 }
 
 func (command *localInspectCmdOptions) run(cmd *cobra.Command, args []string) error {
-	dependencies, err := getDependencies(command.Context, args, command.AdditionalDependencies, command.MavenRepositories, command.AllDependencies)
+	dependencies, err := GetDependencies(command.Context, args, command.Dependencies, command.MavenRepositories, command.AllDependencies)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index 1e347608c..ec021ed0d 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -29,9 +29,9 @@ import (
 	"github.com/apache/camel-k/pkg/util"
 )
 
-func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCmdOptions) {
+func newCmdLocalRun(localCmdOptions *LocalCmdOptions) (*cobra.Command, *localRunCmdOptions) {
 	options := localRunCmdOptions{
-		RootCmdOptions: rootCmdOptions,
+		LocalCmdOptions: localCmdOptions,
 	}
 
 	cmd := cobra.Command{
@@ -40,7 +40,7 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 		Long:    `Run integration locally using the input integration files.`,
 		PreRunE: decode(&options),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := options.validate(cmd, args); err != nil {
+			if err := options.validate(args); err != nil {
 				return err
 			}
 			if err := options.init(); err != nil {
@@ -80,51 +80,39 @@ func newCmdLocalRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localRunCm
 	cmd.Flags().StringArrayP("env", "e", nil, "Flag to specify an environment variable [--env VARIABLE=value].")
 	cmd.Flags().StringArray("property-file", nil, "Add a property file to the integration.")
 	cmd.Flags().StringArrayP("property", "p", nil, "Add a Camel property to the integration.")
-	cmd.Flags().StringArrayP("dependency", "d", nil, additionalDependencyUsageMessage)
 	cmd.Flags().StringArray("maven-repository", nil, "Use a maven repository")
 
-	// hidden flags for compatibility with kamel run
-	cmd.Flags().StringArrayP("trait", "t", nil, "")
-	if err := cmd.Flags().MarkHidden("trait"); err != nil {
-		fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
-	}
-
 	return &cmd, &options
 }
 
 type localRunCmdOptions struct {
-	*RootCmdOptions
-	Containerize           bool     `mapstructure:"containerize"`
-	Image                  string   `mapstructure:"image"`
-	Network                string   `mapstructure:"network"`
-	IntegrationDirectory   string   `mapstructure:"integration-directory"`
-	EnvironmentVariables   []string `mapstructure:"envs"`
-	PropertyFiles          []string `mapstructure:"property-files"`
-	Properties             []string `mapstructure:"properties"`
-	AdditionalDependencies []string `mapstructure:"dependencies"`
-	MavenRepositories      []string `mapstructure:"maven-repositories"`
-	Traits                 []string `mapstructure:"traits"`
+	*LocalCmdOptions
+	Containerize         bool     `mapstructure:"containerize"`
+	Image                string   `mapstructure:"image"`
+	Network              string   `mapstructure:"network"`
+	IntegrationDirectory string   `mapstructure:"integration-directory"`
+	EnvironmentVariables []string `mapstructure:"envs"`
+	PropertyFiles        []string `mapstructure:"property-files"`
+	Properties           []string `mapstructure:"properties"`
+	MavenRepositories    []string `mapstructure:"maven-repositories"`
 }
 
-func (command *localRunCmdOptions) validate(cmd *cobra.Command, args []string) error {
+func (command *localRunCmdOptions) validate(args []string) error {
 	// Validate integration files when no image is provided and we are
 	// not running an already locally-built integration.
 	if command.Image == "" && command.IntegrationDirectory == "" {
-		err := validateIntegrationFiles(args)
-		if err != nil {
+		if err := validateIntegrationFiles(args); err != nil {
 			return err
 		}
 	}
 
 	// Validate additional dependencies specified by the user.
-	err := validateAdditionalDependencies(command.AdditionalDependencies)
-	if err != nil {
+	if err := validateDependencies(command.Dependencies); err != nil {
 		return err
 	}
 
 	// Validate properties file.
-	err = validatePropertyFiles(command.PropertyFiles)
-	if err != nil {
+	if err := validatePropertyFiles(command.PropertyFiles); err != nil {
 		return err
 	}
 
@@ -133,20 +121,16 @@ func (command *localRunCmdOptions) validate(cmd *cobra.Command, args []string) e
 		return errors.New("containerization is active but no image name has been provided")
 	}
 
-	warnTraitUsages(cmd, command.Traits)
-
 	return nil
 }
 
 func (command *localRunCmdOptions) init() error {
 	if command.Containerize {
-		err := createDockerBaseWorkingDirectory()
-		if err != nil {
+		if err := createDockerBaseWorkingDirectory(); err != nil {
 			return err
 		}
 
-		err = createDockerWorkingDirectory()
-		if err != nil {
+		if err := createDockerWorkingDirectory(); err != nil {
 			return err
 		}
 	}
@@ -162,8 +146,7 @@ func (command *localRunCmdOptions) run(cmd *cobra.Command, args []string) error
 	// If local run is provided with an image name, it will just run the image locally and exit.
 	if command.Image != "" && !command.Containerize {
 		// Run image locally.
-		err := runIntegrationImage(command.Context, command.Image, cmd.OutOrStdout(), cmd.ErrOrStderr())
-		if err != nil {
+		if err := runIntegrationImage(command.Context, command.Image, cmd.OutOrStdout(), cmd.ErrOrStderr()); err != nil {
 			return err
 		}
 
@@ -209,7 +192,7 @@ func (command *localRunCmdOptions) run(cmd *cobra.Command, args []string) error
 			return err
 		}
 	} else {
-		computedDependencies, err := getDependencies(command.Context, args, command.AdditionalDependencies, command.MavenRepositories, true)
+		computedDependencies, err := GetDependencies(command.Context, args, command.Dependencies, command.MavenRepositories, true)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/cmd/util_dependencies.go b/pkg/cmd/local_util.go
similarity index 91%
rename from pkg/cmd/util_dependencies.go
rename to pkg/cmd/local_util.go
index e8f609d3f..c9b04feda 100644
--- a/pkg/cmd/util_dependencies.go
+++ b/pkg/cmd/local_util.go
@@ -38,13 +38,14 @@ import (
 	"github.com/apache/camel-k/pkg/util/maven"
 )
 
-var acceptedDependencyTypes = []string{"bom", "camel", "camel-k", "camel-quarkus", "mvn", "github"}
-
-var additionalDependencyUsageMessage = `Additional top-level dependencies are specified with the format:
-<type>:<dependency-name>
-where <type> is one of {` + strings.Join(acceptedDependencyTypes, "|") + `}.`
+var acceptedDependencyTypes = []string{
+	"bom", "camel", "camel-k", "camel-quarkus", "mvn",
+	// jitpack
+	"github", "gitlab", "bitbucket", "gitee", "azure",
+}
 
-func getDependencies(ctx context.Context, args []string, additionalDependencies []string, repositories []string, allDependencies bool) ([]string, error) {
+// GetDependencies resolves and gets the list of dependencies from catalog and sources.
+func GetDependencies(ctx context.Context, args []string, additionalDependencies []string, repositories []string, allDependencies bool) ([]string, error) {
 	// Fetch existing catalog or create new one if one does not already exist
 	catalog, err := createCamelCatalog(ctx)
 	if err != nil {
@@ -109,8 +110,7 @@ func getTransitiveDependencies(ctx context.Context, catalog *camel.RuntimeCatalo
 		catalog.CamelCatalogSpec.Runtime.Metadata["quarkus.version"],
 	)
 
-	err := camel.ManageIntegrationDependencies(&project, dependencies, catalog)
-	if err != nil {
+	if err := camel.ManageIntegrationDependencies(&project, dependencies, catalog); err != nil {
 		return nil, err
 	}
 
@@ -132,8 +132,7 @@ func getTransitiveDependencies(ctx context.Context, catalog *camel.RuntimeCatalo
 	// Make maven command less verbose
 	mc.AdditionalArguments = append(mc.AdditionalArguments, "-q")
 
-	err = builder.BuildQuarkusRunnerCommon(ctx, mc, project)
-	if err != nil {
+	if err := builder.BuildQuarkusRunnerCommon(ctx, mc, project); err != nil {
 		return nil, err
 	}
 
@@ -293,31 +292,19 @@ func validateFiles(args []string) error {
 	return nil
 }
 
-func validateAdditionalDependencies(additionalDependencies []string) error {
-	// Validate list of additional dependencies i.e. make sure that each dependency has a valid type
-	for _, additionalDependency := range additionalDependencies {
-		isValid := validateDependency(additionalDependency)
-		if !isValid {
-			return errors.New("Unexpected type for user-provided dependency: " + additionalDependency + ". " + additionalDependencyUsageMessage)
+// validateDependencies validates list of additional dependencies i.e. makes sure
+// that each dependency has a valid type.
+func validateDependencies(dependencies []string) error {
+	for _, dependency := range dependencies {
+		depType := strings.Split(dependency, ":")[0]
+		if !util.StringSliceExists(acceptedDependencyTypes, depType) {
+			return fmt.Errorf("dependency is not valid: %s", dependency)
 		}
 	}
 
 	return nil
 }
 
-func validateDependency(additionalDependency string) bool {
-	dependencyComponents := strings.Split(additionalDependency, ":")
-
-	TypeIsValid := false
-	for _, dependencyType := range acceptedDependencyTypes {
-		if dependencyType == dependencyComponents[0] {
-			TypeIsValid = true
-		}
-	}
-
-	return TypeIsValid
-}
-
 func validateIntegrationFiles(args []string) error {
 	// If no source files have been provided there is nothing to inspect.
 	if len(args) == 0 {
diff --git a/pkg/cmd/util_dependencies_test.go b/pkg/cmd/local_util_test.go
similarity index 100%
rename from pkg/cmd/util_dependencies_test.go
rename to pkg/cmd/local_util_test.go
diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go
index abdde0747..c32a187e1 100644
--- a/pkg/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -59,7 +59,6 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) {
 		ContextCancel: childCancel,
 	}
 
-	var err error
 	cmd := kamelPreAddCommandInit(&options)
 	addKamelSubcommands(cmd, &options)
 
@@ -67,7 +66,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) {
 		return cmd, err
 	}
 
-	err = kamelPostAddCommandInit(cmd)
+	err := kamelPostAddCommandInit(cmd)
 
 	return cmd, err
 }
@@ -148,7 +147,7 @@ func addKamelSubcommands(cmd *cobra.Command, options *RootCmdOptions) {
 	cmd.AddCommand(cmdOnly(newCmdInit(options)))
 	cmd.AddCommand(cmdOnly(newCmdDebug(options)))
 	cmd.AddCommand(cmdOnly(newCmdDump(options)))
-	cmd.AddCommand(newCmdLocal(options))
+	cmd.AddCommand(cmdOnly(newCmdLocal(options)))
 	cmd.AddCommand(cmdOnly(newCmdBind(options)))
 	cmd.AddCommand(cmdOnly(newCmdPromote(options)))
 	cmd.AddCommand(newCmdKamelet(options))
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 27df5e167..9a02f5064 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -75,6 +75,8 @@ import (
 	"github.com/apache/camel-k/pkg/util/watch"
 )
 
+const usageDependency = `A dependency that should be included, e.g., "-d camel-mail" for a Camel component, "-d mvn:org.my:app:1.0" for a Maven dependency or "file://localPath[?targetPath=<path>&registry=<registry_URL>&skipChecksums=<true>&skipPOM=<true>]" for local files (experimental)`
+
 func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) {
 	options := runCmdOptions{
 		RootCmdOptions: rootCmdOptions,
@@ -94,7 +96,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions)
 
 	cmd.Flags().String("name", "", "The integration name")
 	cmd.Flags().StringArrayP("connect", "c", nil, "A Service that the integration should bind to, specified as [[apigroup/]version:]kind:[namespace/]name")
-	cmd.Flags().StringArrayP("dependency", "d", nil, "A dependency that should be included, e.g., \"-d camel-mail\" for a Camel component, \"-d mvn:org.my:app:1.0\" for a Maven dependency or \"file://localPath[?targetPath=<path>&registry=<registry URL>&skipChecksums=<true>&skipPOM=<true>]\" for local files (experimental)")
+	cmd.Flags().StringArrayP("dependency", "d", nil, usageDependency)
 	cmd.Flags().BoolP("wait", "w", false, "Wait for the integration to be running")
 	cmd.Flags().StringP("kit", "k", "", "The kit used to run the integration")
 	cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file (syntax: [my-key=my-value|file:/path/to/my-conf.properties])")
diff --git a/pkg/kamelet/repository/go.mod b/pkg/kamelet/repository/go.mod
index 85f58e484..1c7f75d57 100644
--- a/pkg/kamelet/repository/go.mod
+++ b/pkg/kamelet/repository/go.mod
@@ -1,6 +1,6 @@
 module github.com/apache/camel-k/pkg/kamelet/repository
 
-go 1.16
+go 1.17
 
 require (
 	github.com/apache/camel-k/pkg/apis/camel v0.0.0
@@ -12,6 +12,41 @@ require (
 	k8s.io/apimachinery v0.22.5
 )
 
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/evanphx/json-patch v4.11.0+incompatible // indirect
+	github.com/go-logr/logr v0.4.0 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/go-cmp v0.5.5 // indirect
+	github.com/google/go-querystring v1.0.0 // indirect
+	github.com/google/gofuzz v1.1.0 // indirect
+	github.com/googleapis/gnostic v0.5.5 // indirect
+	github.com/json-iterator/go v1.1.11 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect
+	golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect
+	golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
+	golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
+	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+	google.golang.org/appengine v1.6.5 // indirect
+	google.golang.org/protobuf v1.26.0 // indirect
+	gopkg.in/inf.v0 v0.9.1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	k8s.io/api v0.22.5 // indirect
+	k8s.io/client-go v0.22.5 // indirect
+	k8s.io/klog/v2 v2.9.0 // indirect
+	k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect
+	k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
+	sigs.k8s.io/yaml v1.2.0 // indirect
+)
+
 // Local modules
 replace github.com/apache/camel-k/pkg/apis/camel => ../../apis/camel
 
diff --git a/pkg/kamelet/repository/go.sum b/pkg/kamelet/repository/go.sum
index b126acc33..f81275cbe 100644
--- a/pkg/kamelet/repository/go.sum
+++ b/pkg/kamelet/repository/go.sum
@@ -46,7 +46,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
@@ -60,15 +59,11 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
 github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
-github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -134,7 +129,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -150,7 +144,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -190,12 +183,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -238,7 +229,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -261,7 +251,6 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -277,7 +266,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -305,9 +293,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -356,10 +342,8 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -454,12 +438,8 @@ k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s=
 k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
 k8s.io/client-go v0.22.5 h1:I8Zn/UqIdi2r02aZmhaJ1hqMxcpfJ3t5VqvHtctHYFo=
 k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
-k8s.io/code-generator v0.22.5 h1:jn+mYXI5q7rzo7Bz/n8xZIgbe61SeXlIjU5jA8jLVps=
-k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk=
 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
-k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
 k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80=
diff --git a/pkg/util/camel/camel_dependencies.go b/pkg/util/camel/camel_dependencies.go
index ae43f9c7f..e6055f596 100644
--- a/pkg/util/camel/camel_dependencies.go
+++ b/pkg/util/camel/camel_dependencies.go
@@ -30,14 +30,9 @@ import (
 )
 
 // ManageIntegrationDependencies --.
-func ManageIntegrationDependencies(
-	project *maven.Project,
-	dependencies []string,
-	catalog *RuntimeCatalog) error {
-
+func ManageIntegrationDependencies(project *maven.Project, dependencies []string, catalog *RuntimeCatalog) error {
 	// Add dependencies from build
-	err := addDependencies(project, dependencies, catalog)
-	if err != nil {
+	if err := addDependencies(project, dependencies, catalog); err != nil {
 		return err
 	}
 	// Add dependencies from catalog
diff --git a/script/Makefile b/script/Makefile
index 2ffbee1e2..e5ed259df 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -23,6 +23,7 @@ BUILDAH_VERSION := 1.23.3
 KANIKO_VERSION := 0.17.1
 INSTALL_DEFAULT_KAMELETS := true
 CONTROLLER_GEN_VERSION := v0.6.1
+CODEGEN_VERSION := v0.22.5
 OPERATOR_SDK_VERSION := v1.14.0
 KUSTOMIZE_VERSION := v4.1.2
 OPM_VERSION := v1.21.0
@@ -171,27 +172,27 @@ codegen:
 
 	gofmt -w pkg/util/defaults/defaults.go
 
-generate: generate-deepcopy generate-crd generate-client generate-doc generate-keda generate-strimzi
-
-generate-client:
+generate: codegen-tools-install
+	# We better force the developer to generate all the resources everytime as
+	# it happens we tend to forget some code generation in the past
 	./script/gen_client.sh
-
-generate-crd: controller-gen
-	CONTROLLER_GEN=$(CONTROLLER_GEN) ./script/gen_crd.sh
-
-generate-doc:
+	./script/gen_crd.sh
 	./script/gen_doc.sh
-
-generate-deepcopy: controller-gen
-	cd pkg/apis/camel && $(CONTROLLER_GEN) paths="./..." object
-
-generate-keda:
-	cd addons/keda/duck && $(CONTROLLER_GEN) paths="./..." object
-
-generate-strimzi:
-	cd addons/strimzi/duck && $(CONTROLLER_GEN) paths="./..." object
+	cd pkg/apis/camel && $(shell go env GOPATH)/bin/controller-gen paths="./..." object
+	cd addons/keda/duck && $(shell go env GOPATH)/bin/controller-gen paths="./..." object
+	cd addons/strimzi/duck && $(shell go env GOPATH)/bin/controller-gen paths="./..." object
 	./script/gen_client_strimzi.sh
 
+codegen-tools-install:
+	# We must force the installation to make sure we are using the correct version
+	# Note: as there is no --version in the tools, we cannot rely on cached local versions
+	echo "Installing k8s.io/code-generator tools with version $(CODEGEN_VERSION)"
+	go install k8s.io/code-generator/cmd/client-gen@$(CODEGEN_VERSION)
+	go install k8s.io/code-generator/cmd/lister-gen@$(CODEGEN_VERSION)
+	go install k8s.io/code-generator/cmd/informer-gen@$(CODEGEN_VERSION)
+	echo "sigs.k8s.io/controller-tools/cmd/controller-gen with version $(CONTROLLER_GEN_VERSION)"
+	go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION)
+
 build: test build-resources build-kamel build-compile-integration-tests build-submodules
 
 ci-build: clean codegen set-module-version set-version check-licenses dir-licenses build-kamel cross-compile
@@ -466,23 +467,6 @@ get-staging-repo:
 
 .PHONY: do-build build build-kamel build-resources dep codegen images images-dev images-push images-push-staging test check test-integration clean release cross-compile package-examples set-version git-tag release-notes check-licenses generate-deepcopy generate-client generate-doc build-resources release-helm release-staging release-nightly get-staging-repo get-version build-submodules set-module-version bundle-kamelets generate-keda generate-strimzi
 .PHONY: controller-gen kubectl kustomize operator-sdk
-
-# find or download controller-gen if necessary
-controller-gen:
-ifeq (, $(shell command -v controller-gen 2> /dev/null))
-	@{ \
-	set -e ;\
-	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@$(CONTROLLER_GEN_VERSION) ;\
-	rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
-	}
-CONTROLLER_GEN=$(GOBIN)/controller-gen
-else
-CONTROLLER_GEN=$(shell command -v controller-gen 2> /dev/null)
-endif
-
 .PHONY: kubectl kustomize operator-sdk opm
 
 kubectl:
diff --git a/script/check_crd_api_support.sh b/script/check_crd_api_support.sh
new file mode 100755
index 000000000..b45ad83fa
--- /dev/null
+++ b/script/check_crd_api_support.sh
@@ -0,0 +1,62 @@
+#!/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.
+
+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
+
+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
+
+crd_version=$("${client}" explain customresourcedefinitions | grep VERSION | awk '{print $2}')
+api="apiextensions.k8s.io"
+
+if [ "${crd_version}" == "${api}/v1beta1" ]; then
+	echo "ERROR: CRD API version is too old to install camel-k in this way. Try using the client CLI app, which is able to convert the APIs."
+elif [ "${crd_version}" != "${api}/v1" ]; then
+	echo "ERROR: CRD API version '${crd_version}' is not supported."
+else
+	echo "OK"
+fi
diff --git a/script/gen_client.sh b/script/gen_client.sh
index bb28d9f8b..25437af84 100755
--- a/script/gen_client.sh
+++ b/script/gen_client.sh
@@ -25,7 +25,7 @@ cd $location/../pkg/client/camel
 
 echo "Generating Go client code..."
 
-go run k8s.io/code-generator/cmd/client-gen \
+$(go env GOPATH)/bin/client-gen \
 	--input=camel/v1,camel/v1alpha1 \
 	--go-header-file=../../../script/headers/default.txt \
 	--clientset-name "versioned"  \
@@ -33,14 +33,13 @@ go run k8s.io/code-generator/cmd/client-gen \
 	--output-base=. \
 	--output-package=github.com/apache/camel-k/pkg/client/camel/clientset
 
-
-go run k8s.io/code-generator/cmd/lister-gen \
+$(go env GOPATH)/bin/lister-gen \
 	--input-dirs=github.com/apache/camel-k/pkg/apis/camel/v1,github.com/apache/camel-k/pkg/apis/camel/v1alpha1 \
 	--go-header-file=../../../script/headers/default.txt \
 	--output-base=. \
 	--output-package=github.com/apache/camel-k/pkg/client/camel/listers
 
-go run k8s.io/code-generator/cmd/informer-gen \
+$(go env GOPATH)/bin/informer-gen \
     --versioned-clientset-package=github.com/apache/camel-k/pkg/client/camel/clientset/versioned \
 	--listers-package=github.com/apache/camel-k/pkg/client/camel/listers \
 	--input-dirs=github.com/apache/camel-k/pkg/apis/camel/v1,github.com/apache/camel-k/pkg/apis/camel/v1alpha1 \
diff --git a/script/gen_client_strimzi.sh b/script/gen_client_strimzi.sh
index 366969e91..6f5f45303 100755
--- a/script/gen_client_strimzi.sh
+++ b/script/gen_client_strimzi.sh
@@ -27,7 +27,7 @@ echo "Generating Go client code for Strimzi addon..."
 
 cd $rootdir
 
-go run k8s.io/code-generator/cmd/client-gen \
+$(go env GOPATH)/bin/client-gen \
   -h script/headers/default.txt \
   --input duck/v1beta2 \
   --input-base=github.com/apache/camel-k/addons/strimzi \
diff --git a/script/gen_crd.sh b/script/gen_crd.sh
index 9e41ba03f..b0dc55f61 100755
--- a/script/gen_crd.sh
+++ b/script/gen_crd.sh
@@ -21,7 +21,7 @@ location=$(dirname "$0")
 apidir=$location/../pkg/apis/camel
 
 cd "$apidir"
-$CONTROLLER_GEN crd \
+$(go env GOPATH)/bin/controller-gen crd \
   paths=./... \
   output:crd:artifacts:config=../../../config/crd/bases \
   output:crd:dir=../../../config/crd/bases \


Test patch:
diff --git a/e2e/local/files/dependency.groovy b/e2e/local/files/dependency.groovy
index d686acb8a..b5d56df17 100644
--- a/e2e/local/files/dependency.groovy
+++ b/e2e/local/files/dependency.groovy
@@ -1,4 +1,4 @@
-// camel-k: language=groovy dependency=camel:twitter dependency=mvn:com.google.guava:guava:31.1-jre dependency=github:squakez/samplejp:v1.0
+// camel-k: language=groovy dependency=camel-twitter dependency=mvn:com.google.guava:guava:31.1-jre dependency=github:squakez/samplejp:v1.0
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/e2e/local/local_build_test.go b/e2e/local/local_build_test.go
index ab3440b4b..2ea34f91b 100644
--- a/e2e/local/local_build_test.go
+++ b/e2e/local/local_build_test.go
@@ -195,7 +195,7 @@ func TestLocalBuildDependenciesOnly(t *testing.T) {
 	file := testutil.MakeTempCopy(t, "files/yaml.yaml")
 	dir := testutil.MakeTempDir(t)
 
-	kamelBuild := KamelWithContext(ctx, "local", "build", file, "--integration-directory", dir, "--dependencies-only")
+	kamelBuild := KamelWithContext(ctx, "local", "build", file, "--integration-directory", dir, "--dependencies-only", "-d", "camel-amqp")
 
 	go func() {
 		err := kamelBuild.Execute()
@@ -206,6 +206,7 @@ func TestLocalBuildDependenciesOnly(t *testing.T) {
 	Eventually(dir+"/dependencies", TestTimeoutShort).Should(BeADirectory())
 	Eventually(dependency(dir, "org.apache.camel.camel-timer-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
 	Eventually(dependency(dir, "org.apache.camel.camel-log-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
+	Eventually(dependency(dir, "org.apache.camel.camel-amqp-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
 	Expect(dir + "/properties").ShouldNot(BeADirectory())
 	Expect(dir + "/routes/yaml.yaml").ShouldNot(BeAnExistingFile())
 }
@@ -219,7 +220,7 @@ func TestLocalBuildModelineDependencies(t *testing.T) {
 	file := testutil.MakeTempCopy(t, "files/dependency.groovy")
 	dir := testutil.MakeTempDir(t)
 
-	kamelBuild := KamelWithContext(ctx, "local", "build", file, "--integration-directory", dir)
+	kamelBuild := KamelWithContext(ctx, "local", "build", file, "--integration-directory", dir, "-d", "camel-amqp")
 
 	go func() {
 		err := kamelBuild.Execute()
@@ -229,6 +230,7 @@ func TestLocalBuildModelineDependencies(t *testing.T) {
 	Eventually(dir+"/dependencies", TestTimeoutShort).Should(BeADirectory())
 	Eventually(dependency(dir, "org.apache.camel.camel-timer-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
 	Eventually(dependency(dir, "org.apache.camel.camel-log-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
+	Eventually(dependency(dir, "org.apache.camel.camel-amqp-%s.jar", camelVersion), TestTimeoutShort).Should(BeAnExistingFile())
 	// camel dependency
 	Eventually(dependency(dir, "org.apache.camel.camel-twitter-%s.jar", camelVersion), TestTimeoutMedium).Should(BeAnExistingFile())
 	// mvn dependency
diff --git a/e2e/local/local_run_test.go b/e2e/local/local_run_test.go
index e016b0119..c703e3825 100644
--- a/e2e/local/local_run_test.go
+++ b/e2e/local/local_run_test.go
@@ -60,6 +60,31 @@ func TestLocalRun(t *testing.T) {
 	Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue())
 }
 
+func TestLocalRunWithDependencies(t *testing.T) {
+	RegisterTestingT(t)
+
+	ctx, cancel := context.WithCancel(TestContext)
+	defer cancel()
+	piper, pipew := io.Pipe()
+	defer pipew.Close()
+	defer piper.Close()
+
+	file := testutil.MakeTempCopy(t, "files/dependency.groovy")
+
+	kamelRun := KamelWithContext(ctx, "local", "run", file, "-d", "camel-amqp")
+	kamelRun.SetOut(pipew)
+
+	logScanner := testutil.NewLogScanner(ctx, piper, "Magicstring!")
+
+	go func() {
+		err := kamelRun.Execute()
+		assert.NoError(t, err)
+		cancel()
+	}()
+
+	Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue())
+}
+
 func TestLocalRunContainerize(t *testing.T) {
 	RegisterTestingT(t)
 
diff --git a/e2e/namespace/install/kustomize/common.go b/e2e/namespace/install/kustomize/common.go
index 11c2ee24e..15c12b655 100644
--- a/e2e/namespace/install/kustomize/common.go
+++ b/e2e/namespace/install/kustomize/common.go
@@ -73,8 +73,28 @@ func ExecMake(t *testing.T, command *exec.Cmd) {
 	session.Wait()
 	Eventually(session).Should(gexec.Exit(0))
 	assert.Nil(t, err)
-	assert.NotContains(t, cmdErr.String(), "Error")
-	assert.NotContains(t, cmdErr.String(), "ERROR")
+	assert.NotContains(t, strings.ToUpper(cmdErr.String()), "ERROR")
+}
+
+//
+// Expect a make error with an exit code of 1
+//
+func ExecMakeError(t *testing.T, command *exec.Cmd) {
+	var cmdOut strings.Builder
+	var cmdErr strings.Builder
+
+	defer func() {
+		if t.Failed() {
+			t.Logf("Output from make command:\n%s\n", cmdOut.String())
+			t.Logf("Error from make command:\n%s\n", cmdErr.String())
+		}
+	}()
+
+	session, err := gexec.Start(command, &cmdOut, &cmdErr)
+	session.Wait()
+	Eventually(session).ShouldNot(gexec.Exit(0))
+	assert.Nil(t, err)
+	assert.Contains(t, strings.ToUpper(cmdErr.String()), "ERROR")
 }
 
 // Clean up the cluster ready for the next set of tests
diff --git a/e2e/namespace/install/kustomize/operator_test.go b/e2e/namespace/install/kustomize/operator_test.go
index a6a9f8738..d9cf17c2b 100644
--- a/e2e/namespace/install/kustomize/operator_test.go
+++ b/e2e/namespace/install/kustomize/operator_test.go
@@ -31,7 +31,21 @@ import (
 	. "github.com/onsi/gomega"
 )
 
+func TestOcp3CrdError(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") != "true" {
+		t.Skip("INFO: Skipping test as only applicable to OCP3")
+	}
+
+	WithNewTestNamespace(t, func(ns string) {
+		ExecMakeError(t, Make("setup-cluster", fmt.Sprintf("NAMESPACE=%s", ns)))
+	})
+}
+
 func TestBasicOperator(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") == "true" {
+		t.Skip("INFO: Skipping test as not supported on OCP3")
+	}
+
 	os.Setenv("MAKE_DIR", "../../../../install")
 
 	// Ensure no CRDs are already installed
@@ -50,6 +64,10 @@ func TestBasicOperator(t *testing.T) {
 }
 
 func TestAlternativeImageOperator(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") == "true" {
+		t.Skip("INFO: Skipping test as not supported on OCP3")
+	}
+
 	os.Setenv("MAKE_DIR", "../../../../install")
 
 	// Ensure no CRDs are already installed
@@ -72,6 +90,10 @@ func TestAlternativeImageOperator(t *testing.T) {
 }
 
 func TestGlobalOperator(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") == "true" {
+		t.Skip("INFO: Skipping test as not supported on OCP3")
+	}
+
 	os.Setenv("MAKE_DIR", "../../../../install")
 
 	// Ensure no CRDs are already installed
diff --git a/e2e/namespace/install/kustomize/setup_test.go b/e2e/namespace/install/kustomize/setup_test.go
index 2ace67ab3..93923fcfb 100644
--- a/e2e/namespace/install/kustomize/setup_test.go
+++ b/e2e/namespace/install/kustomize/setup_test.go
@@ -32,6 +32,10 @@ import (
 )
 
 func TestBasicSetup(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") == "true" {
+		t.Skip("INFO: Skipping test as not supported on OCP3")
+	}
+
 	os.Setenv("MAKE_DIR", "../../../../install")
 
 	// Ensure no CRDs are already installed
@@ -61,6 +65,10 @@ func TestBasicSetup(t *testing.T) {
 }
 
 func TestGlobalSetup(t *testing.T) {
+	if os.Getenv("CAMEL_K_CLUSTER_OCP3") == "true" {
+		t.Skip("INFO: Skipping test as not supported on OCP3")
+	}
+
 	os.Setenv("MAKE_DIR", "../../../../install")
 
 	// Ensure no CRDs are already installed
diff --git a/pkg/apis/camel/v1/integration_types_support_test.go b/pkg/apis/camel/v1/integration_types_support_test.go
index 6f4d4827c..7a5e81d86 100644
--- a/pkg/apis/camel/v1/integration_types_support_test.go
+++ b/pkg/apis/camel/v1/integration_types_support_test.go
@@ -74,6 +74,13 @@ func TestAddDependency(t *testing.T) {
 	assert.Equal(t, integration.Dependencies, []string{"file:dep"})
 }
 
+func TestNormalizeDependency(t *testing.T) {
+	assert.Equal(t, "camel:file", NormalizeDependency("camel-file"))
+	assert.Equal(t, "camel:file", NormalizeDependency("camel:file"))
+	assert.Equal(t, "camel:file", NormalizeDependency("camel-quarkus-file"))
+	assert.Equal(t, "camel:file", NormalizeDependency("camel-quarkus:file"))
+}
+
 func TestGetConfigurationProperty(t *testing.T) {
 	integration := IntegrationSpec{}
 	integration.AddConfiguration("property", "key1=value1")
diff --git a/pkg/cmd/local_build_test.go b/pkg/cmd/local_build_test.go
index 8519bd1a4..5c9db5ff2 100644
--- a/pkg/cmd/local_build_test.go
+++ b/pkg/cmd/local_build_test.go
@@ -22,28 +22,52 @@ import (
 
 	"github.com/apache/camel-k/pkg/util/test"
 	"github.com/spf13/cobra"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func addTestLocalBuildCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localBuildCmdOptions {
+	localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+	// remove predefined sub commands
+	localCmd.RemoveCommand(localCmd.Commands()...)
 	// add a testing version of build Command
-	localBuildCmd, localBuildCmdOptions := newCmdLocalBuild(rootCmdOptions)
+	localBuildCmd, localBuildCmdOptions := newCmdLocalBuild(localCmdOptions)
 	localBuildCmd.RunE = func(c *cobra.Command, args []string) error {
 		return nil
 	}
 	localBuildCmd.Args = test.ArbitraryArgs
-	rootCmd.AddCommand(localBuildCmd)
+	localCmd.AddCommand(localBuildCmd)
+	rootCmd.AddCommand(localCmd)
 	return localBuildCmdOptions
 }
 
 func TestLocalBuildAcceptsTraits(t *testing.T) {
 	options, rootCmd := kamelTestPreAddCommandInit()
-
 	addTestLocalBuildCmd(options, rootCmd)
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "local", "build", "route.java",
+		"-t", "jolokia.enabled=true",
+		"--trait", "prometheus.enabled=true")
+
+	require.NoError(t, err)
+}
 
+func TestLocalBuildWithDependencies(t *testing.T) {
+	options, rootCmd := kamelTestPreAddCommandInit()
+	localBuildCmdOptions := addTestLocalBuildCmd(options, rootCmd)
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "build", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "build", "route.java",
+		"-d", "camel-amqp",
+		"-d", "camel:bean",
+		"-d", "camel-quarkus-controlbus",
+		"-d", "camel-quarkus:directvm",
+		"--dependency", "mvn:test:component:1.0.0")
+
+	require.NoError(t, err)
+	assert.Len(t, localBuildCmdOptions.Dependencies, 5)
+	assert.ElementsMatch(t, localBuildCmdOptions.Dependencies, []string{
+		"camel:amqp", "camel:bean", "camel:controlbus", "camel:directvm", "mvn:test:component:1.0.0",
+	})
 }
diff --git a/pkg/cmd/local_inspect_test.go b/pkg/cmd/local_inspect_test.go
index 993ea88b9..92fad62be 100644
--- a/pkg/cmd/local_inspect_test.go
+++ b/pkg/cmd/local_inspect_test.go
@@ -22,28 +22,52 @@ import (
 
 	"github.com/apache/camel-k/pkg/util/test"
 	"github.com/spf13/cobra"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func addTestLocalInspectCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localInspectCmdOptions {
+	localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+	// remove predefined sub commands
+	localCmd.RemoveCommand(localCmd.Commands()...)
 	// add a testing version of inspect Command
-	localInspectCmd, localInspectCmdOptions := newCmdLocalInspect(rootCmdOptions)
+	localInspectCmd, localInspectCmdOptions := newCmdLocalInspect(localCmdOptions)
 	localInspectCmd.RunE = func(c *cobra.Command, args []string) error {
 		return nil
 	}
 	localInspectCmd.Args = test.ArbitraryArgs
-	rootCmd.AddCommand(localInspectCmd)
+	localCmd.AddCommand(localInspectCmd)
+	rootCmd.AddCommand(localCmd)
 	return localInspectCmdOptions
 }
 
 func TestLocalInspectAcceptsTraits(t *testing.T) {
-	options, rootCmd := kamelTestPreAddCommandInit()
+	rootOptions, rootCmd := kamelTestPreAddCommandInit()
+	addTestLocalInspectCmd(rootOptions, rootCmd)
+	kamelTestPostAddCommandInit(t, rootCmd)
+
+	_, err := test.ExecuteCommand(rootCmd, "local", "inspect", "route.java",
+		"-t", "jolokia.enabled=true",
+		"--trait", "prometheus.enabled=true")
 
-	addTestLocalInspectCmd(options, rootCmd)
+	require.NoError(t, err)
+}
 
+func TestLocalInspectWithDependencies(t *testing.T) {
+	rootOptions, rootCmd := kamelTestPreAddCommandInit()
+	options := addTestLocalInspectCmd(rootOptions, rootCmd)
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "inspect", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "inspect", "route.java",
+		"-d", "camel-amqp",
+		"-d", "camel:bean",
+		"-d", "camel-quarkus-controlbus",
+		"-d", "camel-quarkus:directvm",
+		"--dependency", "mvn:test:component:1.0.0")
+
+	require.NoError(t, err)
+	assert.Len(t, options.Dependencies, 5)
+	assert.ElementsMatch(t, options.Dependencies, []string{
+		"camel:amqp", "camel:bean", "camel:controlbus", "camel:directvm", "mvn:test:component:1.0.0",
+	})
 }
diff --git a/pkg/cmd/local_run_test.go b/pkg/cmd/local_run_test.go
index 1e4c08093..d6bdab05e 100644
--- a/pkg/cmd/local_run_test.go
+++ b/pkg/cmd/local_run_test.go
@@ -22,31 +22,35 @@ import (
 
 	"github.com/apache/camel-k/pkg/util/test"
 	"github.com/spf13/cobra"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func addTestLocalRunCmd(rootCmdOptions *RootCmdOptions, rootCmd *cobra.Command) *localRunCmdOptions {
+	localCmd, localCmdOptions := newCmdLocal(rootCmdOptions)
+	// remove predefined sub commands
+	localCmd.RemoveCommand(localCmd.Commands()...)
 	// add a testing version of run Command
-	localRunCmd, localRunCmdOptions := newCmdLocalRun(rootCmdOptions)
+	localRunCmd, localRunCmdOptions := newCmdLocalRun(localCmdOptions)
 	localRunCmd.RunE = func(c *cobra.Command, args []string) error {
 		return nil
 	}
 	localRunCmd.Args = test.ArbitraryArgs
-	rootCmd.AddCommand(localRunCmd)
+	localCmd.AddCommand(localRunCmd)
+	rootCmd.AddCommand(localCmd)
 	return localRunCmdOptions
 }
 
 func TestLocalRunPropertyFileFlag(t *testing.T) {
 	options, rootCmd := kamelTestPreAddCommandInit()
-
 	localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "run", "route.java", "--property-file", "file1.properties", "--property-file", "file2.properties")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+		"--property-file", "file1.properties",
+		"--property-file", "file2.properties")
 
+	require.NoError(t, err)
 	if len(localRunCmdOptions.PropertyFiles) != 2 {
 		t.Fatalf("Property files expected to contain: \n %v elements\nGot:\n %v elements\n", 2, len(localRunCmdOptions.PropertyFiles))
 	}
@@ -57,16 +61,14 @@ func TestLocalRunPropertyFileFlag(t *testing.T) {
 
 func TestLocalRunPropertiesFlag(t *testing.T) {
 	options, rootCmd := kamelTestPreAddCommandInit()
-
 	localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-p", "prop1=value1", "-p", "prop2=value2")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+		"-p", "prop1=value1",
+		"-p", "prop2=value2")
 
+	require.NoError(t, err)
 	if len(localRunCmdOptions.Properties) != 2 {
 		t.Fatalf("Additional dependencies expected to contain: \n %v elements\nGot:\n %v elements\n", 2, len(localRunCmdOptions.Properties))
 	}
@@ -77,33 +79,31 @@ func TestLocalRunPropertiesFlag(t *testing.T) {
 
 func TestLocalRunAdditionalDependenciesFlag(t *testing.T) {
 	options, rootCmd := kamelTestPreAddCommandInit()
-
 	localRunCmdOptions := addTestLocalRunCmd(options, rootCmd)
-
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-d", "mvn:camel-component-1", "-d", "mvn:camel-component-2")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
-
-	if len(localRunCmdOptions.AdditionalDependencies) != 2 {
-		t.Fatalf("Additional dependencies expected to contain: \n %v elements\nGot:\n %v elements\n", 2, len(localRunCmdOptions.AdditionalDependencies))
-	}
-	if localRunCmdOptions.AdditionalDependencies[0] != "mvn:camel-component-1" || localRunCmdOptions.AdditionalDependencies[1] != "mvn:camel-component-2" {
-		t.Fatalf("Additional dependencies expected to be: \n %v\nGot:\n %v\n", "[mvn:camel-component-1, mvn:camel-component-2]", localRunCmdOptions.AdditionalDependencies)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+		"-d", "camel-amqp",
+		"-d", "camel:bean",
+		"-d", "camel-quarkus-controlbus",
+		"-d", "camel-quarkus:directvm",
+		"--dependency", "mvn:test:component:1.0.0")
+
+	require.NoError(t, err)
+	assert.Len(t, localRunCmdOptions.Dependencies, 5)
+	assert.ElementsMatch(t, localRunCmdOptions.Dependencies, []string{
+		"camel:amqp", "camel:bean", "camel:controlbus", "camel:directvm", "mvn:test:component:1.0.0",
+	})
 }
 
 func TestLocalRunAcceptsTraits(t *testing.T) {
 	options, rootCmd := kamelTestPreAddCommandInit()
-
 	addTestLocalRunCmd(options, rootCmd)
-
 	kamelTestPostAddCommandInit(t, rootCmd)
 
-	_, err := test.ExecuteCommand(rootCmd, "run", "route.java", "-t", "jolokia.enabled=true", "--trait", "prometheus.enabled=true")
-	if err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
+	_, err := test.ExecuteCommand(rootCmd, "local", "run", "route.java",
+		"-t", "jolokia.enabled=true",
+		"--trait", "prometheus.enabled=true")
+
+	require.NoError(t, err)
 }