diff --git a/cmd/tk/check.go b/cmd/tk/check.go
index b201c05f967ec3391b0d75c33e7631164334f9e3..6e6cceeaf8e36705752360b143bec1050c0ad587 100644
--- a/cmd/tk/check.go
+++ b/cmd/tk/check.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"os"
 	"os/exec"
 	"strings"
@@ -31,17 +32,20 @@ func init() {
 }
 
 func runCheckCmd(cmd *cobra.Command, args []string) error {
+	ctx, cancel := context.WithTimeout(context.Background(), timeout)
+	defer cancel()
+
 	logAction("starting verification")
 	checkFailed := false
 	if !sshCheck() {
 		checkFailed = true
 	}
 
-	if !kubectlCheck(">=1.18.0") {
+	if !kubectlCheck(ctx, ">=1.18.0") {
 		checkFailed = true
 	}
 
-	if !kustomizeCheck(">=3.5.0") {
+	if !kustomizeCheck(ctx, ">=3.5.0") {
 		checkFailed = true
 	}
 
@@ -79,14 +83,15 @@ func sshCheck() bool {
 	return ok
 }
 
-func kubectlCheck(version string) bool {
+func kubectlCheck(ctx context.Context, version string) bool {
 	_, err := exec.LookPath("kubectl")
 	if err != nil {
 		logFailure("kubectl not found")
 		return false
 	}
 
-	output, err := execCommand("kubectl version --client --short | awk '{ print $3 }'")
+	command := "kubectl version --client --short | awk '{ print $3 }'"
+	output, err := utils.execCommand(ctx, ModeCapture, command)
 	if err != nil {
 		logFailure("kubectl version can't be determined")
 		return false
@@ -108,21 +113,23 @@ func kubectlCheck(version string) bool {
 	return true
 }
 
-func kustomizeCheck(version string) bool {
+func kustomizeCheck(ctx context.Context, version string) bool {
 	_, err := exec.LookPath("kustomize")
 	if err != nil {
 		logFailure("kustomize not found")
 		return false
 	}
 
-	output, err := execCommand("kustomize version --short | awk '{ print $1 }' | cut -c2-")
+	command := "kustomize version --short | awk '{ print $1 }' | cut -c2-"
+	output, err := utils.execCommand(ctx, ModeCapture, command)
 	if err != nil {
 		logFailure("kustomize version can't be determined")
 		return false
 	}
 
 	if strings.Contains(output, "kustomize/") {
-		output, err = execCommand("kustomize version --short | awk '{ print $1 }' | cut -c12-")
+		command = "kustomize version --short | awk '{ print $1 }' | cut -c12-"
+		output, err = utils.execCommand(ctx, ModeCapture, command)
 		if err != nil {
 			logFailure("kustomize version can't be determined")
 			return false
@@ -146,7 +153,7 @@ func kustomizeCheck(version string) bool {
 }
 
 func kubernetesCheck(version string) bool {
-	client, err := kubernetesClient()
+	client, err := utils.kubeClient(kubeconfig)
 	if err != nil {
 		logFailure("kubernetes client initialization failed: %s", err.Error())
 		return false
diff --git a/cmd/tk/create_source.go b/cmd/tk/create_source.go
index 543a6777de8f90a38188ff9f57c27c2225919aed..656bbb90fb8c7918927831c542ed94ab25479128 100644
--- a/cmd/tk/create_source.go
+++ b/cmd/tk/create_source.go
@@ -5,11 +5,9 @@ import (
 	"bytes"
 	"context"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"net/url"
 	"os"
-	"os/exec"
 	"strings"
 	"text/template"
 
@@ -44,7 +42,6 @@ var (
 	sourceGitSemver string
 	sourceUsername  string
 	sourcePassword  string
-	sourceVerbose   bool
 )
 
 func init() {
@@ -53,7 +50,6 @@ func init() {
 	createSourceCmd.Flags().StringVar(&sourceGitSemver, "git-semver", "", "git tag semver range")
 	createSourceCmd.Flags().StringVarP(&sourceUsername, "username", "u", "", "basic authentication username")
 	createSourceCmd.Flags().StringVarP(&sourcePassword, "password", "p", "", "basic authentication password")
-	createSourceCmd.Flags().BoolVarP(&sourceVerbose, "verbose", "", false, "print generated source object")
 
 	createCmd.AddCommand(createSourceCmd)
 }
@@ -84,12 +80,12 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
 
 	withAuth := false
 	if strings.HasPrefix(sourceGitURL, "ssh") {
-		if err := generateSSH(name, u.Host, tmpDir); err != nil {
+		if err := generateSSH(ctx, name, u.Host, tmpDir); err != nil {
 			return err
 		}
 		withAuth = true
 	} else if sourceUsername != "" && sourcePassword != "" {
-		if err := generateBasicAuth(name); err != nil {
+		if err := generateBasicAuth(ctx, name); err != nil {
 			return err
 		}
 		withAuth = true
@@ -129,69 +125,59 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("source flush failed: %w", err)
 	}
 
-	if sourceVerbose {
+	if verbose {
 		fmt.Print(data.String())
 	}
 
 	command := fmt.Sprintf("echo '%s' | kubectl apply -f-", data.String())
-	c := exec.CommandContext(ctx, "/bin/sh", "-c", command)
-
-	var stdoutBuf, stderrBuf bytes.Buffer
-	c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
-	c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
-
-	err = c.Run()
-	if err != nil {
+	if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
 		return fmt.Errorf("source apply failed")
 	}
 
 	logAction("waiting for source sync")
-	if output, err := execCommand(fmt.Sprintf(
-		"kubectl -n %s wait gitrepository/%s --for=condition=ready --timeout=1m",
-		namespace, name)); err != nil {
-		return fmt.Errorf("source sync failed: %s", output)
-	} else {
-		fmt.Print(output)
+	command = fmt.Sprintf("kubectl -n %s wait gitrepository/%s --for=condition=ready --timeout=1m",
+		namespace, name)
+	if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
+		return fmt.Errorf("source sync failed")
 	}
-
+	logSuccess("source %s is ready", name)
 	return nil
 }
 
-func generateBasicAuth(name string) error {
+func generateBasicAuth(ctx context.Context, name string) error {
 	logAction("saving credentials")
 	credentials := fmt.Sprintf("--from-literal=username='%s' --from-literal=password='%s'",
 		sourceUsername, sourcePassword)
 	secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
 		namespace, name, credentials)
-	if output, err := execCommand(secret); err != nil {
-		return fmt.Errorf("kubectl create secret failed: %s", output)
-	} else {
-		fmt.Print(output)
+	if _, err := utils.execCommand(ctx, ModeOS, secret); err != nil {
+		return fmt.Errorf("kubectl create secret failed")
 	}
 	return nil
 }
 
-func generateSSH(name, host, tmpDir string) error {
+func generateSSH(ctx context.Context, name, host, tmpDir string) error {
 	logAction("generating host key for %s", host)
 
-	keyscan := fmt.Sprintf("ssh-keyscan %s > %s/known_hosts", host, tmpDir)
-	if output, err := execCommand(keyscan); err != nil {
-		return fmt.Errorf("ssh-keyscan failed: %s", output)
+	command := fmt.Sprintf("ssh-keyscan %s > %s/known_hosts", host, tmpDir)
+	if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
+		return fmt.Errorf("ssh-keyscan failed")
 	}
 
 	logAction("generating deploy key")
 
-	keygen := fmt.Sprintf("ssh-keygen -b 2048 -t rsa -f %s/identity -q -N \"\"", tmpDir)
-	if output, err := execCommand(keygen); err != nil {
-		return fmt.Errorf("ssh-keygen failed: %s", output)
+	command = fmt.Sprintf("ssh-keygen -b 2048 -t rsa -f %s/identity -q -N \"\"", tmpDir)
+	if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
+		return fmt.Errorf("ssh-keygen failed")
 	}
 
-	deployKey, err := execCommand(fmt.Sprintf("cat %s/identity.pub", tmpDir))
-	if err != nil {
+	command = fmt.Sprintf("cat %s/identity.pub", tmpDir)
+	if deployKey, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
 		return fmt.Errorf("unable to read identity.pub: %w", err)
+	} else {
+		fmt.Print(deployKey)
 	}
 
-	fmt.Print(deployKey)
 	prompt := promptui.Prompt{
 		Label:     "Have you added the deploy key to your repository",
 		IsConfirm: true,
@@ -206,10 +192,8 @@ func generateSSH(name, host, tmpDir string) error {
 		tmpDir, tmpDir, tmpDir)
 	secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
 		namespace, name, files)
-	if output, err := execCommand(secret); err != nil {
-		return fmt.Errorf("kubectl create secret failed: %s", output)
-	} else {
-		fmt.Print(output)
+	if _, err := utils.execCommand(ctx, ModeOS, secret); err != nil {
+		return fmt.Errorf("create secret failed")
 	}
 	return nil
 }
diff --git a/cmd/tk/install.go b/cmd/tk/install.go
index 17ea41dfe5c425ea050297dc8c45418eb60a2dd3..3cda8504599facedb82cac7fd9dfa3e951a1bbee 100644
--- a/cmd/tk/install.go
+++ b/cmd/tk/install.go
@@ -1,17 +1,12 @@
 package main
 
 import (
-	"bufio"
-	"bytes"
 	"context"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"os"
-	"os/exec"
 	"path"
 	"strings"
-	"text/template"
 
 	"github.com/spf13/cobra"
 )
@@ -43,7 +38,10 @@ func init() {
 }
 
 func installCmdRun(cmd *cobra.Command, args []string) error {
-	kustomizePath := ""
+	ctx, cancel := context.WithTimeout(context.Background(), timeout)
+	defer cancel()
+
+	var kustomizePath string
 	if installVersion == "" && !strings.HasPrefix(installManifestsPath, "github.com/") {
 		if _, err := os.Stat(installManifestsPath); err != nil {
 			return fmt.Errorf("manifests not found: %w", err)
@@ -57,52 +55,61 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
 	}
 	defer os.RemoveAll(tmpDir)
 
+	logAction("generating install manifests")
 	if kustomizePath == "" {
-		err = generateInstall(tmpDir)
+		err = genInstallManifests(installVersion, namespace, tmpDir)
 		if err != nil {
-			return err
+			return fmt.Errorf("install failed: %w", err)
 		}
 		kustomizePath = tmpDir
 	}
 
-	ctx, cancel := context.WithTimeout(context.Background(), timeout)
-	defer cancel()
+	manifest := path.Join(tmpDir, fmt.Sprintf("%s.yaml", namespace))
+	command := fmt.Sprintf("kustomize build %s > %s", kustomizePath, manifest)
+	if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
+		return fmt.Errorf("install failed")
+	}
+
+	command = fmt.Sprintf("cat %s", manifest)
+	if yaml, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
+		return fmt.Errorf("install failed: %w", err)
+	} else {
+		if verbose {
+			fmt.Print(yaml)
+		}
+	}
+	logSuccess("build completed")
 
+	logAction("installing components in %s namespace", namespace)
+	applyOutput := ModeStderrOS
+	if verbose {
+		applyOutput = ModeOS
+	}
 	dryRun := ""
 	if installDryRun {
 		dryRun = "--dry-run=client"
+		applyOutput = ModeOS
 	}
-	command := fmt.Sprintf("kustomize build %s | kubectl apply -f- %s",
-		kustomizePath, dryRun)
-	c := exec.CommandContext(ctx, "/bin/sh", "-c", command)
-
-	var stdoutBuf, stderrBuf bytes.Buffer
-	c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
-	c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
-
-	logAction("installing components in %s namespace", namespace)
-	err = c.Run()
-	if err != nil {
-		logFailure("install failed")
-		os.Exit(1)
+	command = fmt.Sprintf("cat %s | kubectl apply -f- %s", manifest, dryRun)
+	if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
+		return fmt.Errorf("install failed")
 	}
 
 	if installDryRun {
 		logSuccess("install dry-run finished")
 		return nil
+	} else {
+		logSuccess("install completed")
 	}
 
 	logAction("verifying installation")
 	for _, deployment := range []string{"source-controller", "kustomize-controller"} {
 		command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
 			namespace, deployment, timeout.String())
-		c = exec.CommandContext(ctx, "/bin/sh", "-c", command)
-		c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
-		c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
-		err := c.Run()
-		if err != nil {
-			logFailure("install failed")
-			os.Exit(1)
+		if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
+			return fmt.Errorf("install failed")
+		} else {
+			logSuccess("%s ready", deployment)
 		}
 	}
 
@@ -114,7 +121,7 @@ var namespaceTmpl = `---
 apiVersion: v1
 kind: Namespace
 metadata:
-  name: {{.}}
+  name: {{.Namespace}}
 `
 
 var labelsTmpl = `---
@@ -123,7 +130,8 @@ kind: LabelTransformer
 metadata:
   name: labels
 labels:
-  app.kubernetes.io/instance: {{.}}
+  app.kubernetes.io/instance: {{.Namespace}}
+  app.kubernetes.io/version: "{{.Version}}"
 fieldSpecs:
   - path: metadata/labels
     create: true
@@ -151,102 +159,34 @@ resources:
 nameSuffix: -{{.Namespace}}
 `
 
-func generateInstall(tmpDir string) error {
-	logAction("generating install manifests for %s namespace", namespace)
-
-	nst, err := template.New("tmpl").Parse(namespaceTmpl)
-	if err != nil {
-		return fmt.Errorf("template parse error: %w", err)
-	}
-
-	ns, err := execTemplate(nst, namespace)
-	if err != nil {
-		return err
-	}
-
-	if err := writeToFile(path.Join(tmpDir, "namespace.yaml"), ns); err != nil {
-		return err
-	}
-
-	labelst, err := template.New("tmpl").Parse(labelsTmpl)
-	if err != nil {
-		return fmt.Errorf("template parse error: %w", err)
-	}
-
-	labels, err := execTemplate(labelst, namespace)
-	if err != nil {
-		return err
-	}
-
-	if err := writeToFile(path.Join(tmpDir, "labels.yaml"), labels); err != nil {
-		return err
-	}
-
+func genInstallManifests(ver, ns, tmpDir string) error {
 	model := struct {
 		Version   string
 		Namespace string
 	}{
-		Version:   installVersion,
-		Namespace: namespace,
-	}
-
-	kt, err := template.New("tmpl").Parse(kustomizationTmpl)
-	if err != nil {
-		return fmt.Errorf("template parse error: %w", err)
+		Version:   ver,
+		Namespace: ns,
 	}
 
-	k, err := execTemplate(kt, model)
-	if err != nil {
-		return err
-	}
-
-	if err := writeToFile(path.Join(tmpDir, "kustomization.yaml"), k); err != nil {
-		return err
+	if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil {
+		return fmt.Errorf("generate namespace failed: %w", err)
 	}
 
-	krt, err := template.New("tmpl").Parse(kustomizationRolesTmpl)
-	if err != nil {
-		return fmt.Errorf("template parse error: %w", err)
+	if err := utils.execTemplate(model, labelsTmpl, path.Join(tmpDir, "labels.yaml")); err != nil {
+		return fmt.Errorf("generate labels failed: %w", err)
 	}
 
-	kr, err := execTemplate(krt, model)
-	if err != nil {
-		return err
+	if err := utils.execTemplate(model, kustomizationTmpl, path.Join(tmpDir, "kustomization.yaml")); err != nil {
+		return fmt.Errorf("generate kustomization failed: %w", err)
 	}
 
 	if err := os.MkdirAll(path.Join(tmpDir, "roles"), os.ModePerm); err != nil {
-		return err
+		return fmt.Errorf("generate roles failed: %w", err)
 	}
 
-	if err := writeToFile(path.Join(tmpDir, "roles/kustomization.yaml"), kr); err != nil {
-		return err
+	if err := utils.execTemplate(model, kustomizationRolesTmpl, path.Join(tmpDir, "roles/kustomization.yaml")); err != nil {
+		return fmt.Errorf("generate roles failed: %w", err)
 	}
 
 	return nil
 }
-
-func execTemplate(t *template.Template, obj interface{}) (string, error) {
-	var data bytes.Buffer
-	writer := bufio.NewWriter(&data)
-	if err := t.Execute(writer, obj); err != nil {
-		return "", fmt.Errorf("template execution failed: %w", err)
-	}
-	if err := writer.Flush(); err != nil {
-		return "", fmt.Errorf("template flush failed: %w", err)
-	}
-	return data.String(), nil
-}
-
-func writeToFile(filename string, data string) error {
-	file, err := os.Create(filename)
-	if err != nil {
-		return err
-	}
-	defer file.Close()
-
-	_, err = io.WriteString(file, data)
-	if err != nil {
-		return err
-	}
-	return file.Sync()
-}
diff --git a/cmd/tk/main.go b/cmd/tk/main.go
index b6b5797fc2ff32d372db7b67865301fc94c1ec96..68a954b31ccc410731c0eef16b252975c1cca902 100644
--- a/cmd/tk/main.go
+++ b/cmd/tk/main.go
@@ -4,15 +4,12 @@ import (
 	"fmt"
 	"log"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"time"
 
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra/doc"
-	"k8s.io/client-go/kubernetes"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
-	"k8s.io/client-go/tools/clientcmd"
 )
 
 var VERSION = "0.0.1"
@@ -30,6 +27,8 @@ var (
 	kubeconfig string
 	namespace  string
 	timeout    time.Duration
+	verbose    bool
+	utils      Utils
 )
 
 func init() {
@@ -37,6 +36,8 @@ func init() {
 		"the namespace scope for this operation")
 	rootCmd.PersistentFlags().DurationVarP(&timeout, "timeout", "", 5*time.Minute,
 		"timeout for this operation")
+	rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
+		"print generated objects")
 }
 
 func main() {
@@ -56,29 +57,6 @@ func homeDir() string {
 	return os.Getenv("USERPROFILE") // windows
 }
 
-func kubernetesClient() (*kubernetes.Clientset, error) {
-	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
-	if err != nil {
-		return nil, err
-	}
-
-	client, err := kubernetes.NewForConfig(config)
-	if err != nil {
-		return nil, err
-	}
-
-	return client, nil
-}
-
-func execCommand(command string) (string, error) {
-	c := exec.Command("/bin/sh", "-c", command)
-	output, err := c.CombinedOutput()
-	if err != nil {
-		return "", err
-	}
-	return string(output), nil
-}
-
 func logAction(format string, a ...interface{}) {
 	fmt.Println(`✚`, fmt.Sprintf(format, a...))
 }
diff --git a/cmd/tk/uninstall.go b/cmd/tk/uninstall.go
index aeea68cff02ea72ef4a45d70fa09e4dc8e685d9c..e956cf223afbb120f5c95b4005cbed520297b05d 100644
--- a/cmd/tk/uninstall.go
+++ b/cmd/tk/uninstall.go
@@ -1,12 +1,8 @@
 package main
 
 import (
-	"bytes"
 	"context"
 	"fmt"
-	"io"
-	"os"
-	"os/exec"
 
 	"github.com/manifoldco/promptui"
 	"github.com/spf13/cobra"
@@ -49,8 +45,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
 			IsConfirm: true,
 		}
 		if _, err := prompt.Run(); err != nil {
-			logFailure("aborting")
-			os.Exit(1)
+			return fmt.Errorf("aborting")
 		}
 	}
 
@@ -59,19 +54,11 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
 		kinds += ",crds"
 	}
 
+	logAction("uninstalling components")
 	command := fmt.Sprintf("kubectl delete %s -l app.kubernetes.io/instance=%s --timeout=%s %s",
 		kinds, namespace, timeout.String(), dryRun)
-	c := exec.CommandContext(ctx, "/bin/sh", "-c", command)
-
-	var stdoutBuf, stderrBuf bytes.Buffer
-	c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
-	c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
-
-	logAction("uninstalling components")
-	err := c.Run()
-	if err != nil {
-		logFailure("uninstall failed")
-		os.Exit(1)
+	if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
+		return fmt.Errorf("uninstall failed")
 	}
 
 	logSuccess("uninstall finished")
diff --git a/cmd/tk/utils.go b/cmd/tk/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..0bb511b37d2046eb05683c002eacff424c781ada
--- /dev/null
+++ b/cmd/tk/utils.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"context"
+	"io"
+	"os"
+	"os/exec"
+	"text/template"
+
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/tools/clientcmd"
+)
+
+type Utils struct {
+}
+
+type ExecMode string
+
+const (
+	ModeOS       ExecMode = "os.stderr|stdout"
+	ModeStderrOS ExecMode = "os.stderr"
+	ModeCapture  ExecMode = "capture.stderr|stdout"
+)
+
+func (*Utils) execCommand(ctx context.Context, mode ExecMode, command string) (string, error) {
+	var stdoutBuf, stderrBuf bytes.Buffer
+	c := exec.CommandContext(ctx, "/bin/sh", "-c", command)
+
+	if mode == ModeStderrOS {
+		c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
+	}
+	if mode == ModeOS {
+		c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
+		c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
+	}
+
+	if mode == ModeStderrOS || mode == ModeOS {
+		if err := c.Run(); err != nil {
+			return "", err
+		} else {
+			return "", nil
+		}
+	}
+
+	if mode == ModeCapture {
+		if output, err := c.CombinedOutput(); err != nil {
+			return "", err
+		} else {
+			return string(output), nil
+		}
+	}
+
+	return "", nil
+}
+
+func (*Utils) execTemplate(obj interface{}, tmpl, filename string) error {
+	t, err := template.New("tmpl").Parse(tmpl)
+	if err != nil {
+		return err
+	}
+
+	var data bytes.Buffer
+	writer := bufio.NewWriter(&data)
+	if err := t.Execute(writer, obj); err != nil {
+		return err
+	}
+
+	if err := writer.Flush(); err != nil {
+		return err
+	}
+
+	file, err := os.Create(filename)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	_, err = io.WriteString(file, data.String())
+	if err != nil {
+		return err
+	}
+
+	return file.Sync()
+}
+
+func (*Utils) kubeClient(config string) (*kubernetes.Clientset, error) {
+	cfg, err := clientcmd.BuildConfigFromFlags("", config)
+	if err != nil {
+		return nil, err
+	}
+
+	client, err := kubernetes.NewForConfig(cfg)
+	if err != nil {
+		return nil, err
+	}
+
+	return client, nil
+}
diff --git a/go.mod b/go.mod
index 826f06896bea71892f4da0ec384f672c0bbe91c2..29c9b45717034050e160157d49d99bc0797a620b 100644
--- a/go.mod
+++ b/go.mod
@@ -6,5 +6,5 @@ require (
 	github.com/blang/semver v3.5.1+incompatible
 	github.com/manifoldco/promptui v0.7.0
 	github.com/spf13/cobra v0.0.6
-	k8s.io/client-go v0.18.0
+	k8s.io/client-go v0.18.2
 )
diff --git a/go.sum b/go.sum
index eb16da427d43e0a974e51d6f70b6f39638b5da87..cb09b154ef2b57fc89777f432c443d0e92d4b861 100644
--- a/go.sum
+++ b/go.sum
@@ -298,12 +298,12 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ=
-k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
-k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
-k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
-k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
-k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
+k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
+k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
+k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA=
+k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
+k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE=
+k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=