You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2019/01/07 14:25:40 UTC

[camel-k] 03/13: Fix #237: creating client wrapper and fix build

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

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

commit 37fd80d9b7a8cad63fd5c04240652195923e7256
Author: nferraro <ni...@gmail.com>
AuthorDate: Fri Jan 4 13:11:28 2019 +0100

    Fix #237: creating client wrapper and fix build
---
 .gitignore                                         |   6 +-
 build/Dockerfile                                   |  10 +-
 {tmp => build}/maven/settings.xml                  |   2 +-
 cmd/kamel/main.go                                  |   2 +-
 cmd/{camel-k => manager}/main.go                   |   3 +-
 pkg/builder/builder.go                             |   2 +-
 pkg/builder/builder_steps.go                       |  13 +-
 pkg/builder/builder_types.go                       |   2 +-
 pkg/builder/s2i/publisher.go                       |  13 +-
 pkg/client/client.go                               | 131 +++++++++++++++++++++
 pkg/client/cmd/client.go                           |  42 -------
 pkg/{client => }/cmd/completion.go                 |   0
 pkg/{client => }/cmd/completion_bash.go            |   0
 pkg/{client => }/cmd/completion_zsh.go             |   0
 pkg/{client => }/cmd/context.go                    |   0
 pkg/{client => }/cmd/context_create.go             |   6 +-
 pkg/{client => }/cmd/context_delete.go             |   9 +-
 pkg/{client => }/cmd/context_get.go                |   5 +-
 pkg/{client => }/cmd/delete.go                     |   4 +-
 pkg/{client => }/cmd/get.go                        |   5 +-
 pkg/{client => }/cmd/install.go                    |   0
 pkg/{client => }/cmd/log.go                        |  14 +--
 pkg/{client => }/cmd/reset.go                      |  10 +-
 pkg/{client => }/cmd/root.go                       |  11 +-
 pkg/{client => }/cmd/run.go                        |  11 +-
 pkg/{client => }/cmd/util.go                       |   2 +-
 pkg/{client => }/cmd/version.go                    |   0
 pkg/controller/integration/action.go               |   8 +-
 pkg/controller/integration/build_image.go          |   7 +-
 pkg/controller/integration/deploy.go               |   4 +-
 .../integration/integration_controller.go          |  16 +--
 pkg/controller/integration/util.go                 |   8 +-
 pkg/controller/integrationcontext/action.go        |   8 +-
 pkg/controller/integrationcontext/build.go         |   4 +-
 .../integrationcontext_controller.go               |  16 +--
 pkg/controller/integrationplatform/action.go       |   8 +-
 pkg/controller/integrationplatform/initialize.go   |   8 +-
 .../integrationplatform_controller.go              |  16 +--
 pkg/controller/integrationplatform/start.go        |   4 +-
 pkg/install/cluster.go                             |  17 +--
 pkg/install/common.go                              |   2 +-
 pkg/install/operator.go                            |  21 ++--
 pkg/platform/platform.go                           |   5 +-
 pkg/trait/catalog.go                               |   2 +-
 pkg/trait/classpath.go                             |   6 +-
 pkg/trait/knative.go                               |   5 +-
 pkg/trait/trait.go                                 |   2 +-
 pkg/trait/types.go                                 |   8 +-
 pkg/trait/util.go                                  |   9 +-
 pkg/util/kubernetes/config.go                      |  44 -------
 pkg/util/kubernetes/converter.go                   |  32 -----
 pkg/util/kubernetes/namespace.go                   |  58 ---------
 pkg/util/kubernetes/replace.go                     |   5 +-
 pkg/util/kubernetes/wait.go                        |   5 +-
 pkg/util/minishift/minishift.go                    |   5 +-
 script/Makefile                                    |   8 +-
 script/package_maven_artifacts.sh                  |   2 +-
 script/travis_build.sh                             |   2 +-
 test/log_scrape_integration_test.go                |   9 +-
 test/testing_env.go                                |  18 ++-
 tmp/build/Dockerfile                               |  14 ---
 tmp/build/build.sh                                 |  18 ---
 tmp/build/docker_build.sh                          |  11 --
 tmp/codegen/boilerplate.go.txt                     |  16 ---
 tmp/codegen/update-generated.sh                    |  12 --
 65 files changed, 299 insertions(+), 447 deletions(-)

diff --git a/.gitignore b/.gitignore
index 871a20b..e43f829 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,9 +16,9 @@
 .gopath
 
 # Temporary Build Files
-tmp/_output
-tmp/_test
-tmp/_maven_output
+build/_output
+build/_test
+build/_maven_output
 
 # eclipse / vscode
 .settings
diff --git a/build/Dockerfile b/build/Dockerfile
index f3e3af6..39c3b26 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -1,7 +1,11 @@
-FROM alpine:3.8
+FROM fabric8/s2i-java:2.3
 
-RUN apk upgrade --update --no-cache
+ADD build/_maven_output /tmp/artifacts/m2
 
-USER nobody
+USER 0
+RUN chgrp -R 0 /tmp/artifacts/m2 \
+ && chmod -R g=u /tmp/artifacts/m2
+
+USER 1000
 
 ADD build/_output/bin/camel-k /usr/local/bin/camel-k
diff --git a/tmp/maven/settings.xml b/build/maven/settings.xml
similarity index 79%
rename from tmp/maven/settings.xml
rename to build/maven/settings.xml
index 6d16002..6c6c5c7 100644
--- a/tmp/maven/settings.xml
+++ b/build/maven/settings.xml
@@ -2,5 +2,5 @@
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                           https://maven.apache.org/xsd/settings-1.0.0.xsd">
-    <localRepository>tmp/_maven_output</localRepository>
+    <localRepository>build/_maven_output</localRepository>
 </settings>
\ No newline at end of file
diff --git a/cmd/kamel/main.go b/cmd/kamel/main.go
index 475fe62..72ac1c2 100644
--- a/cmd/kamel/main.go
+++ b/cmd/kamel/main.go
@@ -24,7 +24,7 @@ import (
 	"os"
 	"time"
 
-	"github.com/apache/camel-k/pkg/client/cmd"
+	"github.com/apache/camel-k/pkg/cmd"
 
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
 )
diff --git a/cmd/camel-k/main.go b/cmd/manager/main.go
similarity index 99%
rename from cmd/camel-k/main.go
rename to cmd/manager/main.go
index bc44be5..41dd81f 100644
--- a/cmd/camel-k/main.go
+++ b/cmd/manager/main.go
@@ -32,11 +32,12 @@ import (
 	"github.com/operator-framework/operator-sdk/pkg/leader"
 	"github.com/operator-framework/operator-sdk/pkg/ready"
 	sdkVersion "github.com/operator-framework/operator-sdk/version"
-	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
 	"sigs.k8s.io/controller-runtime/pkg/client/config"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
 	"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
+
+	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
 )
 
 var log = logf.Log.WithName("cmd")
diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go
index 0dd7388..2760f11 100644
--- a/pkg/builder/builder.go
+++ b/pkg/builder/builder.go
@@ -22,7 +22,7 @@ import (
 	"errors"
 	"io/ioutil"
 	"os"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 	"sort"
 	"sync"
 	"sync/atomic"
diff --git a/pkg/builder/builder_steps.go b/pkg/builder/builder_steps.go
index b640871..79d98d8 100644
--- a/pkg/builder/builder_steps.go
+++ b/pkg/builder/builder_steps.go
@@ -22,9 +22,10 @@ import (
 	"io/ioutil"
 	"os"
 	"path"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strings"
 
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"github.com/scylladb/go-set/strset"
 
 	"github.com/rs/xid"
@@ -244,7 +245,7 @@ func packager(ctx *Context, selector ArtifactsSelector) error {
 func ListPublishedImages(context *Context) ([]PublishedImage, error) {
 	list := v1alpha1.NewIntegrationContextList()
 
-	err := context.Client.List(context.C, &client.ListOptions{Namespace: context.Namespace}, &list)
+	err := context.Client.List(context.C, &k8sclient.ListOptions{Namespace: context.Namespace}, &list)
 	if err != nil {
 		return nil, err
 	}
@@ -349,9 +350,9 @@ func NotifyIntegrationContext(ctx *Context) error {
 			Name:      ctx.Request.Meta.Name,
 		},
 	}
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: ctx.Namespace,
-		Name: ctx.Request.Meta.Name,
+		Name:      ctx.Request.Meta.Name,
 	}
 
 	if err := ctx.Client.Get(ctx.C, key, &target); err != nil {
@@ -385,9 +386,9 @@ func NotifyIntegration(ctx *Context) error {
 			Name:      ctx.Request.Meta.Name,
 		},
 	}
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: ctx.Namespace,
-		Name: ctx.Request.Meta.Name,
+		Name:      ctx.Request.Meta.Name,
 	}
 
 	if err := ctx.Client.Get(ctx.C, key, &target); err != nil {
diff --git a/pkg/builder/builder_types.go b/pkg/builder/builder_types.go
index ffad6dc..662d068 100644
--- a/pkg/builder/builder_types.go
+++ b/pkg/builder/builder_types.go
@@ -21,7 +21,7 @@ import (
 	"context"
 	"fmt"
 	"math"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 	"time"
 
 	"k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/pkg/builder/s2i/publisher.go b/pkg/builder/s2i/publisher.go
index b365754..757d1b3 100644
--- a/pkg/builder/s2i/publisher.go
+++ b/pkg/builder/s2i/publisher.go
@@ -19,10 +19,11 @@ package s2i
 
 import (
 	"io/ioutil"
-	"k8s.io/apimachinery/pkg/util/json"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"time"
 
+	"k8s.io/apimachinery/pkg/util/json"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"github.com/apache/camel-k/pkg/builder"
 
 	"github.com/apache/camel-k/pkg/util/kubernetes"
@@ -111,11 +112,7 @@ func Publisher(ctx *builder.Context) error {
 		return errors.Wrap(err, "cannot fully read tar file "+ctx.Archive)
 	}
 
-	kc, err := kubernetes.AsKubernetesClient(ctx.Client)
-	if err != nil {
-		return err
-	}
-	restClient, err := customclient.GetClientFor(kc,"build.openshift.io", "v1")
+	restClient, err := customclient.GetClientFor(ctx.Client, "build.openshift.io", "v1")
 	if err != nil {
 		return err
 	}
@@ -159,7 +156,7 @@ func Publisher(ctx *builder.Context) error {
 		return err
 	}
 
-	key, err := client.ObjectKeyFromObject(&is)
+	key, err := k8sclient.ObjectKeyFromObject(&is)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/client/client.go b/pkg/client/client.go
new file mode 100644
index 0000000..026e26b
--- /dev/null
+++ b/pkg/client/client.go
@@ -0,0 +1,131 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package client
+
+import (
+	"github.com/apache/camel-k/pkg/apis"
+	"io/ioutil"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/client-go/tools/clientcmd"
+	"os"
+	"os/user"
+	"path/filepath"
+	"sigs.k8s.io/controller-runtime/pkg/client/config"
+
+	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
+	"github.com/pkg/errors"
+	"k8s.io/client-go/kubernetes"
+	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
+	clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
+	controller "sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/manager"
+)
+
+// Client is an abstraction for a k8s client
+type Client interface {
+	controller.Client
+	kubernetes.Interface
+}
+
+// Injectable identifies objects that can receive a Client
+type Injectable interface {
+	InjectClient(Client)
+}
+
+type defaultClient struct {
+	controller.Client
+	kubernetes.Interface
+}
+
+// NewOutOfClusterClient creates a new k8s client that can be used from outside the cluster
+func NewOutOfClusterClient(kubeconfig string, namespace string) (Client, error) {
+	initialize(kubeconfig)
+	// Get a config to talk to the apiserver
+	cfg, err := config.GetConfig()
+	if err != nil {
+		return nil, err
+	}
+	// Create a new Cmd to provide shared dependencies and start components
+	mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
+
+	// Setup Scheme for all resources
+	if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
+		return nil, err
+	}
+	return FromManager(mgr)
+}
+
+// FromManager creates a new k8s client from a manager object
+func FromManager(manager manager.Manager) (Client, error) {
+	var err error
+	var clientset kubernetes.Interface
+	if clientset, err = kubernetes.NewForConfig(manager.GetConfig()); err != nil {
+		return nil, err
+	}
+	return &defaultClient{
+		Client:    manager.GetClient(),
+		Interface: clientset,
+	}, nil
+}
+
+// init initialize the k8s client for usage outside the cluster
+func initialize(kubeconfig string) error {
+	if kubeconfig == "" {
+		kubeconfig = getDefaultKubeConfigFile()
+	}
+	os.Setenv(k8sutil.KubeConfigEnvVar, kubeconfig)
+	return nil
+}
+
+func getDefaultKubeConfigFile() string {
+	usr, err := user.Current()
+	if err != nil {
+		panic(err) // TODO handle error
+	}
+	return filepath.Join(usr.HomeDir, ".kube", "config")
+}
+
+// GetCurrentNamespace --
+func GetCurrentNamespace(kubeconfig string) (string, error) {
+	if kubeconfig == "" {
+		kubeconfig = getDefaultKubeConfigFile()
+	}
+	if kubeconfig == "" {
+		return "default", nil
+	}
+
+	data, err := ioutil.ReadFile(kubeconfig)
+	if err != nil {
+		return "", err
+	}
+	conf := clientcmdapi.NewConfig()
+	if len(data) == 0 {
+		return "", errors.New("kubernetes config file is empty")
+	}
+
+	decoded, _, err := clientcmdlatest.Codec.Decode(data, &schema.GroupVersionKind{Version: clientcmdlatest.Version, Kind: "Config"}, conf)
+	if err != nil {
+		return "", err
+	}
+
+	clientcmdconfig := decoded.(*clientcmdapi.Config)
+
+	cc := clientcmd.NewDefaultClientConfig(*clientcmdconfig, &clientcmd.ConfigOverrides{})
+	ns, _, err := cc.Namespace()
+	return ns, err
+}
diff --git a/pkg/client/cmd/client.go b/pkg/client/cmd/client.go
deleted file mode 100644
index 12f35e5..0000000
--- a/pkg/client/cmd/client.go
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package cmd
-
-import (
-	"github.com/apache/camel-k/pkg/apis"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/client/config"
-	"sigs.k8s.io/controller-runtime/pkg/manager"
-)
-
-// NewCmdClient returns a new client that can be used from command line tools
-func NewCmdClient(namespace string) (client.Client, error) {
-	// Get a config to talk to the apiserver
-	cfg, err := config.GetConfig()
-	if err != nil {
-		return nil, err
-	}
-	// Create a new Cmd to provide shared dependencies and start components
-	mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
-
-	// Setup Scheme for all resources
-	if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
-		return nil, err
-	}
-	return mgr.GetClient(), nil
-}
diff --git a/pkg/client/cmd/completion.go b/pkg/cmd/completion.go
similarity index 100%
rename from pkg/client/cmd/completion.go
rename to pkg/cmd/completion.go
diff --git a/pkg/client/cmd/completion_bash.go b/pkg/cmd/completion_bash.go
similarity index 100%
rename from pkg/client/cmd/completion_bash.go
rename to pkg/cmd/completion_bash.go
diff --git a/pkg/client/cmd/completion_zsh.go b/pkg/cmd/completion_zsh.go
similarity index 100%
rename from pkg/client/cmd/completion_zsh.go
rename to pkg/cmd/completion_zsh.go
diff --git a/pkg/client/cmd/context.go b/pkg/cmd/context.go
similarity index 100%
rename from pkg/client/cmd/context.go
rename to pkg/cmd/context.go
diff --git a/pkg/client/cmd/context_create.go b/pkg/cmd/context_create.go
similarity index 97%
rename from pkg/client/cmd/context_create.go
rename to pkg/cmd/context_create.go
index e972853..7090d9b 100644
--- a/pkg/client/cmd/context_create.go
+++ b/pkg/cmd/context_create.go
@@ -20,7 +20,6 @@ package cmd
 import (
 	"errors"
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strconv"
 	"strings"
 
@@ -31,6 +30,7 @@ import (
 
 	"github.com/spf13/cobra"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewCmdContext --
@@ -85,9 +85,9 @@ func (command *contextCreateCommand) run(cmd *cobra.Command, args []string) erro
 		return err
 	}
 	ctx := v1alpha1.NewIntegrationContext(command.Namespace, args[0])
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: command.Namespace,
-		Name: args[0],
+		Name:      args[0],
 	}
 	if err := c.Get(command.Context, key, &ctx); err == nil {
 		// the integration context already exists, let's check that it is
diff --git a/pkg/client/cmd/context_delete.go b/pkg/cmd/context_delete.go
similarity index 94%
rename from pkg/client/cmd/context_delete.go
rename to pkg/cmd/context_delete.go
index 5745336..6306a14 100644
--- a/pkg/client/cmd/context_delete.go
+++ b/pkg/cmd/context_delete.go
@@ -20,7 +20,8 @@ package cmd
 import (
 	"errors"
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/spf13/cobra"
@@ -80,7 +81,7 @@ func (command *contextDeleteCommand) run(args []string) error {
 
 	if command.all {
 		ctxList := v1alpha1.NewIntegrationContextList()
-		if err := c.List(command.Context, &client.ListOptions{Namespace: command.Namespace}, &ctxList); err != nil {
+		if err := c.List(command.Context, &k8sclient.ListOptions{Namespace: command.Namespace}, &ctxList); err != nil {
 			return err
 		}
 
@@ -104,9 +105,9 @@ func (command *contextDeleteCommand) run(args []string) error {
 
 func (command *contextDeleteCommand) delete(name string) error {
 	ctx := v1alpha1.NewIntegrationContext(command.Namespace, name)
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: command.Namespace,
-		Name: name,
+		Name:      name,
 	}
 	c, err := command.GetCmdClient()
 	if err != nil {
diff --git a/pkg/client/cmd/context_get.go b/pkg/cmd/context_get.go
similarity index 93%
rename from pkg/client/cmd/context_get.go
rename to pkg/cmd/context_get.go
index a666ce5..eab2390 100644
--- a/pkg/client/cmd/context_get.go
+++ b/pkg/cmd/context_get.go
@@ -20,9 +20,10 @@ package cmd
 import (
 	"fmt"
 	"os"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"text/tabwriter"
 
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/spf13/cobra"
 )
@@ -71,7 +72,7 @@ func (command *contextGetCommand) run() error {
 	if err != nil {
 		return err
 	}
-	if err := c.List(command.Context, &client.ListOptions{Namespace: command.Namespace}, &ctxList); err != nil {
+	if err := c.List(command.Context, &k8sclient.ListOptions{Namespace: command.Namespace}, &ctxList); err != nil {
 		return err
 	}
 
diff --git a/pkg/client/cmd/delete.go b/pkg/cmd/delete.go
similarity index 95%
rename from pkg/client/cmd/delete.go
rename to pkg/cmd/delete.go
index f724f77..22a9280 100644
--- a/pkg/client/cmd/delete.go
+++ b/pkg/cmd/delete.go
@@ -20,9 +20,9 @@ package cmd
 import (
 	"errors"
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strconv"
 
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/spf13/cobra"
 	k8errors "k8s.io/apimachinery/pkg/api/errors"
@@ -98,7 +98,7 @@ func (command *deleteCmdOptions) run(args []string) error {
 		}
 
 		//Looks like Operator SDK doesn't support deletion of all objects with one command
-		err := c.List(command.Context, &client.ListOptions{Namespace: command.Namespace}, &integrationList)
+		err := c.List(command.Context, &k8sclient.ListOptions{Namespace: command.Namespace}, &integrationList)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/client/cmd/get.go b/pkg/cmd/get.go
similarity index 93%
rename from pkg/client/cmd/get.go
rename to pkg/cmd/get.go
index 528bc57..619333c 100644
--- a/pkg/client/cmd/get.go
+++ b/pkg/cmd/get.go
@@ -20,9 +20,10 @@ package cmd
 import (
 	"fmt"
 	"os"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"text/tabwriter"
 
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/spf13/cobra"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -61,7 +62,7 @@ func (o *getCmdOptions) run(cmd *cobra.Command, args []string) error {
 
 	namespace := o.Namespace
 
-	err = c.List(o.Context, &client.ListOptions{Namespace: namespace}, &integrationList)
+	err = c.List(o.Context, &k8sclient.ListOptions{Namespace: namespace}, &integrationList)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/client/cmd/install.go b/pkg/cmd/install.go
similarity index 100%
rename from pkg/client/cmd/install.go
rename to pkg/cmd/install.go
diff --git a/pkg/client/cmd/log.go b/pkg/cmd/log.go
similarity index 88%
rename from pkg/client/cmd/log.go
rename to pkg/cmd/log.go
index 39bcc24..8e92ebc 100644
--- a/pkg/client/cmd/log.go
+++ b/pkg/cmd/log.go
@@ -19,14 +19,12 @@ package cmd
 
 import (
 	"fmt"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/log"
 	"github.com/spf13/cobra"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 func newCmdLog(rootCmdOptions *RootCmdOptions) *cobra.Command {
@@ -65,10 +63,6 @@ func (o *logCmdOptions) run(cmd *cobra.Command, args []string) error {
 	if err != nil {
 		return err
 	}
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return err
-	}
 	integration := v1alpha1.Integration{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       v1alpha1.IntegrationKind,
@@ -79,15 +73,15 @@ func (o *logCmdOptions) run(cmd *cobra.Command, args []string) error {
 			Name:      args[0],
 		},
 	}
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: o.Namespace,
-		Name: args[0],
+		Name:      args[0],
 	}
 
 	if err := c.Get(o.Context, key, &integration); err != nil {
 		return err
 	}
-	if err := log.Print(o.Context, kc, &integration); err != nil {
+	if err := log.Print(o.Context, c, &integration); err != nil {
 		return err
 	}
 
diff --git a/pkg/client/cmd/reset.go b/pkg/cmd/reset.go
similarity index 90%
rename from pkg/client/cmd/reset.go
rename to pkg/cmd/reset.go
index 0e5caa2..652964f 100644
--- a/pkg/client/cmd/reset.go
+++ b/pkg/cmd/reset.go
@@ -19,7 +19,9 @@ package cmd
 
 import (
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
+
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/pkg/errors"
@@ -69,7 +71,7 @@ func (o *resetCmdOptions) reset(cmd *cobra.Command, args []string) (err error) {
 
 func (o *resetCmdOptions) deleteAllIntegrations(c client.Client) (int, error) {
 	list := v1alpha1.NewIntegrationList()
-	if err := c.List(o.Context, &client.ListOptions{Namespace: o.Namespace}, &list); err != nil {
+	if err := c.List(o.Context, &k8sclient.ListOptions{Namespace: o.Namespace}, &list); err != nil {
 		return 0, errors.Wrap(err, fmt.Sprintf("could not retrieve integrations from namespace %s", o.Namespace))
 	}
 	for _, i := range list.Items {
@@ -83,7 +85,7 @@ func (o *resetCmdOptions) deleteAllIntegrations(c client.Client) (int, error) {
 
 func (o *resetCmdOptions) deleteAllIntegrationContexts(c client.Client) (int, error) {
 	list := v1alpha1.NewIntegrationContextList()
-	if err := c.List(o.Context, &client.ListOptions{Namespace: o.Namespace}, &list); err != nil {
+	if err := c.List(o.Context, &k8sclient.ListOptions{Namespace: o.Namespace}, &list); err != nil {
 		return 0, errors.Wrap(err, fmt.Sprintf("could not retrieve integration contexts from namespace %s", o.Namespace))
 	}
 	for _, i := range list.Items {
@@ -97,7 +99,7 @@ func (o *resetCmdOptions) deleteAllIntegrationContexts(c client.Client) (int, er
 
 func (o *resetCmdOptions) resetIntegrationPlatform(c client.Client) error {
 	list := v1alpha1.NewIntegrationPlatformList()
-	if err := c.List(o.Context, &client.ListOptions{Namespace: o.Namespace}, &list); err != nil {
+	if err := c.List(o.Context, &k8sclient.ListOptions{Namespace: o.Namespace}, &list); err != nil {
 		return errors.Wrap(err, fmt.Sprintf("could not retrieve integration platform from namespace %s", o.Namespace))
 	}
 	if len(list.Items) > 1 {
diff --git a/pkg/client/cmd/root.go b/pkg/cmd/root.go
similarity index 88%
rename from pkg/client/cmd/root.go
rename to pkg/cmd/root.go
index 6b2aba9..933a8b8 100644
--- a/pkg/client/cmd/root.go
+++ b/pkg/cmd/root.go
@@ -19,10 +19,9 @@ package cmd
 
 import (
 	"context"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const kamelCommandLongDescription = `
@@ -51,7 +50,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) {
 		BashCompletionFunction: bashCompletionFunction,
 		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
 			if options.Namespace == "" {
-				current, err := kubernetes.GetClientCurrentNamespace(options.KubeConfig)
+				current, err := client.GetCurrentNamespace(options.KubeConfig)
 				if err != nil {
 					return errors.Wrap(err, "cannot get current namespace")
 				}
@@ -60,9 +59,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) {
 					return err
 				}
 			}
-
-			// Initialize the Kubernetes client to allow using the operator-sdk
-			return kubernetes.InitKubeClient(options.KubeConfig)
+			return nil
 		},
 	}
 
@@ -89,6 +86,6 @@ func (command *RootCmdOptions) GetCmdClient() (client.Client, error) {
 		return command._client, nil
 	}
 	var err error
-	command._client, err = NewCmdClient(command.Namespace)
+	command._client, err = client.NewOutOfClusterClient(command.KubeConfig, command.Namespace)
 	return command._client, err
 }
diff --git a/pkg/client/cmd/run.go b/pkg/cmd/run.go
similarity index 98%
rename from pkg/client/cmd/run.go
rename to pkg/cmd/run.go
index 6c778bd..2b35397 100644
--- a/pkg/client/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -21,13 +21,13 @@ import (
 	"bytes"
 	"encoding/base64"
 	"fmt"
+	"github.com/apache/camel-k/pkg/client"
 	"io/ioutil"
 	"net/http"
 	"os"
 	"os/signal"
 	"path"
 	"regexp"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strconv"
 	"strings"
 	"syscall"
@@ -48,6 +48,7 @@ import (
 	"github.com/spf13/cobra"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/apis/meta/v1"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 var (
@@ -148,10 +149,6 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 	if err != nil {
 		return err
 	}
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return err
-	}
 
 	catalog := trait.NewCatalog(o.Context, c)
 	tp := catalog.ComputeTraitsProperties()
@@ -196,7 +193,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
 		}
 	}
 	if o.Logs || o.Dev {
-		err = log.Print(o.Context, kc, integration)
+		err = log.Print(o.Context, c, integration)
 		if err != nil {
 			return err
 		}
@@ -379,7 +376,7 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string)
 	if err != nil && k8serrors.IsAlreadyExists(err) {
 		existed = true
 		clone := integration.DeepCopy()
-		key, err := client.ObjectKeyFromObject(clone)
+		key, err := k8sclient.ObjectKeyFromObject(clone)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/client/cmd/util.go b/pkg/cmd/util.go
similarity index 96%
rename from pkg/client/cmd/util.go
rename to pkg/cmd/util.go
index e57602d..70dd208 100644
--- a/pkg/client/cmd/util.go
+++ b/pkg/cmd/util.go
@@ -21,7 +21,7 @@ import (
 	"context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // DeleteIntegration --
diff --git a/pkg/client/cmd/version.go b/pkg/cmd/version.go
similarity index 100%
rename from pkg/client/cmd/version.go
rename to pkg/cmd/version.go
diff --git a/pkg/controller/integration/action.go b/pkg/controller/integration/action.go
index fdf2a56..6a66e06 100644
--- a/pkg/controller/integration/action.go
+++ b/pkg/controller/integration/action.go
@@ -20,13 +20,12 @@ package integration
 import (
 	"context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // Action --
 type Action interface {
-	inject.Client
+	client.Injectable
 
 	// a user friendly name for the action
 	Name() string
@@ -42,7 +41,6 @@ type baseAction struct {
 	client client.Client
 }
 
-func (action *baseAction) InjectClient(client client.Client) error {
+func (action *baseAction) InjectClient(client client.Client) {
 	action.client = client
-	return nil
 }
diff --git a/pkg/controller/integration/build_image.go b/pkg/controller/integration/build_image.go
index af3ecaf..222b753 100644
--- a/pkg/controller/integration/build_image.go
+++ b/pkg/controller/integration/build_image.go
@@ -29,12 +29,11 @@ import (
 	"github.com/apache/camel-k/pkg/trait"
 
 	"github.com/apache/camel-k/pkg/builder"
-	"github.com/sirupsen/logrus"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
 	"github.com/apache/camel-k/pkg/platform"
+	"github.com/sirupsen/logrus"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewBuildImageAction create an action that handles integration image build
@@ -69,7 +68,7 @@ func (action *buildImageAction) Handle(ctx context.Context, integration *v1alpha
 	// look-up the integration context associated to this integration, this is needed
 	// to determine the base image
 	ictx := v1alpha1.NewIntegrationContext(integration.Namespace, integration.Status.Context)
-	ikey := client.ObjectKey{
+	ikey := k8sclient.ObjectKey{
 		Namespace: integration.Namespace,
 		Name:      integration.Status.Context,
 	}
diff --git a/pkg/controller/integration/deploy.go b/pkg/controller/integration/deploy.go
index 8972378..924ef89 100644
--- a/pkg/controller/integration/deploy.go
+++ b/pkg/controller/integration/deploy.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewDeployAction create an action that handles integration deploy
@@ -49,7 +49,7 @@ func (action *deployAction) Handle(ctx context.Context, integration *v1alpha1.In
 	if ictxName == "" {
 		return errors.Errorf("no context set on integration %s", integration.Name)
 	}
-	ictxKey := client.ObjectKey{
+	ictxKey := k8sclient.ObjectKey{
 		Namespace: integration.Namespace,
 		Name:      integration.Name,
 	}
diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index 5778166..34bf34a 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -6,10 +6,10 @@ import (
 	"time"
 
 	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/client"
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -28,12 +28,16 @@ var log = logf.Log.WithName("controller_integration")
 // Add creates a new Integration Controller and adds it to the Manager. The Manager will set fields on the Controller
 // and Start it when the Manager is Started.
 func Add(mgr manager.Manager) error {
-	return add(mgr, newReconciler(mgr))
+	c, err := client.FromManager(mgr)
+	if err != nil {
+		return err
+	}
+	return add(mgr, newReconciler(mgr, c))
 }
 
 // newReconciler returns a new reconcile.Reconciler
-func newReconciler(mgr manager.Manager) reconcile.Reconciler {
-	return &ReconcileIntegration{client: mgr.GetClient(), scheme: mgr.GetScheme()}
+func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
+	return &ReconcileIntegration{client: c, scheme: mgr.GetScheme()}
 }
 
 // add adds a new Controller to mgr with r as the reconcile.Reconciler
@@ -106,9 +110,7 @@ func (r *ReconcileIntegration) Reconcile(request reconcile.Request) (reconcile.R
 	}
 
 	for _, a := range integrationActionPool {
-		if err := a.InjectClient(r.client); err != nil {
-			return reconcile.Result{}, err
-		}
+		a.InjectClient(r.client)
 		if a.CanHandle(instance) {
 			logrus.Debug("Invoking action ", a.Name(), " on integration ", instance.Name)
 			if err := a.Handle(ctx, instance); err != nil {
diff --git a/pkg/controller/integration/util.go b/pkg/controller/integration/util.go
index 3cbb407..2581cdc 100644
--- a/pkg/controller/integration/util.go
+++ b/pkg/controller/integration/util.go
@@ -19,8 +19,10 @@ package integration
 
 import (
 	"context"
+
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/apache/camel-k/pkg/util"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/pkg/errors"
@@ -31,7 +33,7 @@ func LookupContextForIntegration(ctx context.Context, c client.Client, integrati
 	if integration.Status.Context != "" {
 		name := integration.Status.Context
 		ictx := v1alpha1.NewIntegrationContext(integration.Namespace, name)
-		key := client.ObjectKey{
+		key := k8sclient.ObjectKey{
 			Namespace: integration.Namespace,
 			Name:      name,
 		}
@@ -43,7 +45,7 @@ func LookupContextForIntegration(ctx context.Context, c client.Client, integrati
 	}
 
 	ctxList := v1alpha1.NewIntegrationContextList()
-	if err := c.List(ctx, &client.ListOptions{Namespace: integration.Namespace}, &ctxList); err != nil {
+	if err := c.List(ctx, &k8sclient.ListOptions{Namespace: integration.Namespace}, &ctxList); err != nil {
 		return nil, err
 	}
 
diff --git a/pkg/controller/integrationcontext/action.go b/pkg/controller/integrationcontext/action.go
index 5a87127..55e72c8 100644
--- a/pkg/controller/integrationcontext/action.go
+++ b/pkg/controller/integrationcontext/action.go
@@ -20,13 +20,12 @@ package integrationcontext
 import (
 	"context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // Action --
 type Action interface {
-	inject.Client
+	client.Injectable
 
 	// a user friendly name for the action
 	Name() string
@@ -42,7 +41,6 @@ type baseAction struct {
 	client client.Client
 }
 
-func (action *baseAction) InjectClient(client client.Client) error {
+func (action *baseAction) InjectClient(client client.Client) {
 	action.client = client
-	return nil
 }
\ No newline at end of file
diff --git a/pkg/controller/integrationcontext/build.go b/pkg/controller/integrationcontext/build.go
index edfe3d3..09fe4b0 100644
--- a/pkg/controller/integrationcontext/build.go
+++ b/pkg/controller/integrationcontext/build.go
@@ -27,7 +27,7 @@ import (
 	"github.com/apache/camel-k/pkg/platform"
 
 	"github.com/sirupsen/logrus"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewBuildAction creates a new build handling action for the context
@@ -129,7 +129,7 @@ func (action *buildAction) Handle(ctx context.Context, ictx *v1alpha1.Integratio
 // informIntegrations triggers the processing of all integrations waiting for this context to be built
 func (action *buildAction) informIntegrations(ictx *v1alpha1.IntegrationContext) error {
 	list := v1alpha1.NewIntegrationList()
-	err := action.client.List(action.Context, &client.ListOptions{Namespace: ictx.Namespace}, &list)
+	err := action.client.List(action.Context, &k8sclient.ListOptions{Namespace: ictx.Namespace}, &list)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/controller/integrationcontext/integrationcontext_controller.go b/pkg/controller/integrationcontext/integrationcontext_controller.go
index 1c93ab3..04c54d4 100644
--- a/pkg/controller/integrationcontext/integrationcontext_controller.go
+++ b/pkg/controller/integrationcontext/integrationcontext_controller.go
@@ -8,7 +8,7 @@ import (
 	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -22,12 +22,16 @@ var log = logf.Log.WithName("controller_integrationcontext")
 // Add creates a new IntegrationContext Controller and adds it to the Manager. The Manager will set fields on the Controller
 // and Start it when the Manager is Started.
 func Add(mgr manager.Manager) error {
-	return add(mgr, newReconciler(mgr))
+	c, err := client.FromManager(mgr)
+	if err != nil {
+		return err
+	}
+	return add(mgr, newReconciler(mgr, c))
 }
 
 // newReconciler returns a new reconcile.Reconciler
-func newReconciler(mgr manager.Manager) reconcile.Reconciler {
-	return &ReconcileIntegrationContext{client: mgr.GetClient(), scheme: mgr.GetScheme()}
+func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
+	return &ReconcileIntegrationContext{client: c, scheme: mgr.GetScheme()}
 }
 
 // add adds a new Controller to mgr with r as the reconcile.Reconciler
@@ -89,9 +93,7 @@ func (r *ReconcileIntegrationContext) Reconcile(request reconcile.Request) (reco
 	}
 
 	for _, a := range integrationContextActionPool {
-		if err := a.InjectClient(r.client); err != nil {
-			return reconcile.Result{}, err
-		}
+		a.InjectClient(r.client)
 		if a.CanHandle(instance) {
 			logrus.Debug("Invoking action ", a.Name(), " on integration context ", instance.Name)
 			if err := a.Handle(ctx, instance); err != nil {
diff --git a/pkg/controller/integrationplatform/action.go b/pkg/controller/integrationplatform/action.go
index bf07582..b332a74 100644
--- a/pkg/controller/integrationplatform/action.go
+++ b/pkg/controller/integrationplatform/action.go
@@ -20,13 +20,12 @@ package integrationplatform
 import (
 	"context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // Action --
 type Action interface {
-	inject.Client
+	client.Injectable
 
 	// a user friendly name for the action
 	Name() string
@@ -42,7 +41,6 @@ type baseAction struct {
 	client client.Client
 }
 
-func (action *baseAction) InjectClient(client client.Client) error {
+func (action *baseAction) InjectClient(client client.Client) {
 	action.client = client
-	return nil
 }
diff --git a/pkg/controller/integrationplatform/initialize.go b/pkg/controller/integrationplatform/initialize.go
index 2f1245e..79fff73 100644
--- a/pkg/controller/integrationplatform/initialize.go
+++ b/pkg/controller/integrationplatform/initialize.go
@@ -20,8 +20,6 @@ package integrationplatform
 import (
 	"context"
 	"errors"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	platformutils "github.com/apache/camel-k/pkg/platform"
 	"github.com/apache/camel-k/pkg/util/openshift"
@@ -65,12 +63,8 @@ func (action *initializeAction) Handle(ctx context.Context, platform *v1alpha1.I
 
 	// update missing fields in the resource
 	if target.Spec.Cluster == "" {
-		kc, err := kubernetes.AsKubernetesClient(action.client)
-		if err != nil {
-			return err
-		}
 		// determine the kind of cluster the platform in installed into
-		isOpenshift, err := openshift.IsOpenShift(kc)
+		isOpenshift, err := openshift.IsOpenShift(action.client)
 		switch {
 		case err != nil:
 			return err
diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go
index 1bc43e1..a5e2af2 100644
--- a/pkg/controller/integrationplatform/integrationplatform_controller.go
+++ b/pkg/controller/integrationplatform/integrationplatform_controller.go
@@ -3,10 +3,10 @@ package integrationplatform
 import (
 	"context"
 	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/sirupsen/logrus"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -21,12 +21,16 @@ var log = logf.Log.WithName("controller_integrationplatform")
 // Add creates a new IntegrationPlatform Controller and adds it to the Manager. The Manager will set fields on the Controller
 // and Start it when the Manager is Started.
 func Add(mgr manager.Manager) error {
-	return add(mgr, newReconciler(mgr))
+	c, err := client.FromManager(mgr)
+	if err != nil {
+		return err
+	}
+	return add(mgr, newReconciler(mgr, c))
 }
 
 // newReconciler returns a new reconcile.Reconciler
-func newReconciler(mgr manager.Manager) reconcile.Reconciler {
-	return &ReconcileIntegrationPlatform{client: mgr.GetClient(), scheme: mgr.GetScheme()}
+func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler {
+	return &ReconcileIntegrationPlatform{client: c, scheme: mgr.GetScheme()}
 }
 
 // add adds a new Controller to mgr with r as the reconcile.Reconciler
@@ -88,9 +92,7 @@ func (r *ReconcileIntegrationPlatform) Reconcile(request reconcile.Request) (rec
 	}
 
 	for _, a := range integrationPlatformActionPool {
-		if err := a.InjectClient(r.client); err != nil {
-			return reconcile.Result{}, err
-		}
+		a.InjectClient(r.client)
 		if a.CanHandle(instance) {
 			logrus.Debug("Invoking action ", a.Name(), " on integration platform ", instance.Name)
 			if err := a.Handle(ctx, instance); err != nil {
diff --git a/pkg/controller/integrationplatform/start.go b/pkg/controller/integrationplatform/start.go
index e14a7af..536c9d0 100644
--- a/pkg/controller/integrationplatform/start.go
+++ b/pkg/controller/integrationplatform/start.go
@@ -22,7 +22,7 @@ import (
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/sirupsen/logrus"
 	"k8s.io/apimachinery/pkg/labels"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewStartAction returns a action that waits for all required platform resources to start
@@ -59,7 +59,7 @@ func (action *startAction) Handle(ctx context.Context, platform *v1alpha1.Integr
 
 func (action *startAction) aggregatePlatformPhaseFromContexts(ctx context.Context, namespace string) (v1alpha1.IntegrationPlatformPhase, error) {
 	ctxs := v1alpha1.NewIntegrationContextList()
-	options := client.ListOptions{
+	options := k8sclient.ListOptions{
 		LabelSelector: labels.SelectorFromSet(labels.Set{
 			"camel.apache.org/context.type": "platform",
 		}),
diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go
index 1749322..66f00d5 100644
--- a/pkg/install/cluster.go
+++ b/pkg/install/cluster.go
@@ -20,13 +20,14 @@ package install
 import (
 	"context"
 	"github.com/apache/camel-k/deploy"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/kubernetes/customclient"
 	"k8s.io/api/rbac/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/yaml"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // SetupClusterwideResources --
@@ -69,11 +70,7 @@ func SetupClusterwideResourcesOrCollect(ctx context.Context, c client.Client, co
 
 // IsCRDInstalled check if the given CRT kind is installed
 func IsCRDInstalled(ctx context.Context, c client.Client, kind string) (bool, error) {
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return false, err
-	}
-	lst, err := kc.Discovery().ServerResourcesForGroupVersion("camel.apache.org/v1alpha1")
+	lst, err := c.Discovery().ServerResourcesForGroupVersion("camel.apache.org/v1alpha1")
 	if err != nil && errors.IsNotFound(err) {
 		return false, nil
 	} else if err != nil {
@@ -88,10 +85,6 @@ func IsCRDInstalled(ctx context.Context, c client.Client, kind string) (bool, er
 }
 
 func installCRD(ctx context.Context, c client.Client, kind string, resourceName string, collection *kubernetes.Collection) error {
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return err
-	}
 	crd := []byte(deploy.Resources[resourceName])
 	if collection != nil {
 		unstr, err := kubernetes.LoadRawResourceFromYaml(string(crd))
@@ -115,7 +108,7 @@ func installCRD(ctx context.Context, c client.Client, kind string, resourceName
 	if err != nil {
 		return err
 	}
-	restClient, err := customclient.GetClientFor(kc, "apiextensions.k8s.io", "v1beta1")
+	restClient, err := customclient.GetClientFor(c, "apiextensions.k8s.io", "v1beta1")
 	if err != nil {
 		return err
 	}
@@ -144,7 +137,7 @@ func IsClusterRoleInstalled(ctx context.Context, c client.Client, ) (bool, error
 			Name: "camel-k:edit",
 		},
 	}
-	key, err := client.ObjectKeyFromObject(&clusterRole)
+	key, err := k8sclient.ObjectKeyFromObject(&clusterRole)
 	if err != nil {
 		return false, err
 	}
diff --git a/pkg/install/common.go b/pkg/install/common.go
index 217bfe0..d1f35a8 100644
--- a/pkg/install/common.go
+++ b/pkg/install/common.go
@@ -25,7 +25,7 @@ import (
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // Resources installs named resources from the project resource directory
diff --git a/pkg/install/operator.go b/pkg/install/operator.go
index 130fb62..6417c37 100644
--- a/pkg/install/operator.go
+++ b/pkg/install/operator.go
@@ -25,11 +25,12 @@ import (
 
 	"github.com/apache/camel-k/deploy"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/apache/camel-k/pkg/util/knative"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/apache/camel-k/pkg/util/minishift"
 	"github.com/apache/camel-k/pkg/util/openshift"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // Operator installs the operator resources in the given namespace
@@ -39,11 +40,7 @@ func Operator(ctx context.Context, c client.Client, namespace string) error {
 
 // OperatorOrCollect installs the operator resources or adds them to the collector if present
 func OperatorOrCollect(ctx context.Context, c client.Client, namespace string, collection *kubernetes.Collection) error {
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return err
-	}
-	isOpenshift, err := openshift.IsOpenShift(kc)
+	isOpenshift, err := openshift.IsOpenShift(c)
 	if err != nil {
 		return err
 	}
@@ -57,7 +54,7 @@ func OperatorOrCollect(ctx context.Context, c client.Client, namespace string, c
 		}
 	}
 	// Additionally, install Knative resources (roles and bindings)
-	isKnative, err := knative.IsInstalled(ctx, kc)
+	isKnative, err := knative.IsInstalled(ctx, c)
 	if err != nil {
 		return err
 	}
@@ -103,14 +100,10 @@ func Platform(ctx context.Context, c client.Client, namespace string, registry s
 // PlatformOrCollect --
 // nolint: lll
 func PlatformOrCollect(ctx context.Context, c client.Client, namespace string, registry string, organization string, pushSecret string, collection *kubernetes.Collection) (*v1alpha1.IntegrationPlatform, error) {
-	kc, err := kubernetes.AsKubernetesClient(c)
-	if err != nil {
-		return nil, err
-	}
 	if err := waitForPlatformCRDAvailable(ctx, c, namespace, 25*time.Second); err != nil {
 		return nil, err
 	}
-	isOpenshift, err := openshift.IsOpenShift(kc)
+	isOpenshift, err := openshift.IsOpenShift(c)
 	if err != nil {
 		return nil, err
 	}
@@ -140,7 +133,7 @@ func PlatformOrCollect(ctx context.Context, c client.Client, namespace string, r
 	}
 
 	var knativeInstalled bool
-	if knativeInstalled, err = knative.IsInstalled(ctx, kc); err != nil {
+	if knativeInstalled, err = knative.IsInstalled(ctx, c); err != nil {
 		return nil, err
 	}
 	if knativeInstalled {
@@ -154,7 +147,7 @@ func waitForPlatformCRDAvailable(ctx context.Context, c client.Client, namespace
 	deadline := time.Now().Add(timeout)
 	for {
 		pla := v1alpha1.NewIntegrationPlatformList()
-		if err := c.List(ctx, &client.ListOptions{Namespace: namespace}, &pla); err == nil {
+		if err := c.List(ctx, &k8sclient.ListOptions{Namespace: namespace}, &pla); err == nil {
 			return nil
 		}
 		if time.Now().After(deadline) {
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index 3ac816c..df8fab6 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -20,10 +20,11 @@ package platform
 import (
 	"context"
 	"errors"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/builder"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // gBuilder is the current builder
@@ -60,7 +61,7 @@ func GetCurrentPlatform(ctx context.Context, c client.Client, namespace string)
 // ListPlatforms returns all platforms installed in a given namespace (only one will be active)
 func ListPlatforms(ctx context.Context, c client.Client, namespace string) (*v1alpha1.IntegrationPlatformList, error) {
 	lst := v1alpha1.NewIntegrationPlatformList()
-	if err := c.List(ctx, &client.ListOptions{Namespace: namespace}, &lst); err != nil {
+	if err := c.List(ctx, &k8sclient.ListOptions{Namespace: namespace}, &lst); err != nil {
 		return nil, err
 	}
 	return &lst, nil
diff --git a/pkg/trait/catalog.go b/pkg/trait/catalog.go
index 42ad112..facab15 100644
--- a/pkg/trait/catalog.go
+++ b/pkg/trait/catalog.go
@@ -20,7 +20,7 @@ package trait
 import (
 	"context"
 	"reflect"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 	"strings"
 
 	"github.com/sirupsen/logrus"
diff --git a/pkg/trait/classpath.go b/pkg/trait/classpath.go
index 80ac9a1..2eec71a 100644
--- a/pkg/trait/classpath.go
+++ b/pkg/trait/classpath.go
@@ -19,13 +19,13 @@ package trait
 
 import (
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strings"
 
 	"github.com/pkg/errors"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/envvar"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 type classpathTrait struct {
@@ -57,9 +57,9 @@ func (t *classpathTrait) Apply(e *Environment) error {
 	if ctx == nil && e.Integration.Status.Context != "" {
 		name := e.Integration.Status.Context
 		c := v1alpha1.NewIntegrationContext(e.Integration.Namespace, name)
-		key := client.ObjectKey{
+		key := k8sclient.ObjectKey{
 			Namespace: e.Integration.Namespace,
-			Name: name,
+			Name:      name,
 		}
 
 		if err := t.client.Get(t.ctx, key, &c); err != nil {
diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go
index 045f93a..ac33930 100644
--- a/pkg/trait/knative.go
+++ b/pkg/trait/knative.go
@@ -19,8 +19,6 @@ package trait
 
 import (
 	"fmt"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-
 	"github.com/apache/camel-k/pkg/util/envvar"
 
 	"strconv"
@@ -37,6 +35,7 @@ import (
 	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const (
@@ -414,7 +413,7 @@ func (t *knativeTrait) retrieveChannel(namespace string, name string) (*eventing
 			Name:      name,
 		},
 	}
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: namespace,
 		Name:      name,
 	}
diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go
index 3309679..df773e4 100644
--- a/pkg/trait/trait.go
+++ b/pkg/trait/trait.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"github.com/pkg/errors"
 	"k8s.io/api/core/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 )
 
 // True --
diff --git a/pkg/trait/types.go b/pkg/trait/types.go
index 84752ee..8b48645 100644
--- a/pkg/trait/types.go
+++ b/pkg/trait/types.go
@@ -21,11 +21,10 @@ import (
 	"context"
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/builder"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/apache/camel-k/pkg/platform"
 	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"k8s.io/api/core/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
 )
 
 // Identifiable represent an identifiable type
@@ -39,7 +38,7 @@ type ID string
 // Trait is the interface of all traits
 type Trait interface {
 	Identifiable
-	inject.Client
+	client.Injectable
 
 	// InjectContext to inject a context
 	InjectContext(context.Context)
@@ -67,9 +66,8 @@ func (trait *BaseTrait) ID() ID {
 }
 
 // InjectClient implements client.ClientInject and allows to inject a client into the trait
-func (trait *BaseTrait) InjectClient(c client.Client) error {
+func (trait *BaseTrait) InjectClient(c client.Client) {
 	trait.client = c
-	return nil
 }
 
 // InjectContext allows to inject a context into the trait
diff --git a/pkg/trait/util.go b/pkg/trait/util.go
index 08079b1..14554e7 100644
--- a/pkg/trait/util.go
+++ b/pkg/trait/util.go
@@ -22,20 +22,21 @@ import (
 	"strings"
 
 	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // GetIntegrationContext retrieves the context set on the integration
 func GetIntegrationContext(ctx context.Context, c client.Client, integration *v1alpha1.Integration) (*v1alpha1.IntegrationContext, error) {
-	if integration.Status.Context== "" {
+	if integration.Status.Context == "" {
 		return nil, nil
 	}
 
 	name := integration.Status.Context
 	ictx := v1alpha1.NewIntegrationContext(integration.Namespace, name)
-	key := client.ObjectKey{
+	key := k8sclient.ObjectKey{
 		Namespace: integration.Namespace,
-		Name: name,
+		Name:      name,
 	}
 	err := c.Get(ctx, key, &ictx)
 	return &ictx, err
diff --git a/pkg/util/kubernetes/config.go b/pkg/util/kubernetes/config.go
deleted file mode 100644
index f2a0105..0000000
--- a/pkg/util/kubernetes/config.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package kubernetes
-
-import (
-	"os"
-	"os/user"
-	"path/filepath"
-
-	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
-)
-
-// InitKubeClient initialize the k8s client
-func InitKubeClient(kubeconfig string) error {
-	if kubeconfig == "" {
-		kubeconfig = getDefaultKubeConfigFile()
-	}
-	os.Setenv(k8sutil.KubeConfigEnvVar, kubeconfig)
-	return nil
-}
-
-func getDefaultKubeConfigFile() string {
-	usr, err := user.Current()
-	if err != nil {
-		panic(err) // TODO handle error
-	}
-
-	return filepath.Join(usr.HomeDir, ".kube", "config")
-}
diff --git a/pkg/util/kubernetes/converter.go b/pkg/util/kubernetes/converter.go
deleted file mode 100644
index 0fa23dd..0000000
--- a/pkg/util/kubernetes/converter.go
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package kubernetes
-
-import (
-	"errors"
-	"k8s.io/client-go/kubernetes"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-// AsKubernetesClient converts a controller-runtime Client into a Kubernetes client
-func AsKubernetesClient(c client.Client) (kubernetes.Interface, error) {
-	if k, ok := c.(kubernetes.Interface); ok {
-		return k, nil
-	}
-	return nil, errors.New("client is not a kubernetes client")
-}
diff --git a/pkg/util/kubernetes/namespace.go b/pkg/util/kubernetes/namespace.go
deleted file mode 100644
index 664330c..0000000
--- a/pkg/util/kubernetes/namespace.go
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package kubernetes
-
-import (
-	"io/ioutil"
-
-	"github.com/pkg/errors"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/client-go/tools/clientcmd"
-	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
-	clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
-)
-
-// GetClientCurrentNamespace --
-func GetClientCurrentNamespace(kubeconfig string) (string, error) {
-	if kubeconfig == "" {
-		kubeconfig = getDefaultKubeConfigFile()
-	}
-	if kubeconfig == "" {
-		return "default", nil
-	}
-
-	data, err := ioutil.ReadFile(kubeconfig)
-	if err != nil {
-		return "", err
-	}
-	config := clientcmdapi.NewConfig()
-	if len(data) == 0 {
-		return "", errors.New("kubernetes config file is empty")
-	}
-
-	decoded, _, err := clientcmdlatest.Codec.Decode(data, &schema.GroupVersionKind{Version: clientcmdlatest.Version, Kind: "Config"}, config)
-	if err != nil {
-		return "", err
-	}
-
-	clientcmdconfig := decoded.(*clientcmdapi.Config)
-
-	cc := clientcmd.NewDefaultClientConfig(*clientcmdconfig, &clientcmd.ConfigOverrides{})
-	ns, _, err := cc.Namespace()
-	return ns, err
-}
diff --git a/pkg/util/kubernetes/replace.go b/pkg/util/kubernetes/replace.go
index 44411ac..09e6e9b 100644
--- a/pkg/util/kubernetes/replace.go
+++ b/pkg/util/kubernetes/replace.go
@@ -19,6 +19,7 @@ package kubernetes
 
 import (
 	"context"
+	"github.com/apache/camel-k/pkg/client"
 	eventing "github.com/knative/eventing/pkg/apis/eventing/v1alpha1"
 	routev1 "github.com/openshift/api/route/v1"
 	"github.com/pkg/errors"
@@ -26,7 +27,7 @@ import (
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // ReplaceResources allows to completely replace a list of resources on Kubernetes, taking care of immutable fields and resource versions
@@ -45,7 +46,7 @@ func ReplaceResource(ctx context.Context, c client.Client, res runtime.Object) e
 	err := c.Create(ctx, res)
 	if err != nil && k8serrors.IsAlreadyExists(err) {
 		existing := res.DeepCopyObject()
-		key, err := client.ObjectKeyFromObject(existing)
+		key, err := k8sclient.ObjectKeyFromObject(existing)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/util/kubernetes/wait.go b/pkg/util/kubernetes/wait.go
index dee63be..e4895d7 100644
--- a/pkg/util/kubernetes/wait.go
+++ b/pkg/util/kubernetes/wait.go
@@ -21,9 +21,10 @@ import (
 	"context"
 	"time"
 
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/pkg/errors"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // ResourceRetrieveFunction --
@@ -39,7 +40,7 @@ const (
 // WaitCondition --
 func WaitCondition(ctx context.Context, c client.Client, obj runtime.Object, condition ResourceCheckFunction, maxDuration time.Duration) error {
 	start := time.Now()
-	key, err := client.ObjectKeyFromObject(obj)
+	key, err := k8sclient.ObjectKeyFromObject(obj)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/util/minishift/minishift.go b/pkg/util/minishift/minishift.go
index 4ef1bae..ae6ebdc 100644
--- a/pkg/util/minishift/minishift.go
+++ b/pkg/util/minishift/minishift.go
@@ -20,12 +20,13 @@ package minishift
 
 import (
 	"context"
+	"github.com/apache/camel-k/pkg/client"
 	"k8s.io/apimachinery/pkg/labels"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"strconv"
 
 	"k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const (
@@ -40,7 +41,7 @@ func FindRegistry(ctx context.Context, c client.Client) (*string, error) {
 			Kind:       "Service",
 		},
 	}
-	options := client.ListOptions{
+	options := k8sclient.ListOptions{
 		LabelSelector: labels.SelectorFromSet(labels.Set{
 			"kubernetes.io/minikube-addons": "registry",
 		}),
diff --git a/script/Makefile b/script/Makefile
index a86b9bb..a3815f7 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -3,7 +3,7 @@ build: build-runtime build-operator build-kamel build-compile-integration-tests
 build-go: build-embed-resources build-operator build-kamel
 
 build-operator: build-embed-resources
-	go build -o camel-k ./cmd/camel-k/*.go
+	go build -o camel-k ./cmd/manager/*.go
 
 build-kamel:
 	go build -o kamel ./cmd/kamel/*.go
@@ -47,10 +47,8 @@ clean:
 	go clean
 	rm -f camel-k
 	rm -f kamel
-	rm -rf tmp/_maven_output
-
-codegen:
-	./tmp/codegen/update-generated.sh
+	rm -rf build/_maven_output
+	rm -rf build/_output
 
 images: images-build
 
diff --git a/script/package_maven_artifacts.sh b/script/package_maven_artifacts.sh
index a7502c0..0454a7d 100755
--- a/script/package_maven_artifacts.sh
+++ b/script/package_maven_artifacts.sh
@@ -2,4 +2,4 @@
 
 location=$(dirname $0)
 cd $location/../
-./mvnw clean install -DskipTests -f runtime/pom.xml -s tmp/maven/settings.xml
+./mvnw clean install -DskipTests -f runtime/pom.xml -s build/maven/settings.xml
diff --git a/script/travis_build.sh b/script/travis_build.sh
index f7fa832..2b16d3c 100755
--- a/script/travis_build.sh
+++ b/script/travis_build.sh
@@ -56,7 +56,7 @@ echo "Adding maven artifacts to the image context"
 
 echo "Copying binary file to docker dir"
 mkdir -p ./tmp/_output/bin
-cp ./camel-k ./tmp/_output/bin/
+cp ./camel-k ./build/_output/bin/
 
 echo "Building the images"
 export IMAGE=docker.io/apache/camel-k:$(./script/get_version.sh)
diff --git a/test/log_scrape_integration_test.go b/test/log_scrape_integration_test.go
index 70f074d..9a74b57 100644
--- a/test/log_scrape_integration_test.go
+++ b/test/log_scrape_integration_test.go
@@ -23,7 +23,6 @@ package test
 
 import (
 	"context"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
 	"strings"
 	"testing"
 	"time"
@@ -40,9 +39,7 @@ func TestPodLogScrape(t *testing.T) {
 
 	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(30*time.Second))
 	defer cancel()
-	kc, err := kubernetes.AsKubernetesClient(testClient)
-	assert.Nil(t, err)
-	scraper := log.NewPodScraper(kc, pod.Namespace, pod.Name)
+	scraper := log.NewPodScraper(testClient, pod.Namespace, pod.Name)
 	in := scraper.Start(ctx)
 
 	res := make(chan bool)
@@ -77,9 +74,7 @@ func TestSelectorLogScrape(t *testing.T) {
 
 	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(30*time.Second))
 	defer cancel()
-	kc, err := kubernetes.AsKubernetesClient(testClient)
-	assert.Nil(t, err)
-	scraper := log.NewSelectorScraper(kc, deployment.Namespace, "scrape=me")
+	scraper := log.NewSelectorScraper(testClient, deployment.Namespace, "scrape=me")
 	in := scraper.Start(ctx)
 
 	res := make(chan string)
diff --git a/test/testing_env.go b/test/testing_env.go
index f8df4c5..5218590 100644
--- a/test/testing_env.go
+++ b/test/testing_env.go
@@ -23,29 +23,25 @@ package test
 
 import (
 	"context"
-	"github.com/apache/camel-k/pkg/client/cmd"
 	"k8s.io/apimachinery/pkg/labels"
 	"time"
 
+	"github.com/apache/camel-k/pkg/client"
 	"github.com/apache/camel-k/pkg/install"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/api/core/v1"
 	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 var testContext context.Context
 var testClient client.Client
 
 func init() {
-	// Initializes the kubernetes client to auto-detect the context
-	kubernetes.InitKubeClient("")
-
 	testContext = context.TODO()
 	var err error
-	testClient, err = cmd.NewCmdClient(getTargetNamespace())
+	testClient, err = client.NewOutOfClusterClient("", getTargetNamespace())
 	if err != nil {
 		panic(err)
 	}
@@ -62,7 +58,7 @@ func init() {
 }
 
 func getTargetNamespace() string {
-	ns, err := kubernetes.GetClientCurrentNamespace("")
+	ns, err := client.GetCurrentNamespace("")
 	if err != nil {
 		panic(err)
 	}
@@ -71,7 +67,7 @@ func getTargetNamespace() string {
 
 func createDummyDeployment(name string, replicas *int32, labelKey string, labelValue string, command ...string) (*appsv1.Deployment, error) {
 	deployment := getDummyDeployment(name, replicas, labelKey, labelValue, command...)
-	err := testClient.Delete(testContext, &deployment, client.GracePeriodSeconds(0))
+	err := testClient.Delete(testContext, &deployment, k8sclient.GracePeriodSeconds(0))
 	if err != nil && !k8serrors.IsNotFound(err) {
 		return nil, err
 	}
@@ -82,7 +78,7 @@ func createDummyDeployment(name string, replicas *int32, labelKey string, labelV
 				APIVersion: v1.SchemeGroupVersion.String(),
 			},
 		}
-		options := client.ListOptions{
+		options := k8sclient.ListOptions{
 			Namespace: getTargetNamespace(),
 			LabelSelector: labels.SelectorFromSet(labels.Set{
 				labelKey: labelValue,
@@ -134,7 +130,7 @@ func getDummyDeployment(name string, replicas *int32, labelKey string, labelValu
 
 func createDummyPod(name string, command ...string) (*v1.Pod, error) {
 	pod := getDummyPod(name, command...)
-	err := testClient.Delete(testContext, &pod, client.GracePeriodSeconds(0))
+	err := testClient.Delete(testContext, &pod, k8sclient.GracePeriodSeconds(0))
 	if err != nil && !k8serrors.IsNotFound(err) {
 		return nil, err
 	}
diff --git a/tmp/build/Dockerfile b/tmp/build/Dockerfile
deleted file mode 100644
index f0952d4..0000000
--- a/tmp/build/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-FROM fabric8/s2i-java:2.3
-
-#RUN adduser -D camel-k
-#USER camel-k
-
-ADD tmp/_maven_output /tmp/artifacts/m2
-
-ADD tmp/_output/bin/camel-k /usr/local/bin/camel-k
-
-USER 0
-RUN chgrp -R 0 /tmp/artifacts/m2 \
- && chmod -R g=u /tmp/artifacts/m2
-
-USER 1000
diff --git a/tmp/build/build.sh b/tmp/build/build.sh
deleted file mode 100755
index 6755c89..0000000
--- a/tmp/build/build.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-
-set -o errexit
-set -o nounset
-set -o pipefail
-
-if ! which go > /dev/null; then
-	echo "golang needs to be installed"
-	exit 1
-fi
-
-BIN_DIR="$(pwd)/tmp/_output/bin"
-mkdir -p ${BIN_DIR}
-PROJECT_NAME="camel-k"
-REPO_PATH="github.com/apache/camel-k"
-BUILD_PATH="${REPO_PATH}/cmd/${PROJECT_NAME}"
-echo "building "${PROJECT_NAME}"..."
-GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ${BIN_DIR}/${PROJECT_NAME} $BUILD_PATH
diff --git a/tmp/build/docker_build.sh b/tmp/build/docker_build.sh
deleted file mode 100755
index da98858..0000000
--- a/tmp/build/docker_build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env bash
-
-if ! which docker > /dev/null; then
-	echo "docker needs to be installed"
-	exit 1
-fi
-
-: ${IMAGE:?"Need to set IMAGE, e.g. gcr.io/<repo>/<your>-operator"}
-
-echo "building container ${IMAGE}..."
-docker build -t "${IMAGE}" -f tmp/build/Dockerfile .
diff --git a/tmp/codegen/boilerplate.go.txt b/tmp/codegen/boilerplate.go.txt
deleted file mode 100644
index c61bcc7..0000000
--- a/tmp/codegen/boilerplate.go.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
diff --git a/tmp/codegen/update-generated.sh b/tmp/codegen/update-generated.sh
deleted file mode 100755
index 060b628..0000000
--- a/tmp/codegen/update-generated.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-
-set -o errexit
-set -o nounset
-set -o pipefail
-
-vendor/k8s.io/code-generator/generate-groups.sh \
-deepcopy \
-github.com/apache/camel-k/pkg/generated \
-github.com/apache/camel-k/pkg/apis \
-camel:v1alpha1 \
---go-header-file "./tmp/codegen/boilerplate.go.txt"