Repository: fission/fission
Pull request #2604 (2022-11-04 11:32:11)

List fission resources in specific namespace instead of all namespace
<!--  Thanks for sending a pull request! We request you provide detailed description as much as possible. -->

## Description
<!--- Describe your changes in detail. -->
<!-- Typically try to give details of what, why and how of the PR changes. -->

## Which issue(s) this PR fixes:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
Fixes #

## Testing
Created two environment in go. One in default namespace and second in testns1 namespace.
Created 1 pool manager executor type function in each environment.
Verified that all the deployment, services etc for function created inside testns1 namespace, were created inside testns1 namespace.
Tested both functions individually and verified that idle object reaper is reaping pods in their respective namespaces.

Created 1 newdeploy executor type function in each environment.
Tested both functions individually and verified that idle object reaper is reaping pods in their respective namespaces according to their idletimeout .

Performed same steps for python environment as well,

## Checklist:
<!-- Please tick following checkboxes as per your understanding. -->
- [ ] I ran tests as well as code linting locally to verify my changes. 
- [ ] I have done manual verification of my changes, changes working as expected.
- [ ] I have added new tests to cover my changes.
- [ ] My changes follow contributing guidelines of Fission.
- [ ] I have signed all of my commits.


codecov[bot]: # [Codecov](https://codecov.io/gh/fission/fission/pull/2604?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission) Report
> Merging [#2604](https://codecov.io/gh/fission/fission/pull/2604?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission) (228819f) into [main](https://codecov.io/gh/fission/fission/commit/261bf2497411b47ca87016ae0a3f67a2335a3d5e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission) (261bf24) will **decrease** coverage by `0.00%`.
> The diff coverage is `n/a`.

```diff
@@            Coverage Diff             @@
##             main    #2604      +/-   ##
==========================================
- Coverage   19.78%   19.77%   -0.01%     
==========================================
  Files          62       62              
  Lines        7001     6998       -3     
==========================================
- Hits         1385     1384       -1     
+ Misses       5510     5508       -2     
  Partials      106      106              
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `19.77% <ø> (-0.01%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/fission/fission/pull/2604?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission) | Coverage Δ | |
|---|---|---|
| [pkg/router/functionReferenceResolver.go](https://codecov.io/gh/fission/fission/pull/2604/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission#diff-cGtnL3JvdXRlci9mdW5jdGlvblJlZmVyZW5jZVJlc29sdmVyLmdv) | `0.00% <ø> (ø)` | |
| [pkg/utils/httpserver/server.go](https://codecov.io/gh/fission/fission/pull/2604/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission#diff-cGtnL3V0aWxzL2h0dHBzZXJ2ZXIvc2VydmVyLmdv) | `55.55% <0.00%> (-5.56%)` | :arrow_down: |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fission)


Patch:
diff --git a/cmd/fission-cli/app/app.go b/cmd/fission-cli/app/app.go
index 08da49f8..3bbbe9c9 100644
--- a/cmd/fission-cli/app/app.go
+++ b/cmd/fission-cli/app/app.go
@@ -14,10 +14,9 @@ limitations under the License.
 package app
 
 import (
+	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 
-	"github.com/fission/fission/pkg/controller/client"
-	"github.com/fission/fission/pkg/controller/client/rest"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra/helptemplate"
@@ -39,7 +38,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/console"
 	"github.com/fission/fission/pkg/fission-cli/flag"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 	_ "github.com/fission/fission/pkg/mqtrigger/messageQueue/kafka"
 )
 
@@ -61,19 +59,17 @@ func App() *cobra.Command {
 		PersistentPreRunE: wrapper.Wrapper(
 			func(input cli.Input) error {
 				console.Verbosity = input.Int(flagkey.Verbosity)
-
-				if input.IsSet(flagkey.ClientOnly) || input.IsSet(flagkey.PreCheckOnly) {
-					// TODO: use fake rest client for offline spec generation
-					cmd.SetClientset(client.MakeFakeClientset(nil))
-				} else {
-					serverUrl, err := util.GetServerURL(input)
-					if err != nil {
-						return err
-					}
-					restClient := rest.NewRESTClient(serverUrl)
-					cmd.SetClientset(client.MakeClientset(restClient))
+				clientOptions := cmd.ClientOptions{
+					KubeContext: input.String(flagkey.KubeContext),
 				}
-
+				// TODO: use fake rest client for offline spec generation
+				// if input.IsSet(flagkey.ClientOnly) || input.IsSet(flagkey.PreCheckOnly) {
+				// }
+				client, err := cmd.NewClient(clientOptions)
+				if err != nil {
+					return errors.Wrap(err, "failed to get fission client")
+				}
+				cmd.SetClientset(*client)
 				return nil
 			},
 		),
diff --git a/cmd/preupgradechecks/checks.go b/cmd/preupgradechecks/checks.go
index 36756dc5..ee76d68c 100644
--- a/cmd/preupgradechecks/checks.go
+++ b/cmd/preupgradechecks/checks.go
@@ -33,6 +33,7 @@ import (
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/crd"
 	"github.com/fission/fission/pkg/generated/clientset/versioned"
+	"github.com/fission/fission/pkg/utils"
 )
 
 type (
@@ -124,40 +125,41 @@ func (client *PreUpgradeTaskClient) VerifyFunctionSpecReferences(ctx context.Con
 
 	var err error
 	var fList *fv1.FunctionList
+	errs := &multierror.Error{}
 
-	for i := 0; i < maxRetries; i++ {
-		fList, err = client.fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
-		if err == nil {
-			break
+	for _, namespace := range utils.GetNamespaces() {
+		for i := 0; i < maxRetries; i++ {
+			fList, err = client.fissionClient.CoreV1().Functions(namespace).List(ctx, metav1.ListOptions{})
+			if err == nil {
+				break
+			}
 		}
-	}
-
-	if err != nil {
-		client.logger.Fatal("error listing functions after max retries",
-			zap.Error(err),
-			zap.Int("max_retries", maxRetries))
-	}
 
-	errs := &multierror.Error{}
+		if err != nil {
+			client.logger.Fatal("error listing functions after max retries",
+				zap.Error(err),
+				zap.Int("max_retries", maxRetries))
+		}
 
-	// check that all secrets, configmaps, packages are in the same namespace
-	for _, fn := range fList.Items {
-		secrets := fn.Spec.Secrets
-		for _, secret := range secrets {
-			if secret.Namespace != "" && secret.Namespace != fn.ObjectMeta.Namespace {
-				errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a secret : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, secret.Name, secret.Namespace))
+		// check that all secrets, configmaps, packages are in the same namespace
+		for _, fn := range fList.Items {
+			secrets := fn.Spec.Secrets
+			for _, secret := range secrets {
+				if secret.Namespace != "" && secret.Namespace != fn.ObjectMeta.Namespace {
+					errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a secret : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, secret.Name, secret.Namespace))
+				}
 			}
-		}
 
-		configmaps := fn.Spec.ConfigMaps
-		for _, configmap := range configmaps {
-			if configmap.Namespace != "" && configmap.Namespace != fn.ObjectMeta.Namespace {
-				errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a configmap : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, configmap.Name, configmap.Namespace))
+			configmaps := fn.Spec.ConfigMaps
+			for _, configmap := range configmaps {
+				if configmap.Namespace != "" && configmap.Namespace != fn.ObjectMeta.Namespace {
+					errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a configmap : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, configmap.Name, configmap.Namespace))
+				}
 			}
-		}
 
-		if fn.Spec.Package.PackageRef.Namespace != "" && fn.Spec.Package.PackageRef.Namespace != fn.ObjectMeta.Namespace {
-			errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a package : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, fn.Spec.Package.PackageRef.Name, fn.Spec.Package.PackageRef.Namespace))
+			if fn.Spec.Package.PackageRef.Namespace != "" && fn.Spec.Package.PackageRef.Namespace != fn.ObjectMeta.Namespace {
+				errs = multierror.Append(errs, fmt.Errorf("function : %s.%s cannot reference a package : %s in namespace : %s", fn.ObjectMeta.Name, fn.ObjectMeta.Namespace, fn.Spec.Package.PackageRef.Name, fn.Spec.Package.PackageRef.Namespace))
+			}
 		}
 	}
 
diff --git a/pkg/buildermgr/pkgwatcher.go b/pkg/buildermgr/pkgwatcher.go
index 732c5ac4..8d4d0e5a 100644
--- a/pkg/buildermgr/pkgwatcher.go
+++ b/pkg/buildermgr/pkgwatcher.go
@@ -200,7 +200,7 @@ func (pkgw *packageWatcher) build(ctx context.Context, srcpkg *fv1.Package) {
 			pkgw.logger.Info("starting package info update", zap.String("package_name", pkg.ObjectMeta.Name))
 
 			fnList, err := pkgw.fissionClient.CoreV1().
-				Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
+				Functions(pkg.Namespace).List(ctx, metav1.ListOptions{})
 			if err != nil {
 				e := "error getting function list"
 				pkgw.logger.Error(e, zap.Error(err))
diff --git a/pkg/controller/api.go b/pkg/controller/api.go
index 5d049f57..d99a2088 100644
--- a/pkg/controller/api.go
+++ b/pkg/controller/api.go
@@ -261,7 +261,7 @@ func (api *API) GetHandler() http.Handler {
 	r.HandleFunc("/proxy/{dbType}", api.FunctionLogsApiPost).Methods("POST")
 	r.HandleFunc("/proxy/storage/v1/archive", api.StorageServiceProxy)
 	r.HandleFunc("/proxy/logs/{function}", api.FunctionPodLogs).Methods("POST")
-	r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy)
+	r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy) // Deprecated
 	r.HandleFunc("/proxy/svcname", api.GetSvcName).Queries("application", "").Methods("GET")
 
 	r.Handle("/v2/apidocs.json", openAPI()).Methods("GET")
diff --git a/pkg/controller/client/v1/canaryconfig.go b/pkg/controller/client/v1/canaryconfig.go
index 189bf3d4..bbe43412 100644
--- a/pkg/controller/client/v1/canaryconfig.go
+++ b/pkg/controller/client/v1/canaryconfig.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 )
 
 type (
diff --git a/pkg/controller/client/v1/fake/fake_package.go b/pkg/controller/client/v1/fake/fake_package.go
index 9a4ade1c..01da4878 100644
--- a/pkg/controller/client/v1/fake/fake_package.go
+++ b/pkg/controller/client/v1/fake/fake_package.go
@@ -17,11 +17,10 @@ limitations under the License.
 package fake
 
 import (
-	v1 "github.com/fission/fission/pkg/controller/client/v1"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	v1 "github.com/fission/fission/pkg/controller/client/v1"
 )
 
 type (
diff --git a/pkg/controller/client/v1/fake/fake_timetrigger.go b/pkg/controller/client/v1/fake/fake_timetrigger.go
index a1c6eb6f..05fe9b5c 100644
--- a/pkg/controller/client/v1/fake/fake_timetrigger.go
+++ b/pkg/controller/client/v1/fake/fake_timetrigger.go
@@ -17,11 +17,10 @@ limitations under the License.
 package fake
 
 import (
-	v1 "github.com/fission/fission/pkg/controller/client/v1"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	v1 "github.com/fission/fission/pkg/controller/client/v1"
 )
 
 type (
diff --git a/pkg/controller/client/v1/httptrigger.go b/pkg/controller/client/v1/httptrigger.go
index ae1e3f74..e8f4d928 100644
--- a/pkg/controller/client/v1/httptrigger.go
+++ b/pkg/controller/client/v1/httptrigger.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 )
 
 type (
diff --git a/pkg/controller/client/v1/kuberneteswatchtrigger.go b/pkg/controller/client/v1/kuberneteswatchtrigger.go
index 6f723646..91969d08 100644
--- a/pkg/controller/client/v1/kuberneteswatchtrigger.go
+++ b/pkg/controller/client/v1/kuberneteswatchtrigger.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 	ferror "github.com/fission/fission/pkg/error"
 )
 
diff --git a/pkg/controller/client/v1/mqtrigger.go b/pkg/controller/client/v1/mqtrigger.go
index 02e28f7b..a391bf45 100644
--- a/pkg/controller/client/v1/mqtrigger.go
+++ b/pkg/controller/client/v1/mqtrigger.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 )
 
 type (
diff --git a/pkg/controller/client/v1/package.go b/pkg/controller/client/v1/package.go
index 509646cb..70ec5be6 100644
--- a/pkg/controller/client/v1/package.go
+++ b/pkg/controller/client/v1/package.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 )
 
 type (
diff --git a/pkg/controller/client/v1/timetrigger.go b/pkg/controller/client/v1/timetrigger.go
index 23688617..9e2f174c 100644
--- a/pkg/controller/client/v1/timetrigger.go
+++ b/pkg/controller/client/v1/timetrigger.go
@@ -20,11 +20,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/fission/fission/pkg/controller/client/rest"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
+	"github.com/fission/fission/pkg/controller/client/rest"
 )
 
 type (
diff --git a/pkg/controller/client/v1/v1.go b/pkg/controller/client/v1/v1.go
index 7e7d1581..35d9a2be 100644
--- a/pkg/controller/client/v1/v1.go
+++ b/pkg/controller/client/v1/v1.go
@@ -20,9 +20,8 @@ import (
 	"io"
 	"net/http"
 
-	ferror "github.com/fission/fission/pkg/error"
-
 	"github.com/fission/fission/pkg/controller/client/rest"
+	ferror "github.com/fission/fission/pkg/error"
 )
 
 type (
diff --git a/pkg/executor/executortype/container/containermgr.go b/pkg/executor/executortype/container/containermgr.go
index 341e3591..692a08ba 100644
--- a/pkg/executor/executortype/container/containermgr.go
+++ b/pkg/executor/executortype/container/containermgr.go
@@ -269,28 +269,30 @@ func (caaf *Container) RefreshFuncPods(ctx context.Context, logger *zap.Logger,
 
 // AdoptExistingResources attempts to adopt resources for functions in all namespaces.
 func (caaf *Container) AdoptExistingResources(ctx context.Context) {
-	fnList, err := caaf.fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
-	if err != nil {
-		caaf.logger.Error("error getting function list", zap.Error(err))
-		return
-	}
-
 	wg := &sync.WaitGroup{}
 
-	for i := range fnList.Items {
-		fn := &fnList.Items[i]
-		if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeContainer {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-
-				_, err = caaf.fnCreate(ctx, fn)
-				if err != nil {
-					caaf.logger.Warn("failed to adopt resources for function", zap.Error(err))
-					return
-				}
-				caaf.logger.Info("adopt resources for function", zap.String("function", fn.ObjectMeta.Name))
-			}()
+	for _, namepsace := range utils.GetNamespaces() {
+		fnList, err := caaf.fissionClient.CoreV1().Functions(namepsace).List(ctx, metav1.ListOptions{})
+		if err != nil {
+			caaf.logger.Error("error getting function list", zap.Error(err))
+			return
+		}
+
+		for i := range fnList.Items {
+			fn := &fnList.Items[i]
+			if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeContainer {
+				wg.Add(1)
+				go func() {
+					defer wg.Done()
+
+					_, err = caaf.fnCreate(ctx, fn)
+					if err != nil {
+						caaf.logger.Warn("failed to adopt resources for function", zap.Error(err))
+						return
+					}
+					caaf.logger.Info("adopt resources for function", zap.String("function", fn.ObjectMeta.Name))
+				}()
+			}
 		}
 	}
 
diff --git a/pkg/executor/executortype/newdeploy/newdeploymgr.go b/pkg/executor/executortype/newdeploy/newdeploymgr.go
index f25036bf..e8e50384 100644
--- a/pkg/executor/executortype/newdeploy/newdeploymgr.go
+++ b/pkg/executor/executortype/newdeploy/newdeploymgr.go
@@ -290,28 +290,30 @@ func (deploy *NewDeploy) RefreshFuncPods(ctx context.Context, logger *zap.Logger
 
 // AdoptExistingResources attempts to adopt resources for functions in all namespaces.
 func (deploy *NewDeploy) AdoptExistingResources(ctx context.Context) {
-	fnList, err := deploy.fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
-	if err != nil {
-		deploy.logger.Error("error getting function list", zap.Error(err))
-		return
-	}
-
 	wg := &sync.WaitGroup{}
 
-	for i := range fnList.Items {
-		fn := &fnList.Items[i]
-		if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeNewdeploy {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-
-				_, err = deploy.fnCreate(ctx, fn)
-				if err != nil {
-					deploy.logger.Warn("failed to adopt resources for function", zap.Error(err))
-					return
-				}
-				deploy.logger.Info("adopt resources for function", zap.String("function", fn.ObjectMeta.Name))
-			}()
+	for _, namepsace := range utils.GetNamespaces() {
+		fnList, err := deploy.fissionClient.CoreV1().Functions(namepsace).List(ctx, metav1.ListOptions{})
+		if err != nil {
+			deploy.logger.Error("error getting function list", zap.Error(err))
+			return
+		}
+
+		for i := range fnList.Items {
+			fn := &fnList.Items[i]
+			if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeNewdeploy {
+				wg.Add(1)
+				go func() {
+					defer wg.Done()
+
+					_, err = deploy.fnCreate(ctx, fn)
+					if err != nil {
+						deploy.logger.Warn("failed to adopt resources for function", zap.Error(err))
+						return
+					}
+					deploy.logger.Info("adopt resources for function", zap.String("function", fn.ObjectMeta.Name))
+				}()
+			}
 		}
 	}
 
@@ -349,7 +351,7 @@ func (deploy *NewDeploy) CleanupOldExecutorObjects(ctx context.Context) {
 }
 
 func (deploy *NewDeploy) getEnvFunctions(ctx context.Context, m *metav1.ObjectMeta) []fv1.Function {
-	funcList, err := deploy.fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
+	funcList, err := deploy.fissionClient.CoreV1().Functions(m.Namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		deploy.logger.Error("Error getting functions for env", zap.Error(err), zap.Any("environment", m))
 	}
diff --git a/pkg/executor/executortype/poolmgr/gpm.go b/pkg/executor/executortype/poolmgr/gpm.go
index fa779c86..901f4095 100644
--- a/pkg/executor/executortype/poolmgr/gpm.go
+++ b/pkg/executor/executortype/poolmgr/gpm.go
@@ -289,7 +289,7 @@ func (gpm *GenericPoolManager) RefreshFuncPods(ctx context.Context, logger *zap.
 
 	funcLabels := gp.labelsForFunction(&f.ObjectMeta)
 
-	podList, err := gpm.kubernetesClient.CoreV1().Pods(metav1.NamespaceAll).List(ctx, metav1.ListOptions{
+	podList, err := gpm.kubernetesClient.CoreV1().Pods(f.Spec.Environment.Namespace).List(ctx, metav1.ListOptions{
 		LabelSelector: labels.Set(funcLabels).AsSelector().String(),
 	})
 
@@ -311,132 +311,136 @@ func (gpm *GenericPoolManager) RefreshFuncPods(ctx context.Context, logger *zap.
 }
 
 func (gpm *GenericPoolManager) AdoptExistingResources(ctx context.Context) {
-	envs, err := gpm.fissionClient.CoreV1().Environments(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
-	if err != nil {
-		gpm.logger.Error("error getting environment list", zap.Error(err))
-		return
-	}
-
-	envMap := make(map[string]fv1.Environment, len(envs.Items))
+	envMap := make(map[string]fv1.Environment)
 	wg := &sync.WaitGroup{}
 
-	for i := range envs.Items {
-		env := envs.Items[i]
-
-		if getEnvPoolSize(&env) > 0 {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-				_, created, err := gpm.getPool(ctx, &env)
-				if err != nil {
-					gpm.logger.Error("adopt pool failed", zap.Error(err))
-				}
-				if created {
-					gpm.logger.Info("created pool for the environment", zap.String("env", env.ObjectMeta.Name), zap.String("namespace", gpm.namespace))
-				}
-			}()
+	for _, namespace := range utils.GetNamespaces() {
+		envs, err := gpm.fissionClient.CoreV1().Environments(namespace).List(ctx, metav1.ListOptions{})
+		if err != nil {
+			gpm.logger.Error("error getting environment list", zap.Error(err))
+			return
 		}
 
-		// create environment map for later use
-		key := fmt.Sprintf("%v/%v", env.ObjectMeta.Namespace, env.ObjectMeta.Name)
-		envMap[key] = env
+		for i := range envs.Items {
+			env := envs.Items[i]
+
+			if getEnvPoolSize(&env) > 0 {
+				wg.Add(1)
+				go func() {
+					defer wg.Done()
+					_, created, err := gpm.getPool(ctx, &env)
+					if err != nil {
+						gpm.logger.Error("adopt pool failed", zap.Error(err))
+					}
+					if created {
+						gpm.logger.Info("created pool for the environment", zap.String("env", env.ObjectMeta.Name), zap.String("namespace", gpm.namespace))
+					}
+				}()
+			}
+
+			// create environment map for later use
+			key := fmt.Sprintf("%v/%v", env.ObjectMeta.Namespace, env.ObjectMeta.Name)
+			envMap[key] = env
+		}
 	}
 
 	l := map[string]string{
 		fv1.EXECUTOR_TYPE: string(fv1.ExecutorTypePoolmgr),
 	}
 
-	podList, err := gpm.kubernetesClient.CoreV1().Pods(metav1.NamespaceAll).List(ctx, metav1.ListOptions{
-		LabelSelector: labels.Set(l).AsSelector().String(),
-	})
-
-	if err != nil {
-		gpm.logger.Error("error getting pod list", zap.Error(err))
-		return
-	}
+	for _, namespace := range utils.GetNamespaces() {
+		podList, err := gpm.kubernetesClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{
+			LabelSelector: labels.Set(l).AsSelector().String(),
+		})
 
-	for i := range podList.Items {
-		pod := &podList.Items[i]
-		if !utils.IsReadyPod(pod) {
-			continue
+		if err != nil {
+			gpm.logger.Error("error getting pod list", zap.Error(err))
+			return
 		}
 
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
+		for i := range podList.Items {
+			pod := &podList.Items[i]
+			if !utils.IsReadyPod(pod) {
+				continue
+			}
 
-			// avoid too many requests arrive Kubernetes API server at the same time.
-			time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
+			wg.Add(1)
+			go func() {
+				defer wg.Done()
 
-			patch := fmt.Sprintf(`{"metadata":{"annotations":{"%v":"%v"}}}`, fv1.EXECUTOR_INSTANCEID_LABEL, gpm.instanceID)
-			pod, err = gpm.kubernetesClient.CoreV1().Pods(pod.Namespace).Patch(ctx, pod.Name, k8sTypes.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{})
-			if err != nil {
-				// just log the error since it won't affect the function serving
-				gpm.logger.Warn("error patching executor instance ID of pod", zap.Error(err),
-					zap.String("pod", pod.Name), zap.String("ns", pod.Namespace))
-				return
-			}
+				// avoid too many requests arrive Kubernetes API server at the same time.
+				time.Sleep(time.Duration(rand.Intn(30)) * time.Millisecond)
 
-			// for unspecialized pod, we only update its annotations
-			if pod.Labels["managed"] == "true" {
-				return
-			}
+				patch := fmt.Sprintf(`{"metadata":{"annotations":{"%v":"%v"}}}`, fv1.EXECUTOR_INSTANCEID_LABEL, gpm.instanceID)
+				pod, err = gpm.kubernetesClient.CoreV1().Pods(pod.Namespace).Patch(ctx, pod.Name, k8sTypes.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{})
+				if err != nil {
+					// just log the error since it won't affect the function serving
+					gpm.logger.Warn("error patching executor instance ID of pod", zap.Error(err),
+						zap.String("pod", pod.Name), zap.String("ns", pod.Namespace))
+					return
+				}
 
-			fnName, ok1 := pod.Labels[fv1.FUNCTION_NAME]
-			fnNS, ok2 := pod.Labels[fv1.FUNCTION_NAMESPACE]
-			fnUID, ok3 := pod.Labels[fv1.FUNCTION_UID]
-			fnRV, ok4 := pod.Annotations[fv1.FUNCTION_RESOURCE_VERSION]
-			envName, ok5 := pod.Labels[fv1.ENVIRONMENT_NAME]
-			envNS, ok6 := pod.Labels[fv1.ENVIRONMENT_NAMESPACE]
-			svcHost, ok7 := pod.Annotations[fv1.ANNOTATION_SVC_HOST]
-			env, ok8 := envMap[fmt.Sprintf("%v/%v", envNS, envName)]
-
-			if !(ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8) {
-				gpm.logger.Warn("failed to adopt pod for function due to lack of necessary information",
-					zap.String("pod", pod.Name), zap.Any("labels", pod.Labels), zap.Any("annotations", pod.Annotations),
-					zap.String("env", env.ObjectMeta.Name))
-				return
-			}
+				// for unspecialized pod, we only update its annotations
+				if pod.Labels["managed"] == "true" {
+					return
+				}
 
-			fsvc := fscache.FuncSvc{
-				Name: pod.Name,
-				Function: &metav1.ObjectMeta{
-					Name:            fnName,
-					Namespace:       fnNS,
-					UID:             k8sTypes.UID(fnUID),
-					ResourceVersion: fnRV,
-				},
-				Environment: &env,
-				Address:     svcHost,
-				KubernetesObjects: []apiv1.ObjectReference{
-					{
-						Kind:            "pod",
-						Name:            pod.Name,
-						APIVersion:      pod.TypeMeta.APIVersion,
-						Namespace:       pod.ObjectMeta.Namespace,
-						ResourceVersion: pod.ObjectMeta.ResourceVersion,
-						UID:             pod.ObjectMeta.UID,
-					},
-				},
-				Executor: fv1.ExecutorTypePoolmgr,
-				Ctime:    time.Now(),
-				Atime:    time.Now(),
-			}
+				fnName, ok1 := pod.Labels[fv1.FUNCTION_NAME]
+				fnNS, ok2 := pod.Labels[fv1.FUNCTION_NAMESPACE]
+				fnUID, ok3 := pod.Labels[fv1.FUNCTION_UID]
+				fnRV, ok4 := pod.Annotations[fv1.FUNCTION_RESOURCE_VERSION]
+				envName, ok5 := pod.Labels[fv1.ENVIRONMENT_NAME]
+				envNS, ok6 := pod.Labels[fv1.ENVIRONMENT_NAMESPACE]
+				svcHost, ok7 := pod.Annotations[fv1.ANNOTATION_SVC_HOST]
+				env, ok8 := envMap[fmt.Sprintf("%v/%v", envNS, envName)]
+
+				if !(ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8) {
+					gpm.logger.Warn("failed to adopt pod for function due to lack of necessary information",
+						zap.String("pod", pod.Name), zap.Any("labels", pod.Labels), zap.Any("annotations", pod.Annotations),
+						zap.String("env", env.ObjectMeta.Name))
+					return
+				}
 
-			_, err = gpm.fsCache.Add(fsvc)
-			if err != nil {
-				// If fsvc already exists we just skip the duplicate one. And let reaper to recycle the duplicate pods.
-				// This is for the case that there are multiple function pods for the same function due to unknown reason.
-				if !fscache.IsNameExistError(err) {
-					gpm.logger.Warn("failed to adopt pod for function", zap.Error(err), zap.String("pod", pod.Name))
+				fsvc := fscache.FuncSvc{
+					Name: pod.Name,
+					Function: &metav1.ObjectMeta{
+						Name:            fnName,
+						Namespace:       fnNS,
+						UID:             k8sTypes.UID(fnUID),
+						ResourceVersion: fnRV,
+					},
+					Environment: &env,
+					Address:     svcHost,
+					KubernetesObjects: []apiv1.ObjectReference{
+						{
+							Kind:            "pod",
+							Name:            pod.Name,
+							APIVersion:      pod.TypeMeta.APIVersion,
+							Namespace:       pod.ObjectMeta.Namespace,
+							ResourceVersion: pod.ObjectMeta.ResourceVersion,
+							UID:             pod.ObjectMeta.UID,
+						},
+					},
+					Executor: fv1.ExecutorTypePoolmgr,
+					Ctime:    time.Now(),
+					Atime:    time.Now(),
 				}
 
-				return
-			}
+				_, err = gpm.fsCache.Add(fsvc)
+				if err != nil {
+					// If fsvc already exists we just skip the duplicate one. And let reaper to recycle the duplicate pods.
+					// This is for the case that there are multiple function pods for the same function due to unknown reason.
+					if !fscache.IsNameExistError(err) {
+						gpm.logger.Warn("failed to adopt pod for function", zap.Error(err), zap.String("pod", pod.Name))
+					}
 
-			gpm.logger.Info("adopt function pod",
-				zap.String("pod", pod.Name), zap.Any("labels", pod.Labels), zap.Any("annotations", pod.Annotations))
-		}()
+					return
+				}
+
+				gpm.logger.Info("adopt function pod",
+					zap.String("pod", pod.Name), zap.Any("labels", pod.Labels), zap.Any("annotations", pod.Annotations))
+			}()
+		}
 	}
 
 	wg.Wait()
diff --git a/pkg/executor/executortype/poolmgr/poolpodcontroller.go b/pkg/executor/executortype/poolmgr/poolpodcontroller.go
index 9e6fd29a..d0a28fa8 100644
--- a/pkg/executor/executortype/poolmgr/poolpodcontroller.go
+++ b/pkg/executor/executortype/poolmgr/poolpodcontroller.go
@@ -263,7 +263,7 @@ func (p *PoolPodController) workerRun(ctx context.Context, name string, processF
 }
 
 func (p *PoolPodController) getEnvLister(namespace string) (flisterv1.EnvironmentLister, error) {
-	lister, ok := p.envLister[metav1.NamespaceAll]
+	lister, ok := p.envLister[namespace]
 	if ok {
 		return lister, nil
 	}
diff --git a/pkg/executor/reaper/reaper.go b/pkg/executor/reaper/reaper.go
index 2c028e0c..bdc76695 100644
--- a/pkg/executor/reaper/reaper.go
+++ b/pkg/executor/reaper/reaper.go
@@ -93,6 +93,7 @@ func CleanupDeployments(ctx context.Context, logger *zap.Logger, client kubernet
 			// ignore err
 		}
 	}
+
 	return nil
 }
 
@@ -120,6 +121,7 @@ func CleanupPods(ctx context.Context, logger *zap.Logger, client kubernetes.Inte
 			// ignore err
 		}
 	}
+
 	return nil
 }
 
@@ -147,6 +149,7 @@ func CleanupServices(ctx context.Context, logger *zap.Logger, client kubernetes.
 			// ignore err
 		}
 	}
+
 	return nil
 }
 
@@ -175,6 +178,7 @@ func CleanupHpa(ctx context.Context, logger *zap.Logger, client kubernetes.Inter
 			// ignore err
 		}
 	}
+
 	return nil
 }
 
@@ -186,6 +190,7 @@ func CleanupRoleBindings(ctx context.Context, logger *zap.Logger, client kuberne
 		time.Sleep(cleanupRoleBindingInterval)
 
 		logger.Debug("starting cleanupRoleBindings cycle")
+
 		// get all rolebindings ( just to be efficient, one call to kubernetes )
 		rbList, err := client.RbacV1().RoleBindings(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
diff --git a/pkg/fission-cli/cmd/archive/command.go b/pkg/fission-cli/cmd/archive/command.go
index c1fdeb56..383253ef 100644
--- a/pkg/fission-cli/cmd/archive/command.go
+++ b/pkg/fission-cli/cmd/archive/command.go
@@ -32,7 +32,7 @@ func Commands() *cobra.Command {
 	}
 	wrapper.SetFlags(uploadCmd, flag.FlagSet{
 		Required: []flag.Flag{flag.ArchiveName},
-		Optional: []flag.Flag{flag.KubeContext},
+		Optional: []flag.Flag{},
 	})
 
 	listCmd := &cobra.Command{
@@ -41,7 +41,7 @@ func Commands() *cobra.Command {
 		RunE:  wrapper.Wrapper(List),
 	}
 	wrapper.SetFlags(listCmd, flag.FlagSet{
-		Optional: []flag.Flag{flag.KubeContext},
+		Optional: []flag.Flag{},
 	})
 
 	deleteCmd := &cobra.Command{
@@ -61,7 +61,7 @@ func Commands() *cobra.Command {
 	}
 	wrapper.SetFlags(geturlCmd, flag.FlagSet{
 		Required: []flag.Flag{flag.ArchiveID},
-		Optional: []flag.Flag{flag.KubeContext},
+		Optional: []flag.Flag{},
 	})
 
 	downloadCmd := &cobra.Command{
@@ -71,7 +71,7 @@ func Commands() *cobra.Command {
 	}
 	wrapper.SetFlags(downloadCmd, flag.FlagSet{
 		Required: []flag.Flag{flag.ArchiveID},
-		Optional: []flag.Flag{flag.KubeContext, flag.ArchiveOutput},
+		Optional: []flag.Flag{flag.ArchiveOutput},
 	})
 
 	command := &cobra.Command{
diff --git a/pkg/fission-cli/cmd/archive/delete.go b/pkg/fission-cli/cmd/archive/delete.go
index dc195a5e..35e798cc 100644
--- a/pkg/fission-cli/cmd/archive/delete.go
+++ b/pkg/fission-cli/cmd/archive/delete.go
@@ -36,10 +36,9 @@ func Delete(input cli.Input) error {
 
 func (opts *DeleteSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
 	archiveID := input.String(flagkey.ArchiveID)
 
-	storagesvcURL, err := util.GetStorageURL(input.Context(), kubeContext)
+	storagesvcURL, err := util.GetStorageURL(input.Context(), opts.Client())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/archive/download.go b/pkg/fission-cli/cmd/archive/download.go
index e64e3abf..3526dc54 100644
--- a/pkg/fission-cli/cmd/archive/download.go
+++ b/pkg/fission-cli/cmd/archive/download.go
@@ -37,7 +37,6 @@ func Download(input cli.Input) error {
 
 func (opts *DownloadSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
 	archiveID := input.String(flagkey.ArchiveID)
 	archiveOutput := input.String(flagkey.ArchiveOutput)
 
@@ -45,7 +44,7 @@ func (opts *DownloadSubCommand) do(input cli.Input) error {
 		archiveOutput = strings.TrimPrefix(archiveID, "/fission/fission-functions/")
 	}
 
-	storageAccessURL, err := util.GetStorageURL(input.Context(), kubeContext)
+	storageAccessURL, err := util.GetStorageURL(input.Context(), opts.Client())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/archive/geturl.go b/pkg/fission-cli/cmd/archive/geturl.go
index 75c9acf8..e3cd1d04 100644
--- a/pkg/fission-cli/cmd/archive/geturl.go
+++ b/pkg/fission-cli/cmd/archive/geturl.go
@@ -38,10 +38,9 @@ func GetURL(input cli.Input) error {
 
 func (opts *GetURLSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
 	archiveID := input.String(flagkey.ArchiveID)
 
-	serverURL, err := util.GetStorageURL(input.Context(), kubeContext)
+	serverURL, err := util.GetStorageURL(input.Context(), opts.Client())
 	if err != nil {
 		return err
 	}
@@ -67,7 +66,7 @@ func (opts *GetURLSubCommand) do(input cli.Input) error {
 	storageType := resp.Header.Get("X-FISSION-STORAGETYPE")
 
 	if storageType == "local" {
-		storageSvc, err := opts.Client().V1().Misc().GetSvcURL("application=fission-storage")
+		storageSvc, err := util.GetSvcName(input.Context(), opts.Client().KubernetesClient, "fission-storage")
 		if err != nil {
 			return err
 		}
diff --git a/pkg/fission-cli/cmd/archive/list.go b/pkg/fission-cli/cmd/archive/list.go
index 4c1e18dc..78829bda 100644
--- a/pkg/fission-cli/cmd/archive/list.go
+++ b/pkg/fission-cli/cmd/archive/list.go
@@ -21,7 +21,6 @@ import (
 
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
-	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
 	"github.com/fission/fission/pkg/fission-cli/util"
 	storagesvcClient "github.com/fission/fission/pkg/storagesvc/client"
 )
@@ -36,9 +35,7 @@ func List(input cli.Input) error {
 
 func (opts *ListSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
-
-	storageAccessURL, err := util.GetStorageURL(input.Context(), kubeContext)
+	storageAccessURL, err := util.GetStorageURL(input.Context(), opts.Client())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/archive/upload.go b/pkg/fission-cli/cmd/archive/upload.go
index db231b57..3614b5c5 100644
--- a/pkg/fission-cli/cmd/archive/upload.go
+++ b/pkg/fission-cli/cmd/archive/upload.go
@@ -36,10 +36,9 @@ func Upload(input cli.Input) error {
 
 func (opts *UploadSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
 	archiveName := input.String(flagkey.ArchiveName)
 
-	storagesvcURL, err := util.GetStorageURL(input.Context(), kubeContext)
+	storagesvcURL, err := util.GetStorageURL(input.Context(), opts.Client())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/canaryconfig/create.go b/pkg/fission-cli/cmd/canaryconfig/create.go
index a97ee0ba..35d75561 100644
--- a/pkg/fission-cli/cmd/canaryconfig/create.go
+++ b/pkg/fission-cli/cmd/canaryconfig/create.go
@@ -54,7 +54,8 @@ func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
 	ht := input.String(flagkey.CanaryHTTPTriggerName)
 	newFunc := input.String(flagkey.CanaryNewFunc)
 	oldFunc := input.String(flagkey.CanaryOldFunc)
-	_, fnNs, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+
+	_, fnNs, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in creating canaryconfig")
 	}
@@ -69,10 +70,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
 	}
 
 	// check that the trigger exists in the same namespace.
-	htTrigger, err := opts.Client().V1().HTTPTrigger().Get(&metav1.ObjectMeta{
-		Name:      ht,
-		Namespace: fnNs,
-	})
+	htTrigger, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(fnNs).Get(input.Context(), ht, metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error finding http trigger referenced in the canary config")
 	}
@@ -95,7 +93,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
 
 	// check that the functions exist in the same namespace
 	fnList := []string{newFunc, oldFunc}
-	err = util.CheckFunctionExistence(opts.Client(), fnList, fnNs)
+	err = util.CheckFunctionExistence(input.Context(), opts.Client(), fnList, fnNs)
 	if err != nil {
 		return errors.Wrap(err, "error checking functions existence")
 	}
@@ -124,7 +122,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *CreateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().CanaryConfig().Create(opts.canary)
+	_, err := opts.Client().FissionClientSet.CoreV1().CanaryConfigs(opts.canary.ObjectMeta.Namespace).Create(input.Context(), opts.canary, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating canary config")
 	}
diff --git a/pkg/fission-cli/cmd/canaryconfig/delete.go b/pkg/fission-cli/cmd/canaryconfig/delete.go
index e50f8228..c9cd088a 100644
--- a/pkg/fission-cli/cmd/canaryconfig/delete.go
+++ b/pkg/fission-cli/cmd/canaryconfig/delete.go
@@ -37,16 +37,12 @@ func Delete(input cli.Input) error {
 }
 
 func (opts *DeleteSubCommand) run(input cli.Input) (err error) {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceCanary)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting canaryConfig ")
 	}
-	m := &metav1.ObjectMeta{
-		Name:      input.String(flagkey.CanaryName),
-		Namespace: namespace,
-	}
 
-	err = opts.Client().V1().CanaryConfig().Delete(m)
+	err = opts.Client().FissionClientSet.CoreV1().CanaryConfigs(namespace).Delete(input.Context(), input.String(flagkey.CanaryName), metav1.DeleteOptions{})
 	if err != nil {
 		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
 			return nil
@@ -54,6 +50,6 @@ func (opts *DeleteSubCommand) run(input cli.Input) (err error) {
 		return errors.Wrap(err, "error deleting canary config")
 	}
 
-	fmt.Printf("canaryconfig '%v.%v' deleted\n", m.Name, m.Namespace)
+	fmt.Printf("canaryconfig '%v.%v' deleted\n", input.String(flagkey.CanaryName), namespace)
 	return nil
 }
diff --git a/pkg/fission-cli/cmd/canaryconfig/get.go b/pkg/fission-cli/cmd/canaryconfig/get.go
index dd773f88..3a34ec84 100644
--- a/pkg/fission-cli/cmd/canaryconfig/get.go
+++ b/pkg/fission-cli/cmd/canaryconfig/get.go
@@ -27,7 +27,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type GetSubCommand struct {
@@ -40,15 +39,12 @@ func Get(input cli.Input) error {
 
 func (opts *GetSubCommand) run(input cli.Input) (err error) {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceCanary)
 	if err != nil {
 		return errors.Wrap(err, "error getting canary config")
 	}
 
-	canaryCfg, err := opts.Client().V1().CanaryConfig().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.CanaryName),
-		Namespace: namespace,
-	})
+	canaryCfg, err := opts.Client().FissionClientSet.CoreV1().CanaryConfigs(namespace).Get(input.Context(), input.String(flagkey.CanaryName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting canary config")
 	}
diff --git a/pkg/fission-cli/cmd/canaryconfig/list.go b/pkg/fission-cli/cmd/canaryconfig/list.go
index 86cb5782..c4cb6d60 100644
--- a/pkg/fission-cli/cmd/canaryconfig/list.go
+++ b/pkg/fission-cli/cmd/canaryconfig/list.go
@@ -22,12 +22,11 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -48,7 +47,7 @@ func (opts *ListSubCommand) do(input cli.Input) error {
 }
 
 func (opts *ListSubCommand) complete(input cli.Input) (err error) {
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceCanary)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespaceCanary)
 	if err != nil {
 		return errors.Wrap(err, "error in listing canary config ")
 	}
@@ -57,19 +56,18 @@ func (opts *ListSubCommand) complete(input cli.Input) (err error) {
 
 func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
-	var canaryCfgs []v1.CanaryConfig
 	if input.Bool(flagkey.AllNamespaces) {
-		canaryCfgs, err = opts.Client().V1().CanaryConfig().List("")
-	} else {
-		canaryCfgs, err = opts.Client().V1().CanaryConfig().List(opts.namespace)
+		opts.namespace = metav1.NamespaceAll
 	}
+	canaryCfgs, err := opts.Client().FissionClientSet.CoreV1().CanaryConfigs(opts.namespace).List(input.Context(), metav1.ListOptions{})
+
 	if err != nil {
 		return errors.Wrap(err, "error listing canary config")
 	}
 
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "TRIGGER", "FUNCTION-N", "FUNCTION-N-1", "WEIGHT-INCREMENT", "INTERVAL", "FAILURE-THRESHOLD", "FAILURE-TYPE", "STATUS")
-	for _, canaryCfg := range canaryCfgs {
+	for _, canaryCfg := range canaryCfgs.Items {
 		fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
 			canaryCfg.ObjectMeta.Name, canaryCfg.Spec.Trigger, canaryCfg.Spec.NewFunction, canaryCfg.Spec.OldFunction, canaryCfg.Spec.WeightIncrement, canaryCfg.Spec.WeightIncrementDuration,
 			canaryCfg.Spec.FailureThreshold, canaryCfg.Spec.FailureType, canaryCfg.Status.Status)
diff --git a/pkg/fission-cli/cmd/canaryconfig/update.go b/pkg/fission-cli/cmd/canaryconfig/update.go
index 513e9244..808fe0a0 100644
--- a/pkg/fission-cli/cmd/canaryconfig/update.go
+++ b/pkg/fission-cli/cmd/canaryconfig/update.go
@@ -27,7 +27,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type UpdateSubCommand struct {
@@ -49,8 +48,7 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 
 func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 	// get the current config
-	name := input.String(flagkey.CanaryName)
-	_, ns, err := util.GetResourceNamespace(input, flagkey.NamespaceCanary)
+	_, ns, err := opts.GetResourceNamespace(input, flagkey.NamespaceCanary)
 	if err != nil {
 		return errors.Wrap(err, "error updating canary config")
 	}
@@ -64,10 +62,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 		return errors.Wrap(err, "error parsing time duration")
 	}
 
-	canaryCfg, err := opts.Client().V1().CanaryConfig().Get(&metav1.ObjectMeta{
-		Name:      name,
-		Namespace: ns,
-	})
+	canaryCfg, err := opts.Client().FissionClientSet.CoreV1().CanaryConfigs(ns).Get(input.Context(), input.String(flagkey.CanaryName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting canary config")
 	}
@@ -96,7 +91,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().CanaryConfig().Update(opts.canary)
+	_, err := opts.Client().FissionClientSet.CoreV1().CanaryConfigs(opts.canary.ObjectMeta.Namespace).Update(input.Context(), opts.canary, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating canary config")
 	}
diff --git a/pkg/fission-cli/cmd/check/check.go b/pkg/fission-cli/cmd/check/check.go
index c74df766..43717577 100644
--- a/pkg/fission-cli/cmd/check/check.go
+++ b/pkg/fission-cli/cmd/check/check.go
@@ -30,8 +30,6 @@ func Check(input cli.Input) error {
 
 func (opts *CheckSubCommand) do(input cli.Input) error {
 
-	kubeContext := input.String(flagkey.KubeContext)
-
 	checks := []healthcheck.CategoryID{}
 
 	if input.IsSet(flagkey.PreCheckOnly) {
@@ -40,11 +38,8 @@ func (opts *CheckSubCommand) do(input cli.Input) error {
 		checks = append(checks, healthcheck.FissionServices, healthcheck.FissionVersion)
 	}
 
-	hc := healthcheck.NewHealthChecker(checks, &healthcheck.Options{
-		KubeContext:   kubeContext,
-		FissionClient: opts.Client(),
-	})
+	hc := healthcheck.NewHealthChecker(opts.Client(), checks)
 
-	healthcheck.RunChecks(input.Context(), hc)
+	healthcheck.RunChecks(input.Context(), input, opts.Client(), hc)
 	return nil
 }
diff --git a/pkg/fission-cli/cmd/client.go b/pkg/fission-cli/cmd/client.go
new file mode 100644
index 00000000..b00dd662
--- /dev/null
+++ b/pkg/fission-cli/cmd/client.go
@@ -0,0 +1,134 @@
+/*
+Copyright 2022 The Fission Authors.
+
+Licensed 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 (
+	"errors"
+	"fmt"
+	"os"
+	"os/user"
+	"path/filepath"
+
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+	"k8s.io/client-go/tools/clientcmd"
+
+	"github.com/fission/fission/pkg/fission-cli/console"
+	"github.com/fission/fission/pkg/generated/clientset/versioned"
+)
+
+type (
+	ClientOptions struct {
+		KubeContext string
+	}
+	Client struct {
+		Options          ClientOptions
+		ClientConfig     clientcmd.ClientConfig
+		RestConfig       *rest.Config
+		FissionClientSet versioned.Interface
+		KubernetesClient kubernetes.Interface
+		Namespace        string
+	}
+)
+
+func (c *Client) SetFissionClientset(fissionClientSet versioned.Interface) {
+	c.FissionClientSet = fissionClientSet
+}
+
+func (c *Client) SetKubernetesClient(kubernetesClient kubernetes.Interface) {
+	c.KubernetesClient = kubernetesClient
+}
+
+func getLoadingRules() (loadingRules *clientcmd.ClientConfigLoadingRules, err error) {
+	loadingRules = clientcmd.NewDefaultClientConfigLoadingRules()
+
+	kubeConfigPath := os.Getenv("KUBECONFIG")
+	if len(kubeConfigPath) == 0 {
+		var homeDir string
+		usr, err := user.Current()
+		if err != nil {
+			// In case that user.Current() may be unable to work under some circumstances and return errors like
+			// "user: Current not implemented on darwin/amd64" due to cross-compilation problem. (https://github.com/golang/go/issues/6376).
+			// Instead of doing fatal here, we fallback to get home directory from the environment $HOME.
+			console.Warn(fmt.Sprintf("Could not get the current user's directory (%s), fallback to get it from env $HOME", err))
+			homeDir = os.Getenv("HOME")
+		} else {
+			homeDir = usr.HomeDir
+		}
+		kubeConfigPath = filepath.Join(homeDir, ".kube", "config")
+
+		if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
+			return nil, errors.New("couldn't find kubeconfig file. " +
+				"Set the KUBECONFIG environment variable to your kubeconfig's path.")
+		}
+		loadingRules.ExplicitPath = kubeConfigPath
+		console.Verbose(2, "Using kubeconfig from %q", kubeConfigPath)
+	} else {
+		console.Verbose(2, "Using kubeconfig from environment %q", kubeConfigPath)
+	}
+	return loadingRules, nil
+}
+
+func GetClientConfig(kubeContext string) (clientcmd.ClientConfig, error) {
+	loadingRules, err := getLoadingRules()
+	if err != nil {
+		return nil, err
+	}
+	overrides := &clientcmd.ConfigOverrides{}
+	if len(kubeContext) > 0 {
+		console.Verbose(2, "Using kubeconfig context %q", kubeContext)
+		overrides.CurrentContext = kubeContext
+	}
+	return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides), nil
+}
+
+func NewClient(opts ClientOptions) (*Client, error) {
+	client := &Client{
+		Options: opts,
+	}
+	cmdConfig, err := GetClientConfig(opts.KubeContext)
+	if err != nil {
+		return nil, err
+	}
+	client.ClientConfig = cmdConfig
+
+	namespace, _, err := cmdConfig.Namespace()
+	if err != nil {
+		return nil, err
+	}
+	client.Namespace = namespace
+	console.Verbose(2, "Kubeconfig default namespace %q", namespace)
+
+	restConfig, err := cmdConfig.ClientConfig()
+	if err != nil {
+		return nil, err
+	}
+	client.RestConfig = restConfig
+	clientset, err := kubernetes.NewForConfig(restConfig)
+	if err != nil {
+		return nil, err
+	}
+	client.KubernetesClient = clientset
+
+	fissionClientset, err := versioned.NewForConfig(restConfig)
+	if err != nil {
+		return nil, err
+	}
+	client.FissionClientSet = fissionClientset
+
+	return client, nil
+}
diff --git a/pkg/fission-cli/cmd/cmd.go b/pkg/fission-cli/cmd/cmd.go
index 599ee831..23f128fa 100644
--- a/pkg/fission-cli/cmd/cmd.go
+++ b/pkg/fission-cli/cmd/cmd.go
@@ -17,10 +17,12 @@ limitations under the License.
 package cmd
 
 import (
+	"os"
 	"sync"
 
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/console"
+	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
 )
 
 type (
@@ -29,16 +31,40 @@ type (
 )
 
 var (
-	once             = sync.Once{}
-	defaultClientset client.Interface
+	once          = sync.Once{}
+	defaultClient Client
 )
 
-func SetClientset(clientset client.Interface) {
+func SetClientset(client Client) {
 	once.Do(func() {
-		defaultClientset = clientset
+		defaultClient = client
 	})
 }
 
-func (c *CommandActioner) Client() client.Interface {
-	return defaultClientset
+func (c *CommandActioner) Client() Client {
+	return defaultClient
+}
+
+func (c *CommandActioner) GetResourceNamespace(input cli.Input, deprecatedFlag string) (namespace, currentNS string, err error) {
+	namespace = input.String(deprecatedFlag)
+	currentNS = namespace
+
+	if input.String(flagkey.Namespace) != "" {
+		namespace = input.String(flagkey.Namespace)
+		currentNS = namespace
+		console.Verbose(2, "Namespace for resource %s ", currentNS)
+		return namespace, currentNS, err
+	}
+
+	if namespace == "" {
+		if os.Getenv("FISSION_DEFAULT_NAMESPACE") != "" {
+			currentNS = os.Getenv("FISSION_DEFAULT_NAMESPACE")
+		} else {
+			currentNS = c.Client().Namespace
+			return namespace, currentNS, err
+		}
+	}
+
+	console.Verbose(2, "Namespace for resource %s ", currentNS)
+	return namespace, currentNS, nil
 }
diff --git a/pkg/fission-cli/cmd/environment/create.go b/pkg/fission-cli/cmd/environment/create.go
index d631aaa1..e0e38176 100644
--- a/pkg/fission-cli/cmd/environment/create.go
+++ b/pkg/fission-cli/cmd/environment/create.go
@@ -66,16 +66,16 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 func (opts *CreateSubCommand) run(input cli.Input) (err error) {
 	m := opts.env.ObjectMeta
 
-	envList, err := opts.Client().V1().Environment().List(m.Namespace)
+	envList, err := opts.Client().FissionClientSet.CoreV1().Environments(m.Namespace).List(input.Context(), metav1.ListOptions{})
 	if err != nil {
 		return err
-	} else if len(envList) > 0 {
+	} else if len(envList.Items) > 0 {
 		console.Verbose(2, "%d environment(s) are present in the %s namespace.  "+
 			"These environments are not isolated from each other; use separate namespaces if you need isolation.",
-			len(envList), m.Namespace)
+			len(envList.Items), m.Namespace)
 	}
 
-	userDefinedNS, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	userDefinedNS, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -108,14 +108,10 @@ func (opts *CreateSubCommand) run(input cli.Input) (err error) {
 	}
 
 	opts.env.ObjectMeta.Namespace = currentNS
-	err = opts.env.Validate()
-	if err != nil {
-		return fv1.AggregateValidationErrors("Environment", err)
-	}
 
-	_, err = opts.Client().V1().Environment().Create(opts.env)
+	_, err = opts.Client().FissionClientSet.CoreV1().Environments(opts.env.Namespace).Create(input.Context(), opts.env, metav1.CreateOptions{})
 	if err != nil {
-		return errors.Wrap(err, "error creating environment")
+		return errors.Wrap(err, "error creating resource")
 	}
 
 	fmt.Printf("environment '%v' created\n", m.Name)
diff --git a/pkg/fission-cli/cmd/environment/delete.go b/pkg/fission-cli/cmd/environment/delete.go
index f7b5b751..374ea5b9 100644
--- a/pkg/fission-cli/cmd/environment/delete.go
+++ b/pkg/fission-cli/cmd/environment/delete.go
@@ -20,13 +20,13 @@ import (
 	"fmt"
 
 	"github.com/pkg/errors"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type DeleteSubCommand struct {
@@ -39,40 +39,36 @@ func Delete(input cli.Input) error {
 
 func (opts *DeleteSubCommand) do(input cli.Input) (err error) {
 
-	_, currentContextNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentContextNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return errors.Wrap(err, "error creating environment")
 	}
 	console.Verbose(2, "Searching for resource in  %s Namespace", currentContextNS)
-
-	m := &metav1.ObjectMeta{
-		Name:      input.String(flagkey.EnvName),
-		Namespace: currentContextNS,
-	}
+	envName := input.String(flagkey.EnvName)
 
 	if !input.Bool(flagkey.EnvForce) {
-		fns, err := opts.Client().V1().Function().List(metav1.NamespaceAll)
+		fns, err := opts.Client().FissionClientSet.CoreV1().Functions(metav1.NamespaceAll).List(input.Context(), metav1.ListOptions{})
 		if err != nil {
 			return errors.Wrap(err, "Error getting functions wrt environment.")
 		}
 
-		for _, fn := range fns {
-			if fn.Spec.Environment.Name == m.Name &&
-				fn.Spec.Environment.Namespace == m.Namespace {
+		for _, fn := range fns.Items {
+			if fn.Spec.Environment.Name == envName &&
+				fn.Spec.Environment.Namespace == currentContextNS {
 				return errors.New("Environment is used by at least one function.")
 			}
 		}
 	}
 
-	err = opts.Client().V1().Environment().Delete(m)
+	err = opts.Client().FissionClientSet.CoreV1().Environments(currentContextNS).Delete(input.Context(), envName, metav1.DeleteOptions{})
 	if err != nil {
-		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
+		if input.Bool(flagkey.IgnoreNotFound) && kerrors.IsNotFound(err) {
 			return nil
 		}
 		return errors.Wrap(err, "error deleting environment")
 	}
 
-	fmt.Printf("environment '%v' deleted\n", m.Name)
+	fmt.Printf("environment '%s' deleted\n", envName)
 
 	return nil
 }
diff --git a/pkg/fission-cli/cmd/environment/get.go b/pkg/fission-cli/cmd/environment/get.go
index 4c72bdbf..8b969d08 100644
--- a/pkg/fission-cli/cmd/environment/get.go
+++ b/pkg/fission-cli/cmd/environment/get.go
@@ -27,7 +27,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type GetSubCommand struct {
@@ -40,17 +39,12 @@ func Get(input cli.Input) error {
 
 func (opts *GetSubCommand) do(input cli.Input) (err error) {
 
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return errors.Wrap(err, "error creating environment")
 	}
 
-	m := &metav1.ObjectMeta{
-		Name:      input.String(flagkey.EnvName),
-		Namespace: currentNS,
-	}
-
-	env, err := opts.Client().V1().Environment().Get(m)
+	env, err := opts.Client().FissionClientSet.CoreV1().Environments(currentNS).Get(input.Context(), input.String(flagkey.EnvName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting environment")
 	}
diff --git a/pkg/fission-cli/cmd/environment/list.go b/pkg/fission-cli/cmd/environment/list.go
index 383f43e9..8300db23 100644
--- a/pkg/fission-cli/cmd/environment/list.go
+++ b/pkg/fission-cli/cmd/environment/list.go
@@ -22,12 +22,11 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -40,22 +39,22 @@ func List(input cli.Input) error {
 
 func (opts *ListSubCommand) do(input cli.Input) (err error) {
 
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return errors.Wrap(err, "error creating environment")
 	}
 
-	var envs []v1.Environment
 	if input.Bool(flagkey.AllNamespaces) {
-		envs, err = opts.Client().V1().Environment().List("")
-	} else {
-		envs, err = opts.Client().V1().Environment().List(currentNS)
+		currentNS = metav1.NamespaceAll
 	}
 
+	response, err := opts.Client().FissionClientSet.CoreV1().Environments(currentNS).List(input.Context(), metav1.ListOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error listing environments")
 	}
 
+	envs := response.Items
+
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "IMAGE", "BUILDER_IMAGE", "POOLSIZE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "EXTNET", "GRACETIME", "NAMESPACE")
 	for _, env := range envs {
diff --git a/pkg/fission-cli/cmd/environment/pods.go b/pkg/fission-cli/cmd/environment/pods.go
index b536684b..2eca539c 100644
--- a/pkg/fission-cli/cmd/environment/pods.go
+++ b/pkg/fission-cli/cmd/environment/pods.go
@@ -23,12 +23,12 @@ import (
 
 	"github.com/pkg/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/labels"
 
 	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 	"github.com/fission/fission/pkg/utils"
 )
 
@@ -42,37 +42,35 @@ func ListPods(input cli.Input) error {
 
 func (opts *ListPodsSubCommand) do(input cli.Input) (err error) {
 
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return errors.Wrap(err, "error creating environment")
 	}
 
-	// validate environment
-	_, err = opts.Client().V1().Environment().Get(
-		&metav1.ObjectMeta{
-			Name:      input.String(flagkey.EnvName),
-			Namespace: currentNS,
-		})
+	_, err = opts.Client().FissionClientSet.CoreV1().Environments(currentNS).Get(input.Context(), input.String(flagkey.EnvName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting environment")
 	}
 
-	m := &metav1.ObjectMeta{
-		Name: input.String(flagkey.EnvName),
-		Labels: map[string]string{
-			v1.ENVIRONMENT_NAMESPACE: currentNS,
-			v1.EXECUTOR_TYPE:         input.String(flagkey.EnvExecutorType),
-		},
+	// label selector
+	selector := map[string]string{
+		v1.ENVIRONMENT_NAME: input.String(flagkey.EnvName),
+	}
+	selector[v1.ENVIRONMENT_NAMESPACE] = currentNS
+	if len(input.String(flagkey.EnvExecutorType)) > 0 {
+		selector[v1.EXECUTOR_TYPE] = input.String(flagkey.EnvExecutorType)
 	}
 
-	pods, err := opts.Client().V1().Environment().ListPods(m)
+	podsList, err := opts.Client().KubernetesClient.CoreV1().Pods(metav1.NamespaceAll).List(input.Context(), metav1.ListOptions{
+		LabelSelector: labels.Set(selector).AsSelector().String(),
+	})
 	if err != nil {
 		return errors.Wrap(err, "error listing environments")
 	}
 
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t\n", "NAME", "NAMESPACE", "READY", "STATUS", "IP", "EXECUTORTYPE", "MANAGED")
-	for _, pod := range pods {
+	for _, pod := range podsList.Items {
 
 		// A deletion timestamp indicates that a pod is terminating. Do not count this pod.
 		if pod.ObjectMeta.DeletionTimestamp != nil {
diff --git a/pkg/fission-cli/cmd/environment/update.go b/pkg/fission-cli/cmd/environment/update.go
index 5ac7a23b..ea89791a 100644
--- a/pkg/fission-cli/cmd/environment/update.go
+++ b/pkg/fission-cli/cmd/environment/update.go
@@ -54,14 +54,11 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 
 func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 
-	_, currentContextNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentContextNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return errors.Wrap(err, "error creating environment")
 	}
-	env, err := opts.Client().V1().Environment().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.EnvName),
-		Namespace: currentContextNS,
-	})
+	env, err := opts.Client().FissionClientSet.CoreV1().Environments(currentContextNS).Get(input.Context(), input.String(flagkey.EnvName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error finding environment")
 	}
@@ -81,12 +78,16 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().Environment().Update(opts.env)
+
+	enew, err := opts.Client().FissionClientSet.CoreV1().Environments(opts.env.ObjectMeta.Namespace).Update(input.Context(), opts.env, metav1.UpdateOptions{})
+	if err != nil {
+		return errors.Wrap(err, "error updating environment")
+	}
 	if err != nil {
 		return errors.Wrap(err, "error updating environment")
 	}
 
-	fmt.Printf("environment '%v' updated\n", opts.env.ObjectMeta.Name)
+	fmt.Printf("environment '%v' updated\n", enew.ObjectMeta.Name)
 	return nil
 }
 
diff --git a/pkg/fission-cli/cmd/function/create.go b/pkg/fission-cli/cmd/function/create.go
index 8959b3c2..0b6e3e5d 100644
--- a/pkg/fission-cli/cmd/function/create.go
+++ b/pkg/fission-cli/cmd/function/create.go
@@ -65,7 +65,7 @@ func (opts *CreateSubCommand) do(input cli.Input) error {
 func (opts *CreateSubCommand) complete(input cli.Input) error {
 	fnName := input.String(flagkey.FnName)
 
-	userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	userProvidedNS, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error retrieving namespace information")
 	}
@@ -81,13 +81,10 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 
 	if !toSpec {
 		// check for unique function names within a namespace
-		fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-			Name:      input.String(flagkey.FnName),
-			Namespace: fnNamespace,
-		})
-		if err != nil && !ferror.IsNotFound(err) {
+		fn, err := opts.Client().FissionClientSet.CoreV1().Functions(fnNamespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
+		if err != nil && !k8serrors.IsNotFound(err) {
 			return err
-		} else if fn != nil {
+		} else if fn.Name != "" && fn.Namespace != "" {
 			return errors.New("a function with the same name already exists")
 		}
 	}
@@ -155,10 +152,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 			pkgMetadata = &pkg.ObjectMeta
 		} else {
 			// use existing package
-			pkg, err = opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      pkgName,
-			})
+			pkg, err = opts.Client().FissionClientSet.CoreV1().Packages(fnNamespace).Get(input.Context(), pkgName, metav1.GetOptions{})
 			if err != nil {
 				return errors.Wrap(err, fmt.Sprintf("read package in '%s' in Namespace: %s. Package needs to be present in the same namespace as function", pkgName, fnNamespace))
 			}
@@ -196,10 +190,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 					fnName, envName))
 			}
 		} else {
-			_, err := opts.Client().V1().Environment().Get(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      envName,
-			})
+			_, err := opts.Client().FissionClientSet.CoreV1().Environments(fnNamespace).Get(input.Context(), envName, metav1.GetOptions{})
 			if err != nil {
 				if e, ok := err.(ferror.Error); ok && e.Code == ferror.ErrorNotFound {
 					console.Warn(fmt.Sprintf("Environment \"%s\" does not exist. Please create the environment before executing the function. \nFor example: `fission env create --name %s --envns %s --image <image>`\n", envName, envName, fnNamespace))
@@ -246,10 +237,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 		// check the referenced secret is in the same ns as the function, if not give a warning.
 		if !toSpec { // TODO: workaround in order not to block users from creating function spec, remove it.
 			for _, secretName := range secretNames {
-				err := opts.Client().V1().Misc().SecretExists(&metav1.ObjectMeta{
-					Namespace: fnNamespace,
-					Name:      secretName,
-				})
+				err := util.SecretExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: secretName}, opts.Client().KubernetesClient)
 				if err != nil {
 					if k8serrors.IsNotFound(err) {
 						console.Warn(fmt.Sprintf("Secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
@@ -279,10 +267,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 		// check the referenced cfgmap is in the same ns as the function, if not give a warning.
 		if !toSpec {
 			for _, cfgMapName := range cfgMapNames {
-				err := opts.Client().V1().Misc().ConfigMapExists(&metav1.ObjectMeta{
-					Namespace: fnNamespace,
-					Name:      cfgMapName,
-				})
+				err := util.ConfigMapExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: cfgMapName}, opts.Client().KubernetesClient)
 				if err != nil {
 					if k8serrors.IsNotFound(err) {
 						console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as function", cfgMapName, fnNamespace))
@@ -385,7 +370,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().Function().Create(opts.function)
+	_, err := opts.Client().FissionClientSet.CoreV1().Functions(opts.function.ObjectMeta.Namespace).Create(input.Context(), opts.function, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating function")
 	}
@@ -434,7 +419,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 			},
 		},
 	}
-	_, err = opts.Client().V1().HTTPTrigger().Create(ht)
+	_, err = opts.Client().FissionClientSet.CoreV1().HTTPTriggers(opts.function.ObjectMeta.Namespace).Create(input.Context(), ht, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating HTTP trigger")
 	}
diff --git a/pkg/fission-cli/cmd/function/delete.go b/pkg/fission-cli/cmd/function/delete.go
index e0095dda..2f2d1fb2 100644
--- a/pkg/fission-cli/cmd/function/delete.go
+++ b/pkg/fission-cli/cmd/function/delete.go
@@ -38,7 +38,7 @@ func Delete(input cli.Input) error {
 
 func (opts *DeleteSubCommand) do(input cli.Input) error {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -47,7 +47,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
 		Namespace: namespace,
 	}
 
-	err = opts.Client().V1().Function().Delete(m)
+	err = opts.Client().FissionClientSet.CoreV1().Functions(namespace).Delete(input.Context(), input.String(flagkey.FnName), metav1.DeleteOptions{})
 	if err != nil {
 		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
 			return nil
diff --git a/pkg/fission-cli/cmd/function/get.go b/pkg/fission-cli/cmd/function/get.go
index af48081a..25135b93 100644
--- a/pkg/fission-cli/cmd/function/get.go
+++ b/pkg/fission-cli/cmd/function/get.go
@@ -25,7 +25,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type GetSubCommand struct {
@@ -37,22 +36,16 @@ func Get(input cli.Input) error {
 }
 
 func (opts *GetSubCommand) do(input cli.Input) error {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in get function ")
 	}
-	fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: namespace,
-	})
+	fn, err := opts.Client().FissionClientSet.CoreV1().Functions(namespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting function")
 	}
 
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Name:      fn.Spec.Package.PackageRef.Name,
-		Namespace: fn.Spec.Package.PackageRef.Namespace,
-	})
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(fn.Spec.Package.PackageRef.Namespace).Get(input.Context(), fn.Spec.Package.PackageRef.Name, metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting package")
 	}
diff --git a/pkg/fission-cli/cmd/function/getmeta.go b/pkg/fission-cli/cmd/function/getmeta.go
index 02c67ca9..936fa5ef 100644
--- a/pkg/fission-cli/cmd/function/getmeta.go
+++ b/pkg/fission-cli/cmd/function/getmeta.go
@@ -25,7 +25,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type GetMetaSubCommand struct {
@@ -37,15 +36,12 @@ func GetMeta(input cli.Input) error {
 }
 
 func (opts *GetMetaSubCommand) do(input cli.Input) error {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in getting meta function ")
 	}
 
-	fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: namespace,
-	})
+	fn, err := opts.Client().FissionClientSet.CoreV1().Functions(namespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting function")
 	}
diff --git a/pkg/fission-cli/cmd/function/list.go b/pkg/fission-cli/cmd/function/list.go
index 98a3662d..5ef7a7ce 100644
--- a/pkg/fission-cli/cmd/function/list.go
+++ b/pkg/fission-cli/cmd/function/list.go
@@ -23,12 +23,11 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -40,17 +39,16 @@ func List(input cli.Input) error {
 }
 
 func (opts *ListSubCommand) do(input cli.Input) error {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in listing function ")
 	}
 
-	var fns []v1.Function
 	if input.Bool(flagkey.AllNamespaces) {
-		fns, err = opts.Client().V1().Function().List("")
-	} else {
-		fns, err = opts.Client().V1().Function().List(namespace)
+		namespace = metav1.NamespaceAll
 	}
+	fns, err := opts.Client().FissionClientSet.CoreV1().Functions(namespace).List(input.Context(), metav1.ListOptions{})
+
 	if err != nil {
 		return errors.Wrap(err, "error listing functions")
 	}
@@ -58,7 +56,7 @@ func (opts *ListSubCommand) do(input cli.Input) error {
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
 
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "ENV", "EXECUTORTYPE", "MINSCALE", "MAXSCALE", "MINCPU", "MAXCPU", "MINMEMORY", "MAXMEMORY", "SECRETS", "CONFIGMAPS", "NAMESPACE")
-	for _, f := range fns {
+	for _, f := range fns.Items {
 		secrets := f.Spec.Secrets
 		configMaps := f.Spec.ConfigMaps
 		var secretsList, configMapList []string
diff --git a/pkg/fission-cli/cmd/function/log.go b/pkg/fission-cli/cmd/function/log.go
index b1a187db..7bcffa66 100644
--- a/pkg/fission-cli/cmd/function/log.go
+++ b/pkg/fission-cli/cmd/function/log.go
@@ -40,14 +40,13 @@ func Log(input cli.Input) error {
 }
 
 func (opts *LogSubCommand) do(input cli.Input) error {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in logs for function ")
 	}
 
 	dbType := input.String(flagkey.FnLogDBType)
 	fnPod := input.String(flagkey.FnLogPod)
-	kubeContext := input.String(flagkey.KubeContext)
 
 	logReverseQuery := !input.Bool(flagkey.FnLogFollow) && input.Bool(flagkey.FnLogReverseQuery)
 
@@ -56,15 +55,12 @@ func (opts *LogSubCommand) do(input cli.Input) error {
 		recordLimit = 1000
 	}
 
-	f, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: namespace,
-	})
+	f, err := opts.Client().FissionClientSet.CoreV1().Functions(namespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting function")
 	}
 
-	server, err := util.GetApplicationUrl(input.Context(), "application=fission-api", kubeContext)
+	server, err := util.GetApplicationUrl(input.Context(), opts.Client(), "application=fission-api")
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/function/pods.go b/pkg/fission-cli/cmd/function/pods.go
index 0f6835ec..5bfe8138 100644
--- a/pkg/fission-cli/cmd/function/pods.go
+++ b/pkg/fission-cli/cmd/function/pods.go
@@ -23,12 +23,12 @@ import (
 
 	"github.com/pkg/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/labels"
 
 	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 	"github.com/fission/fission/pkg/utils"
 )
 
@@ -42,35 +42,34 @@ func ListPods(input cli.Input) error {
 
 func (opts *ListPodsSubCommand) do(input cli.Input) error {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 
 	if err != nil {
 		return errors.Wrap(err, "error in finding pod for function ")
 	}
 	// validate function
-	_, err = opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: namespace,
-	})
+	_, err = opts.Client().FissionClientSet.CoreV1().Functions(namespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting function")
 	}
 
-	m := &metav1.ObjectMeta{
-		Name: input.String(flagkey.FnName),
-		Labels: map[string]string{
-			v1.FUNCTION_NAMESPACE: namespace,
-		},
+	selector := map[string]string{
+		v1.FUNCTION_NAME: input.String(flagkey.FnName),
+	}
+	if len(namespace) != 0 {
+		selector[v1.FUNCTION_NAMESPACE] = namespace
 	}
 
-	pods, err := opts.Client().V1().Function().ListPods(m)
+	pods, err := opts.Client().KubernetesClient.CoreV1().Pods(metav1.NamespaceAll).List(input.Context(), metav1.ListOptions{
+		LabelSelector: labels.Set(selector).AsSelector().String(),
+	})
 	if err != nil {
 		return errors.Wrap(err, "error listing environments")
 	}
 
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t\n", "NAME", "NAMESPACE", "READY", "STATUS", "IP", "EXECUTORTYPE", "MANAGED")
-	for _, pod := range pods {
+	for _, pod := range pods.Items {
 
 		// A deletion timestamp indicates that a pod is terminating. Do not count this pod.
 		if pod.ObjectMeta.DeletionTimestamp != nil {
diff --git a/pkg/fission-cli/cmd/function/run_container.go b/pkg/fission-cli/cmd/function/run_container.go
index 492ac8db..d603e1ad 100644
--- a/pkg/fission-cli/cmd/function/run_container.go
+++ b/pkg/fission-cli/cmd/function/run_container.go
@@ -22,11 +22,10 @@ import (
 
 	"github.com/pkg/errors"
 	apiv1 "k8s.io/api/core/v1"
-	k8serrors "k8s.io/apimachinery/pkg/api/errors"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	ferror "github.com/fission/fission/pkg/error"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec"
@@ -56,7 +55,7 @@ func (opts *RunContainerSubCommand) do(input cli.Input) error {
 func (opts *RunContainerSubCommand) complete(input cli.Input) error {
 	fnName := input.String(flagkey.FnName)
 
-	_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in running container for function ")
 	}
@@ -70,13 +69,11 @@ func (opts *RunContainerSubCommand) complete(input cli.Input) error {
 
 	if !toSpec {
 		// check for unique function names within a namespace
-		fn, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-			Name:      input.String(flagkey.FnName),
-			Namespace: fnNamespace,
-		})
-		if err != nil && !ferror.IsNotFound(err) {
+		fn, err := opts.Client().FissionClientSet.CoreV1().Functions(fnNamespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
+
+		if err != nil && !kerrors.IsNotFound(err) {
 			return err
-		} else if fn != nil {
+		} else if fn.Name != "" && fn.Namespace != "" {
 			return errors.New("a function with the same name already exists")
 		}
 	}
@@ -128,12 +125,9 @@ func (opts *RunContainerSubCommand) complete(input cli.Input) error {
 		// check the referenced secret is in the same ns as the function, if not give a warning.
 		if !toSpec { // TODO: workaround in order not to block users from creating function spec, remove it.
 			for _, secretName := range secretNames {
-				err := opts.Client().V1().Misc().SecretExists(&metav1.ObjectMeta{
-					Namespace: fnNamespace,
-					Name:      secretName,
-				})
+				err := util.SecretExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: secretName}, opts.Client().KubernetesClient)
 				if err != nil {
-					if k8serrors.IsNotFound(err) {
+					if kerrors.IsNotFound(err) {
 						console.Warn(fmt.Sprintf("Secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
 					} else {
 						return errors.Wrapf(err, "error checking secret %s", secretName)
@@ -154,12 +148,10 @@ func (opts *RunContainerSubCommand) complete(input cli.Input) error {
 		// check the referenced cfgmap is in the same ns as the function, if not give a warning.
 		if !toSpec {
 			for _, cfgMapName := range cfgMapNames {
-				err := opts.Client().V1().Misc().ConfigMapExists(&metav1.ObjectMeta{
-					Namespace: fnNamespace,
-					Name:      cfgMapName,
-				})
+				err := util.ConfigMapExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: cfgMapName}, opts.Client().KubernetesClient)
+
 				if err != nil {
-					if k8serrors.IsNotFound(err) {
+					if kerrors.IsNotFound(err) {
 						console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as function", cfgMapName, fnNamespace))
 					} else {
 						return errors.Wrapf(err, "error checking configmap %s", cfgMapName)
@@ -238,7 +230,7 @@ func (opts *RunContainerSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().Function().Create(opts.function)
+	_, err := opts.Client().FissionClientSet.CoreV1().Functions(opts.function.ObjectMeta.Namespace).Create(input.Context(), opts.function, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating function")
 	}
diff --git a/pkg/fission-cli/cmd/function/update.go b/pkg/fission-cli/cmd/function/update.go
index 42c22c9d..e39aefce 100644
--- a/pkg/fission-cli/cmd/function/update.go
+++ b/pkg/fission-cli/cmd/function/update.go
@@ -51,15 +51,12 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 
 func (opts *UpdateSubCommand) complete(input cli.Input) error {
 	fnName := input.String(flagkey.FnName)
-	_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in updating function ")
 	}
 
-	function, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: fnNamespace,
-	})
+	function, err := opts.Client().FissionClientSet.CoreV1().Functions(fnNamespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("read function '%v'", fnName))
 	}
@@ -90,10 +87,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 
 		// check that the referenced secret is in the same ns as the function, if not give a warning.
 		for _, secretName := range secretNames {
-			err := opts.Client().V1().Misc().SecretExists(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      secretName,
-			})
+			err := util.SecretExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: secretName}, opts.Client().KubernetesClient)
 			if k8serrors.IsNotFound(err) {
 				console.Warn(fmt.Sprintf("secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
 			}
@@ -114,10 +108,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 
 		// check that the referenced cfgmap is in the same ns as the function, if not give a warning.
 		for _, cfgMapName := range cfgMapNames {
-			err := opts.Client().V1().Misc().ConfigMapExists(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      cfgMapName,
-			})
+			err := util.ConfigMapExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: cfgMapName}, opts.Client().KubernetesClient)
 			if k8serrors.IsNotFound(err) {
 				console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as the function", cfgMapName, fnNamespace))
 			}
@@ -186,17 +177,14 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 
 	function.Spec.Resources = *resReqs
 
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Namespace: fnNamespace,
-		Name:      pkgName,
-	})
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(fnNamespace).Get(input.Context(), pkgName, metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("read package '%v.%v'. Pkg should be present in the same ns as the function", pkgName, fnNamespace))
 	}
 
 	forceUpdate := input.Bool(flagkey.PkgForce)
 
-	fnList, err := _package.GetFunctionsByPackage(opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
+	fnList, err := _package.GetFunctionsByPackage(input.Context(), opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
 	if err != nil {
 		return errors.Wrap(err, "error getting function list")
 	}
@@ -222,7 +210,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 				fns = append(fns, fn)
 			}
 		}
-		err = _package.UpdateFunctionPackageResourceVersion(opts.Client(), newPkgMeta, fns...)
+		err = _package.UpdateFunctionPackageResourceVersion(input.Context(), opts.Client(), newPkgMeta, fns...)
 		if err != nil {
 			return errors.Wrap(err, "error updating function package reference resource version")
 		}
@@ -255,7 +243,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().Function().Update(opts.function)
+	_, err := opts.Client().FissionClientSet.CoreV1().Functions(opts.function.Namespace).Update(input.Context(), opts.function, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating function")
 	}
diff --git a/pkg/fission-cli/cmd/function/update_container.go b/pkg/fission-cli/cmd/function/update_container.go
index 13633ca3..9b34db1e 100644
--- a/pkg/fission-cli/cmd/function/update_container.go
+++ b/pkg/fission-cli/cmd/function/update_container.go
@@ -53,15 +53,13 @@ func (opts *UpdateContainerSubCommand) do(input cli.Input) error {
 func (opts *UpdateContainerSubCommand) complete(input cli.Input) error {
 	fnName := input.String(flagkey.FnName)
 
-	_, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in updating container for function ")
 	}
 
-	function, err := opts.Client().V1().Function().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.FnName),
-		Namespace: fnNamespace,
-	})
+	function, err := opts.Client().FissionClientSet.CoreV1().Functions(fnNamespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
+
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("read function '%v'", fnName))
 	}
@@ -84,10 +82,7 @@ func (opts *UpdateContainerSubCommand) complete(input cli.Input) error {
 
 		// check that the referenced secret is in the same ns as the function, if not give a warning.
 		for _, secretName := range secretNames {
-			err := opts.Client().V1().Misc().SecretExists(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      secretName,
-			})
+			err := util.SecretExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: secretName}, opts.Client().KubernetesClient)
 			if k8serrors.IsNotFound(err) {
 				console.Warn(fmt.Sprintf("secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
 			}
@@ -108,10 +103,7 @@ func (opts *UpdateContainerSubCommand) complete(input cli.Input) error {
 
 		// check that the referenced cfgmap is in the same ns as the function, if not give a warning.
 		for _, cfgMapName := range cfgMapNames {
-			err := opts.Client().V1().Misc().ConfigMapExists(&metav1.ObjectMeta{
-				Namespace: fnNamespace,
-				Name:      cfgMapName,
-			})
+			err := util.ConfigMapExists(input.Context(), &metav1.ObjectMeta{Namespace: fnNamespace, Name: cfgMapName}, opts.Client().KubernetesClient)
 			if k8serrors.IsNotFound(err) {
 				console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as the function", cfgMapName, fnNamespace))
 			}
@@ -192,7 +184,7 @@ func (opts *UpdateContainerSubCommand) complete(input cli.Input) error {
 }
 
 func (opts *UpdateContainerSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().Function().Update(opts.function)
+	_, err := opts.Client().FissionClientSet.CoreV1().Functions(opts.function.Namespace).Update(input.Context(), opts.function, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating function")
 	}
diff --git a/pkg/fission-cli/cmd/httptrigger/create.go b/pkg/fission-cli/cmd/httptrigger/create.go
index 77e42935..235d8899 100644
--- a/pkg/fission-cli/cmd/httptrigger/create.go
+++ b/pkg/fission-cli/cmd/httptrigger/create.go
@@ -24,10 +24,10 @@ import (
 
 	"github.com/pkg/errors"
 	uuid "github.com/satori/go.uuid"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	ferror "github.com/fission/fission/pkg/error"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec"
@@ -77,7 +77,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 		triggerName = id.String()
 	}
 
-	userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	userProvidedNS, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -129,11 +129,11 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 	// For Specs, the spec validate checks for function reference
 	if input.Bool(flagkey.SpecSave) {
 
-		htTrigger, err := opts.Client().V1().HTTPTrigger().Get(&m)
-		if err != nil && !ferror.IsNotFound(err) {
+		htTrigger, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(m.Namespace).Get(input.Context(), m.Name, metav1.GetOptions{})
+		if err != nil && !kerrors.IsNotFound(err) {
 			return err
 		}
-		if htTrigger != nil {
+		if htTrigger.Name != "" && htTrigger.Namespace != "" {
 			return errors.New("duplicate trigger exists, choose a different name or leave it empty for fission to auto-generate it")
 		}
 
@@ -164,16 +164,16 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 			Name:      triggerName,
 			Namespace: fnNamespace,
 		}
+		htTrigger, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(m.Namespace).Get(input.Context(), m.Name, metav1.GetOptions{})
 
-		htTrigger, err := opts.Client().V1().HTTPTrigger().Get(&m)
-		if err != nil && !ferror.IsNotFound(err) {
+		if err != nil && !kerrors.IsNotFound(err) {
 			return err
 		}
-		if htTrigger != nil {
+		if htTrigger != nil && htTrigger.Namespace != "" {
 			return errors.New("duplicate trigger exists, choose a different name or leave it empty for fission to auto-generate it")
 		}
 
-		err = util.CheckFunctionExistence(opts.Client(), functionList, fnNamespace)
+		err = util.CheckFunctionExistence(input.Context(), opts.Client(), functionList, fnNamespace)
 		if err != nil {
 			console.Warn(err.Error())
 		}
@@ -226,7 +226,13 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().HTTPTrigger().Create(opts.trigger)
+	// Ensure we don't have a duplicate HTTP route defined (same URL and method)
+	err := util.CheckHTTPTriggerDuplicates(input.Context(), opts.Client(), opts.trigger)
+	if err != nil {
+		return errors.Wrap(err, "Error while creating HTTP Trigger")
+	}
+
+	_, err = opts.Client().FissionClientSet.CoreV1().HTTPTriggers(opts.trigger.Namespace).Create(input.Context(), opts.trigger, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "create HTTP trigger")
 	}
diff --git a/pkg/fission-cli/cmd/httptrigger/delete.go b/pkg/fission-cli/cmd/httptrigger/delete.go
index 3f35b9bb..5f578923 100644
--- a/pkg/fission-cli/cmd/httptrigger/delete.go
+++ b/pkg/fission-cli/cmd/httptrigger/delete.go
@@ -58,7 +58,7 @@ func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 		return errors.Errorf("need either of --%v or --%v and not both arguments", flagkey.HtName, flagkey.HtFnName)
 	}
 
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -66,7 +66,7 @@ func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *DeleteSubCommand) run(input cli.Input) error {
-	triggers, err := opts.Client().V1().HTTPTrigger().List(opts.namespace)
+	triggers, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(opts.namespace).List(input.Context(), metav1.ListOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting HTTP trigger list")
 	}
@@ -74,7 +74,7 @@ func (opts *DeleteSubCommand) run(input cli.Input) error {
 	var triggersToDelete []string
 
 	if len(opts.functionName) > 0 {
-		for _, trigger := range triggers {
+		for _, trigger := range triggers.Items {
 			// TODO: delete canary http triggers as well.
 			if trigger.Spec.FunctionReference.Name == opts.functionName {
 				triggersToDelete = append(triggersToDelete, trigger.ObjectMeta.Name)
@@ -87,10 +87,7 @@ func (opts *DeleteSubCommand) run(input cli.Input) error {
 	errs := utils.MultiErrorWithFormat()
 
 	for _, name := range triggersToDelete {
-		err := opts.Client().V1().HTTPTrigger().Delete(&metav1.ObjectMeta{
-			Name:      name,
-			Namespace: opts.namespace,
-		})
+		err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(opts.namespace).Delete(input.Context(), name, metav1.DeleteOptions{})
 		if err != nil {
 			errs = multierror.Append(errs, err)
 		} else {
diff --git a/pkg/fission-cli/cmd/httptrigger/get.go b/pkg/fission-cli/cmd/httptrigger/get.go
index 77fb4511..c7f56e97 100644
--- a/pkg/fission-cli/cmd/httptrigger/get.go
+++ b/pkg/fission-cli/cmd/httptrigger/get.go
@@ -29,7 +29,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type GetSubCommand struct {
@@ -45,16 +44,12 @@ func (opts *GetSubCommand) do(input cli.Input) error {
 }
 
 func (opts *GetSubCommand) run(input cli.Input) (err error) {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
 
-	m := &metav1.ObjectMeta{
-		Name:      input.String(flagkey.HtName),
-		Namespace: namespace,
-	}
-	ht, err := opts.Client().V1().HTTPTrigger().Get(m)
+	ht, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(namespace).Get(input.Context(), input.String(flagkey.HtName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting http trigger")
 	}
diff --git a/pkg/fission-cli/cmd/httptrigger/list.go b/pkg/fission-cli/cmd/httptrigger/list.go
index cdbf9df9..de9b965a 100644
--- a/pkg/fission-cli/cmd/httptrigger/list.go
+++ b/pkg/fission-cli/cmd/httptrigger/list.go
@@ -18,12 +18,12 @@ package httptrigger
 
 import (
 	"github.com/pkg/errors"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -40,17 +40,15 @@ func (opts *ListSubCommand) do(input cli.Input) error {
 
 func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
 
-	var hts []fv1.HTTPTrigger
 	if input.Bool(flagkey.AllNamespaces) {
-		hts, err = opts.Client().V1().HTTPTrigger().List("")
-	} else {
-		hts, err = opts.Client().V1().HTTPTrigger().List(namespace)
+		namespace = v1.NamespaceAll
 	}
+	hts, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(namespace).List(input.Context(), v1.ListOptions{})
 
 	if err != nil {
 		return errors.Wrap(err, "error listing HTTP triggers")
@@ -59,7 +57,7 @@ func (opts *ListSubCommand) run(input cli.Input) (err error) {
 	filterFunctionName := input.String(flagkey.HtFnName)
 
 	var triggers []fv1.HTTPTrigger
-	for _, ht := range hts {
+	for _, ht := range hts.Items {
 		// TODO: list canary http triggers as well.
 		if len(filterFunctionName) == 0 ||
 			(len(filterFunctionName) > 0 && filterFunctionName == ht.Spec.FunctionReference.Name) {
diff --git a/pkg/fission-cli/cmd/httptrigger/update.go b/pkg/fission-cli/cmd/httptrigger/update.go
index 31010a93..b1357c79 100644
--- a/pkg/fission-cli/cmd/httptrigger/update.go
+++ b/pkg/fission-cli/cmd/httptrigger/update.go
@@ -51,15 +51,12 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 	htName := input.String(flagkey.HtName)
 
-	_, triggerNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, triggerNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
 
-	ht, err := opts.Client().V1().HTTPTrigger().Get(&metav1.ObjectMeta{
-		Name:      htName,
-		Namespace: triggerNamespace,
-	})
+	ht, err := opts.Client().FissionClientSet.CoreV1().HTTPTriggers(triggerNamespace).Get(input.Context(), htName, metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting HTTP trigger")
 	}
@@ -102,7 +99,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 	if input.IsSet(flagkey.HtFnName) {
 		// get the functions and their weights if specified
 		functionList := input.StringSlice(flagkey.HtFnName)
-		err := util.CheckFunctionExistence(opts.Client(), functionList, triggerNamespace)
+		err := util.CheckFunctionExistence(input.Context(), opts.Client(), functionList, triggerNamespace)
 		if err != nil {
 			console.Warn(err.Error())
 		}
@@ -151,7 +148,13 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().HTTPTrigger().Update(opts.trigger)
+
+	err := util.CheckHTTPTriggerDuplicates(input.Context(), opts.Client(), opts.trigger)
+	if err != nil {
+		return errors.Wrap(err, "Error while creating HTTP Trigger")
+	}
+
+	_, err = opts.Client().FissionClientSet.CoreV1().HTTPTriggers(opts.trigger.ObjectMeta.Namespace).Update(input.Context(), opts.trigger, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating the HTTP trigger")
 	}
diff --git a/pkg/fission-cli/cmd/kubewatch/create.go b/pkg/fission-cli/cmd/kubewatch/create.go
index 1c4ab2fa..0ba2c66a 100644
--- a/pkg/fission-cli/cmd/kubewatch/create.go
+++ b/pkg/fission-cli/cmd/kubewatch/create.go
@@ -61,7 +61,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 	}
 	fnName := input.String(flagkey.KwFnName)
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.KwNamespace)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.KwNamespace)
 	if err != nil {
 		return errors.Wrap(err, "error in listing function ")
 	}
@@ -126,7 +126,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().KubeWatcher().Create(opts.watcher)
+	_, err := opts.Client().FissionClientSet.CoreV1().KubernetesWatchTriggers(opts.watcher.ObjectMeta.Namespace).Create(input.Context(), opts.watcher, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating kubewatch")
 	}
diff --git a/pkg/fission-cli/cmd/kubewatch/delete.go b/pkg/fission-cli/cmd/kubewatch/delete.go
index ff351dd9..912b4a66 100644
--- a/pkg/fission-cli/cmd/kubewatch/delete.go
+++ b/pkg/fission-cli/cmd/kubewatch/delete.go
@@ -48,7 +48,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
 
 func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 	opts.name = input.String(flagkey.KwName)
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting kubewatch")
 	}
@@ -56,10 +56,7 @@ func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *DeleteSubCommand) run(input cli.Input) error {
-	err := opts.Client().V1().KubeWatcher().Delete(&metav1.ObjectMeta{
-		Name:      opts.name,
-		Namespace: opts.namespace,
-	})
+	err := opts.Client().FissionClientSet.CoreV1().KubernetesWatchTriggers(opts.namespace).Delete(input.Context(), opts.name, metav1.DeleteOptions{})
 	if err != nil {
 		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
 			return nil
diff --git a/pkg/fission-cli/cmd/kubewatch/list.go b/pkg/fission-cli/cmd/kubewatch/list.go
index 05531b51..a0e9d19d 100644
--- a/pkg/fission-cli/cmd/kubewatch/list.go
+++ b/pkg/fission-cli/cmd/kubewatch/list.go
@@ -22,12 +22,12 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -48,7 +48,7 @@ func (opts *ListSubCommand) do(input cli.Input) error {
 }
 
 func (opts *ListSubCommand) complete(input cli.Input) (err error) {
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error listing kubewatchers")
 	}
@@ -56,12 +56,12 @@ func (opts *ListSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *ListSubCommand) run(input cli.Input) (err error) {
-	var ws []v1.KubernetesWatchTrigger
+	var ws *v1.KubernetesWatchTriggerList
 	if input.Bool(flagkey.AllNamespaces) {
-		ws, err = opts.Client().V1().KubeWatcher().List("")
-	} else {
-		ws, err = opts.Client().V1().KubeWatcher().List(opts.namespace)
+		opts.namespace = metav1.NamespaceAll
 	}
+	ws, err = opts.Client().FissionClientSet.CoreV1().KubernetesWatchTriggers(opts.namespace).List(input.Context(), metav1.ListOptions{})
+
 	if err != nil {
 		return errors.Wrap(err, "error listing kubewatchers")
 	}
@@ -70,7 +70,7 @@ func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n",
 		"NAME", "NAMESPACE", "OBJTYPE", "LABELS", "FUNCTION_NAME")
-	for _, wa := range ws {
+	for _, wa := range ws.Items {
 		fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n",
 			wa.ObjectMeta.Name, wa.Spec.Namespace, wa.Spec.Type, wa.Spec.LabelSelector, wa.Spec.FunctionReference.Name)
 	}
diff --git a/pkg/fission-cli/cmd/mqtrigger/create.go b/pkg/fission-cli/cmd/mqtrigger/create.go
index ef614050..893fe870 100644
--- a/pkg/fission-cli/cmd/mqtrigger/create.go
+++ b/pkg/fission-cli/cmd/mqtrigger/create.go
@@ -62,7 +62,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 	}
 	fnName := input.String(flagkey.MqtFnName)
 
-	userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	userProvidedNS, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -151,7 +151,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
 				mqtName, fnName))
 		}
 	} else {
-		err = util.CheckFunctionExistence(opts.Client(), []string{fnName}, fnNamespace)
+		err = util.CheckFunctionExistence(input.Context(), opts.Client(), []string{fnName}, fnNamespace)
 		if err != nil {
 			return err
 		}
@@ -210,7 +210,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().MessageQueueTrigger().Create(opts.trigger)
+	_, err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(opts.trigger.ObjectMeta.Namespace).Create(input.Context(), opts.trigger, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "create message queue trigger")
 	}
diff --git a/pkg/fission-cli/cmd/mqtrigger/delete.go b/pkg/fission-cli/cmd/mqtrigger/delete.go
index a0ed824b..3302357c 100644
--- a/pkg/fission-cli/cmd/mqtrigger/delete.go
+++ b/pkg/fission-cli/cmd/mqtrigger/delete.go
@@ -20,12 +20,12 @@ import (
 	"fmt"
 
 	"github.com/pkg/errors"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type DeleteSubCommand struct {
@@ -47,7 +47,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
 
 func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -60,9 +60,9 @@ func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *DeleteSubCommand) run(input cli.Input) error {
-	err := opts.Client().V1().MessageQueueTrigger().Delete(opts.metadata)
+	err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(opts.metadata.Namespace).Delete(input.Context(), opts.metadata.Name, metav1.DeleteOptions{})
 	if err != nil {
-		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
+		if input.Bool(flagkey.IgnoreNotFound) && kerrors.IsNotFound(err) {
 			return nil
 		}
 		return errors.Wrap(err, "error deleting message queue trigger")
diff --git a/pkg/fission-cli/cmd/mqtrigger/list.go b/pkg/fission-cli/cmd/mqtrigger/list.go
index e0b3e953..0e30339e 100644
--- a/pkg/fission-cli/cmd/mqtrigger/list.go
+++ b/pkg/fission-cli/cmd/mqtrigger/list.go
@@ -22,12 +22,11 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -48,7 +47,7 @@ func (opts *ListSubCommand) do(input cli.Input) error {
 }
 
 func (opts *ListSubCommand) complete(input cli.Input) (err error) {
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -57,12 +56,11 @@ func (opts *ListSubCommand) complete(input cli.Input) (err error) {
 
 func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
-	var mqts []v1.MessageQueueTrigger
 	if input.Bool(flagkey.AllNamespaces) {
-		mqts, err = opts.Client().V1().MessageQueueTrigger().List(input.String(flagkey.MqtMQType), "")
-	} else {
-		mqts, err = opts.Client().V1().MessageQueueTrigger().List(input.String(flagkey.MqtMQType), opts.namespace)
+		opts.namespace = metav1.NamespaceAll
 	}
+	mqts, err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(opts.namespace).List(input.Context(), metav1.ListOptions{})
+
 	if err != nil {
 		return errors.Wrap(err, "error listing message queue triggers")
 	}
@@ -71,7 +69,7 @@ func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
 		"NAME", "FUNCTION_NAME", "MESSAGE_QUEUE_TYPE", "TOPIC", "RESPONSE_TOPIC", "ERROR_TOPIC", "MAX_RETRIES", "PUB_MSG_CONTENT_TYPE", "NAMESPACE")
-	for _, mqt := range mqts {
+	for _, mqt := range mqts.Items {
 		fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
 			mqt.ObjectMeta.Name, mqt.Spec.FunctionReference.Name, mqt.Spec.MessageQueueType, mqt.Spec.Topic, mqt.Spec.ResponseTopic, mqt.Spec.ErrorTopic, mqt.Spec.MaxRetries, mqt.Spec.ContentType, mqt.ObjectMeta.Namespace)
 	}
diff --git a/pkg/fission-cli/cmd/mqtrigger/update.go b/pkg/fission-cli/cmd/mqtrigger/update.go
index 5e88e81b..7c716041 100644
--- a/pkg/fission-cli/cmd/mqtrigger/update.go
+++ b/pkg/fission-cli/cmd/mqtrigger/update.go
@@ -48,15 +48,12 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 }
 
 func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
 
-	mqt, err := opts.Client().V1().MessageQueueTrigger().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.MqtName),
-		Namespace: namespace,
-	})
+	mqt, err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(namespace).Get(input.Context(), input.String(flagkey.MqtName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting message queue trigger")
 	}
@@ -100,7 +97,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 	}
 	if len(fnName) > 0 {
 		functionList := []string{fnName}
-		err := util.CheckFunctionExistence(opts.Client(), functionList, namespace)
+		err := util.CheckFunctionExistence(input.Context(), opts.Client(), functionList, namespace)
 		if err != nil {
 			console.Warn(err.Error())
 		}
@@ -151,7 +148,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().MessageQueueTrigger().Update(opts.trigger)
+	_, err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(opts.trigger.ObjectMeta.Namespace).Update(input.Context(), opts.trigger, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating message queue trigger")
 	}
diff --git a/pkg/fission-cli/cmd/package/create.go b/pkg/fission-cli/cmd/package/create.go
index 6f811cb9..23923a32 100644
--- a/pkg/fission-cli/cmd/package/create.go
+++ b/pkg/fission-cli/cmd/package/create.go
@@ -28,7 +28,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec"
@@ -65,7 +64,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 
 	envName := input.String(flagkey.PkgEnvironment)
 
-	userProvidedNS, pkgNamespace, err := util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	userProvidedNS, pkgNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -126,7 +125,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 }
 
 // TODO: get all necessary value from CLI input directly
-func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkgNamespace string, envName string,
+func CreatePackage(input cli.Input, client cmd.Client, pkgName string, pkgNamespace string, envName string,
 	srcArchiveFiles []string, deployArchiveFiles []string, buildcmd string, specDir string, specFile string, noZip bool, userProvidedNS string) (*metav1.ObjectMeta, error) {
 
 	insecure := input.Bool(flagkey.PkgInsecure)
@@ -224,11 +223,12 @@ func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkg
 		return &pkg.ObjectMeta, nil
 	} else {
 		pkg.ObjectMeta.Namespace = pkgNamespace
-		pkgMetadata, err := client.V1().Package().Create(pkg)
+
+		pkgMetadata, err := client.FissionClientSet.CoreV1().Packages(pkgNamespace).Create(input.Context(), pkg, metav1.CreateOptions{})
 		if err != nil {
 			return nil, errors.Wrap(err, "error creating package")
 		}
 		fmt.Printf("Package '%v' created\n", pkgMetadata.GetName())
-		return pkgMetadata, nil
+		return &pkgMetadata.ObjectMeta, nil
 	}
 }
diff --git a/pkg/fission-cli/cmd/package/delete.go b/pkg/fission-cli/cmd/package/delete.go
index 64f7fa69..a6e1d5da 100644
--- a/pkg/fission-cli/cmd/package/delete.go
+++ b/pkg/fission-cli/cmd/package/delete.go
@@ -17,17 +17,17 @@ limitations under the License.
 package _package
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/pkg/errors"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type DeleteSubCommand struct {
@@ -52,7 +52,7 @@ func (opts *DeleteSubCommand) do(input cli.Input) error {
 
 func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 	opts.name = input.String(flagkey.PkgName)
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -69,18 +69,15 @@ func (opts *DeleteSubCommand) complete(input cli.Input) (err error) {
 
 func (opts *DeleteSubCommand) run(input cli.Input) error {
 	if len(opts.name) != 0 {
-		_, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-			Namespace: opts.namespace,
-			Name:      opts.name,
-		})
+		_, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.namespace).Get(input.Context(), opts.name, metav1.GetOptions{})
 		if err != nil {
-			if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
+			if input.Bool(flagkey.IgnoreNotFound) && kerrors.IsNotFound(err) {
 				return nil
 			}
 			return errors.Wrap(err, "find package")
 		}
 
-		fnList, err := GetFunctionsByPackage(opts.Client(), opts.name, opts.namespace)
+		fnList, err := GetFunctionsByPackage(input.Context(), opts.Client(), opts.name, opts.namespace)
 		if err != nil {
 			return err
 		}
@@ -88,7 +85,7 @@ func (opts *DeleteSubCommand) run(input cli.Input) error {
 		if !opts.force && len(fnList) > 0 {
 			return errors.New("Package is used by at least one function, use -f to force delete")
 		}
-		err = deletePackage(opts.Client(), opts.name, opts.namespace)
+		err = deletePackage(input.Context(), opts.Client(), opts.name, opts.namespace)
 		if err != nil {
 			return err
 		}
@@ -97,7 +94,7 @@ func (opts *DeleteSubCommand) run(input cli.Input) error {
 
 	// TODO improve list speed when --orphan
 	if opts.deleteOrphans {
-		err := deleteOrphanPkgs(opts.Client(), opts.namespace)
+		err := deleteOrphanPkgs(input.Context(), opts.Client(), opts.namespace)
 		if err != nil {
 			return errors.Wrap(err, "deleting orphan packages")
 		}
@@ -107,20 +104,20 @@ func (opts *DeleteSubCommand) run(input cli.Input) error {
 	return nil
 }
 
-func deleteOrphanPkgs(client client.Interface, pkgNamespace string) error {
-	pkgList, err := client.V1().Package().List(pkgNamespace)
+func deleteOrphanPkgs(ctx context.Context, client cmd.Client, pkgNamespace string) error {
+	pkgList, err := client.FissionClientSet.CoreV1().Packages(pkgNamespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return err
 	}
 
 	// range through all packages and find out the ones not referenced by any function
-	for _, pkg := range pkgList {
-		fnList, err := GetFunctionsByPackage(client, pkg.ObjectMeta.Name, pkgNamespace)
+	for _, pkg := range pkgList.Items {
+		fnList, err := GetFunctionsByPackage(ctx, client, pkg.ObjectMeta.Name, pkgNamespace)
 		if err != nil {
 			return errors.Wrap(err, fmt.Sprintf("get functions sharing package %s", pkg.ObjectMeta.Name))
 		}
 		if len(fnList) == 0 {
-			err = deletePackage(client, pkg.ObjectMeta.Name, pkgNamespace)
+			err = deletePackage(ctx, client, pkg.ObjectMeta.Name, pkgNamespace)
 			if err != nil {
 				return err
 			}
@@ -129,9 +126,6 @@ func deleteOrphanPkgs(client client.Interface, pkgNamespace string) error {
 	return nil
 }
 
-func deletePackage(client client.Interface, pkgName string, pkgNamespace string) error {
-	return client.V1().Package().Delete(&metav1.ObjectMeta{
-		Namespace: pkgNamespace,
-		Name:      pkgName,
-	})
+func deletePackage(ctx context.Context, client cmd.Client, pkgName string, pkgNamespace string) error {
+	return client.FissionClientSet.CoreV1().Packages(pkgNamespace).Delete(ctx, pkgName, metav1.DeleteOptions{})
 }
diff --git a/pkg/fission-cli/cmd/package/get.go b/pkg/fission-cli/cmd/package/get.go
index 0f170b07..37c0a2a0 100644
--- a/pkg/fission-cli/cmd/package/get.go
+++ b/pkg/fission-cli/cmd/package/get.go
@@ -21,6 +21,7 @@ import (
 	"io"
 	"os"
 
+	"github.com/pkg/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
@@ -28,7 +29,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 const (
@@ -61,7 +61,7 @@ func (opts *GetSubCommand) do(input cli.Input) error {
 
 func (opts *GetSubCommand) complete(input cli.Input) (err error) {
 	opts.name = input.String(flagkey.PkgName)
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -70,10 +70,8 @@ func (opts *GetSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *GetSubCommand) run(input cli.Input) error {
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Namespace: opts.namespace,
-		Name:      opts.name,
-	})
+
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.namespace).Get(input.Context(), opts.name, metav1.GetOptions{})
 	if err != nil {
 		return err
 	}
@@ -87,10 +85,12 @@ func (opts *GetSubCommand) run(input cli.Input) error {
 	if pkg.Spec.Deployment.Type == fv1.ArchiveTypeLiteral {
 		reader = bytes.NewReader(archive.Literal)
 	} else if pkg.Spec.Deployment.Type == fv1.ArchiveTypeUrl {
-		readCloser, err := pkgutil.DownloadStoragesvcURL(opts.Client(), archive.URL)
+
+		readCloser, err := pkgutil.DownloadStrorageURL(input.Context(), opts.Client(), archive.URL)
 		if err != nil {
-			return err
+			return errors.Wrapf(err, "error downloading from storage service url: %s", archive.URL)
 		}
+
 		defer readCloser.Close()
 		reader = readCloser
 	}
diff --git a/pkg/fission-cli/cmd/package/info.go b/pkg/fission-cli/cmd/package/info.go
index 3e3258ce..f4f06f7c 100644
--- a/pkg/fission-cli/cmd/package/info.go
+++ b/pkg/fission-cli/cmd/package/info.go
@@ -27,7 +27,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type InfoSubCommand struct {
@@ -51,7 +50,7 @@ func (opts *InfoSubCommand) do(input cli.Input) error {
 func (opts *InfoSubCommand) complete(input cli.Input) (err error) {
 	opts.name = input.String(flagkey.PkgName)
 
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -59,10 +58,11 @@ func (opts *InfoSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *InfoSubCommand) run(input cli.Input) error {
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Namespace: opts.namespace,
-		Name:      opts.name,
-	})
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.namespace).Get(input.Context(), opts.name, metav1.GetOptions{})
+	if err != nil {
+		return err
+	}
+
 	if err != nil {
 		return errors.Wrapf(err, "error finding package %s", opts.name)
 	}
diff --git a/pkg/fission-cli/cmd/package/list.go b/pkg/fission-cli/cmd/package/list.go
index 21c01dcd..ac872c28 100644
--- a/pkg/fission-cli/cmd/package/list.go
+++ b/pkg/fission-cli/cmd/package/list.go
@@ -24,12 +24,12 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -55,7 +55,7 @@ func (opts *ListSubCommand) complete(input cli.Input) (err error) {
 	// option for the user to list all orphan packages (not referenced by any function)
 	opts.listOrphans = input.Bool(flagkey.PkgOrphan)
 	opts.status = input.String(flagkey.PkgStatus)
-	_, opts.pkgNamespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.pkgNamespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -64,29 +64,28 @@ func (opts *ListSubCommand) complete(input cli.Input) (err error) {
 
 func (opts *ListSubCommand) run(input cli.Input) (err error) {
 
-	var pkgList []fv1.Package
 	if input.Bool(flagkey.AllNamespaces) {
-		pkgList, err = opts.Client().V1().Package().List("")
-	} else {
-		pkgList, err = opts.Client().V1().Package().List(opts.pkgNamespace)
+		opts.pkgNamespace = v1.NamespaceAll
 	}
+	pkgList, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.pkgNamespace).List(input.Context(), v1.ListOptions{})
+
 	if err != nil {
 		return err
 	}
 
 	// sort the package list by lastUpdatedTimestamp
-	sort.Slice(pkgList, func(i, j int) bool {
-		return pkgList[i].Status.LastUpdateTimestamp.After(pkgList[j].Status.LastUpdateTimestamp.Time)
+	sort.Slice(pkgList.Items, func(i, j int) bool {
+		return pkgList.Items[i].Status.LastUpdateTimestamp.After(pkgList.Items[j].Status.LastUpdateTimestamp.Time)
 	})
 
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
 	fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", "NAME", "BUILD_STATUS", "ENV", "LASTUPDATEDAT", "NAMESPACE")
 
-	for _, pkg := range pkgList {
+	for _, pkg := range pkgList.Items {
 		show := true
 		// TODO improve list speed when --orphan
 		if opts.listOrphans {
-			fnList, err := GetFunctionsByPackage(opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
+			fnList, err := GetFunctionsByPackage(input.Context(), opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
 			if err != nil {
 				return errors.Wrap(err, fmt.Sprintf("get functions sharing package %s", pkg.ObjectMeta.Name))
 			}
diff --git a/pkg/fission-cli/cmd/package/package.go b/pkg/fission-cli/cmd/package/package.go
index 83f2a1aa..5f1d7101 100644
--- a/pkg/fission-cli/cmd/package/package.go
+++ b/pkg/fission-cli/cmd/package/package.go
@@ -17,6 +17,7 @@ limitations under the License.
 package _package
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"os"
@@ -27,10 +28,11 @@ import (
 	"github.com/hashicorp/go-multierror"
 	"github.com/pkg/errors"
 	uuid "github.com/satori/go.uuid"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec"
 	spectypes "github.com/fission/fission/pkg/fission-cli/cmd/spec/types"
@@ -44,7 +46,7 @@ import (
 // create an archive upload spec in the specs directory; otherwise
 // upload the archive using client.  noZip avoids zipping the
 // includeFiles, but is ignored if there's more than one includeFile.
-func CreateArchive(client client.Interface, input cli.Input, includeFiles []string, noZip bool, insecure bool, checksum string, specDir string, specFile string) (*fv1.Archive, error) {
+func CreateArchive(client cmd.Client, input cli.Input, includeFiles []string, noZip bool, insecure bool, checksum string, specDir string, specFile string) (*fv1.Archive, error) {
 	// get root dir
 	var rootDir string
 	var err error
@@ -251,13 +253,13 @@ func archiveName(givenNameHint string, includedFiles []string) string {
 	return fmt.Sprintf("%v-%v", util.KubifyName(includedFiles[0]), uniuri.NewLen(4))
 }
 
-func GetFunctionsByPackage(client client.Interface, pkgName, pkgNamespace string) ([]fv1.Function, error) {
-	fnList, err := client.V1().Function().List(pkgNamespace)
+func GetFunctionsByPackage(ctx context.Context, client cmd.Client, pkgName, pkgNamespace string) ([]fv1.Function, error) {
+	fnList, err := client.FissionClientSet.CoreV1().Functions(pkgNamespace).List(ctx, v1.ListOptions{})
 	if err != nil {
 		return nil, err
 	}
 	fns := []fv1.Function{}
-	for _, fn := range fnList {
+	for _, fn := range fnList.Items {
 		if fn.Spec.Package.PackageRef.Name == pkgName {
 			fns = append(fns, fn)
 		}
diff --git a/pkg/fission-cli/cmd/package/rebuild.go b/pkg/fission-cli/cmd/package/rebuild.go
index 0e9d61cb..4d4b6e54 100644
--- a/pkg/fission-cli/cmd/package/rebuild.go
+++ b/pkg/fission-cli/cmd/package/rebuild.go
@@ -26,7 +26,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type RebuildSubCommand struct {
@@ -49,7 +48,7 @@ func (opts *RebuildSubCommand) do(input cli.Input) error {
 
 func (opts *RebuildSubCommand) complete(input cli.Input) (err error) {
 	opts.name = input.String(flagkey.PkgName)
-	_, opts.namespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.namespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -57,10 +56,10 @@ func (opts *RebuildSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *RebuildSubCommand) run(input cli.Input) error {
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Name:      opts.name,
-		Namespace: opts.namespace,
-	})
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.namespace).Get(input.Context(), opts.name, metav1.GetOptions{})
+	if err != nil {
+		return err
+	}
 	if err != nil {
 		return errors.Wrap(err, "find package")
 	}
@@ -70,7 +69,7 @@ func (opts *RebuildSubCommand) run(input cli.Input) error {
 			pkg.ObjectMeta.Name, fv1.BuildStatusFailed))
 	}
 
-	_, err = updatePackageStatus(opts.Client(), pkg, fv1.BuildStatusPending)
+	_, err = updatePackageStatus(input.Context(), opts.Client(), pkg, fv1.BuildStatusPending)
 	if err != nil {
 		return errors.Wrap(err, "update package status")
 	}
diff --git a/pkg/fission-cli/cmd/package/update.go b/pkg/fission-cli/cmd/package/update.go
index 7ff2da7e..faed8dae 100644
--- a/pkg/fission-cli/cmd/package/update.go
+++ b/pkg/fission-cli/cmd/package/update.go
@@ -17,6 +17,7 @@ limitations under the License.
 package _package
 
 import (
+	"context"
 	"fmt"
 	"time"
 
@@ -25,11 +26,9 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type UpdateSubCommand struct {
@@ -53,7 +52,7 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 
 func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 	opts.pkgName = input.String(flagkey.PkgName)
-	_, opts.pkgNamespace, err = util.GetResourceNamespace(input, flagkey.NamespacePackage)
+	_, opts.pkgNamespace, err = opts.GetResourceNamespace(input, flagkey.NamespacePackage)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -62,17 +61,17 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	pkg, err := opts.Client().V1().Package().Get(&metav1.ObjectMeta{
-		Namespace: opts.pkgNamespace,
-		Name:      opts.pkgName,
-	})
+	pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.pkgNamespace).Get(input.Context(), opts.pkgName, metav1.GetOptions{})
+	if err != nil {
+		return err
+	}
 	if err != nil {
 		return errors.Wrap(err, "get package")
 	}
 
 	forceUpdate := input.Bool(flagkey.PkgForce)
 
-	fnList, err := GetFunctionsByPackage(opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
+	fnList, err := GetFunctionsByPackage(input.Context(), opts.Client(), pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)
 	if err != nil {
 		return errors.Wrap(err, "error getting function list")
 	}
@@ -87,7 +86,7 @@ func (opts *UpdateSubCommand) run(input cli.Input) error {
 	}
 
 	if pkg.ObjectMeta.ResourceVersion != newPkgMeta.ResourceVersion {
-		err = UpdateFunctionPackageResourceVersion(opts.Client(), newPkgMeta, fnList...)
+		err = UpdateFunctionPackageResourceVersion(input.Context(), opts.Client(), newPkgMeta, fnList...)
 		if err != nil {
 			return errors.Wrap(err, "error updating function package reference resource version")
 		}
@@ -96,7 +95,7 @@ func (opts *UpdateSubCommand) run(input cli.Input) error {
 	return nil
 }
 
-func UpdatePackage(input cli.Input, client client.Interface, pkg *fv1.Package) (*metav1.ObjectMeta, error) {
+func UpdatePackage(input cli.Input, client cmd.Client, pkg *fv1.Package) (*metav1.ObjectMeta, error) {
 	envName := input.String(flagkey.PkgEnvironment)
 	srcArchiveFiles := input.StringSlice(flagkey.PkgSrcArchive)
 	deployArchiveFiles := input.StringSlice(flagkey.PkgDeployArchive)
@@ -175,23 +174,23 @@ func UpdatePackage(input cli.Input, client client.Interface, pkg *fv1.Package) (
 		}
 	}
 
-	newPkgMeta, err := client.V1().Package().Update(pkg)
+	newPkgMeta, err := client.FissionClientSet.CoreV1().Packages(pkg.ObjectMeta.Namespace).Update(input.Context(), pkg, metav1.UpdateOptions{})
 	if err != nil {
 		return nil, errors.Wrap(err, "update package")
 	}
 
 	fmt.Printf("Package '%v' updated\n", newPkgMeta.GetName())
 
-	return newPkgMeta, err
+	return &newPkgMeta.ObjectMeta, err
 }
 
-func UpdateFunctionPackageResourceVersion(client client.Interface, pkgMeta *metav1.ObjectMeta, fnList ...fv1.Function) error {
+func UpdateFunctionPackageResourceVersion(ctx context.Context, client cmd.Client, pkgMeta *metav1.ObjectMeta, fnList ...fv1.Function) error {
 	errs := &multierror.Error{}
 
 	// update resource version of package reference of functions that shared the same package
 	for _, fn := range fnList {
 		fn.Spec.Package.PackageRef.ResourceVersion = pkgMeta.ResourceVersion
-		_, err := client.V1().Function().Update(&fn)
+		_, err := client.FissionClientSet.CoreV1().Functions(fn.ObjectMeta.Namespace).Update(ctx, &fn, metav1.UpdateOptions{})
 		if err != nil {
 			errs = multierror.Append(errs, errors.Wrapf(err, "error updating package resource version of function '%v'", fn.ObjectMeta.Name))
 		}
@@ -200,15 +199,15 @@ func UpdateFunctionPackageResourceVersion(client client.Interface, pkgMeta *meta
 	return errs.ErrorOrNil()
 }
 
-func updatePackageStatus(client client.Interface, pkg *fv1.Package, status fv1.BuildStatus) (*metav1.ObjectMeta, error) {
+func updatePackageStatus(ctx context.Context, client cmd.Client, pkg *fv1.Package, status fv1.BuildStatus) (*metav1.ObjectMeta, error) {
 	switch status {
 	case fv1.BuildStatusNone, fv1.BuildStatusPending, fv1.BuildStatusRunning, fv1.BuildStatusSucceeded, fv1.CanaryConfigStatusAborted:
 		pkg.Status = fv1.PackageStatus{
 			BuildStatus:         status,
 			LastUpdateTimestamp: metav1.Time{Time: time.Now().UTC()},
 		}
-		pkg, err := client.V1().Package().Update(pkg)
-		return pkg, err
+		pkg, err := client.FissionClientSet.CoreV1().Packages(pkg.Namespace).Update(ctx, pkg, metav1.UpdateOptions{})
+		return &pkg.ObjectMeta, err
 	}
 	return nil, errors.New("unknown package status")
 }
diff --git a/pkg/fission-cli/cmd/package/util/util.go b/pkg/fission-cli/cmd/package/util/util.go
index c8c36f29..8ebcdd2d 100644
--- a/pkg/fission-cli/cmd/package/util/util.go
+++ b/pkg/fission-cli/cmd/package/util/util.go
@@ -31,11 +31,13 @@ import (
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/controller/client"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
+	"github.com/fission/fission/pkg/fission-cli/util"
 	storageSvcClient "github.com/fission/fission/pkg/storagesvc/client"
 	"github.com/fission/fission/pkg/utils"
 )
 
-func UploadArchiveFile(ctx context.Context, client client.Interface, fileName string) (*fv1.Archive, error) {
+func UploadArchiveFile(ctx context.Context, client cmd.Client, fileName string) (*fv1.Archive, error) {
 	var archive fv1.Archive
 
 	size, err := utils.FileSize(fileName)
@@ -50,25 +52,23 @@ func UploadArchiveFile(ctx context.Context, client client.Interface, fileName st
 			return nil, err
 		}
 	} else {
-		u := strings.TrimSuffix(client.ServerURL(), "/") + "/proxy/storage"
-		ssClient := storageSvcClient.MakeClient(u)
 
-		// TODO add a progress bar
-		id, err := ssClient.Upload(ctx, fileName, nil)
+		storagesvcURL, err := util.GetStorageURL(ctx, client)
 		if err != nil {
-			return nil, errors.Wrapf(err, "error uploading file %v", fileName)
+			return nil, errors.Wrapf(err, "error getting fission storage service URL")
 		}
 
-		storageSvc, err := client.V1().Misc().GetSvcURL("application=fission-storage")
-		storageSvcURL := "http://" + storageSvc
+		storageClient := storageSvcClient.MakeClient(storagesvcURL.String())
+		// TODO add a progress bar
+		id, err := storageClient.Upload(ctx, fileName, nil)
 		if err != nil {
-			return nil, errors.Wrapf(err, "error getting fission storage service name")
+			return nil, errors.Wrapf(err, "error uploading to fission storage service")
 		}
 
-		// We make a new client with actual URL of Storage service so that the URL is not
-		// pointing to 127.0.0.1 i.e. proxy. DON'T reuse previous ssClient
-		pkgClient := storageSvcClient.MakeClient(storageSvcURL)
-		archiveURL := pkgClient.GetUrl(id)
+		archiveURL, err := getArchiveURL(ctx, client, id, storagesvcURL)
+		if err != nil {
+			return nil, errors.Wrapf(err, "could not get URL of archive")
+		}
 
 		archive.Type = fv1.ArchiveTypeUrl
 		archive.URL = archiveURL
@@ -84,6 +84,42 @@ func UploadArchiveFile(ctx context.Context, client client.Interface, fileName st
 	return &archive, nil
 }
 
+func getArchiveURL(ctx context.Context, client cmd.Client, archiveID string, serverURL *url.URL) (archiveURL string, err error) {
+	relativeURL, _ := url.Parse(util.FISSION_STORAGE_URI)
+
+	queryString := relativeURL.Query()
+	queryString.Set("id", archiveID)
+	relativeURL.RawQuery = queryString.Encode()
+
+	storageAccessURL := serverURL.ResolveReference(relativeURL)
+
+	resp, err := http.Head(storageAccessURL.String())
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return "", fmt.Errorf("error getting URL. Exited with Status:  %s", resp.Status)
+	}
+
+	storageType := resp.Header.Get("X-FISSION-STORAGETYPE")
+
+	if storageType == "local" {
+		storageSvc, err := util.GetSvcName(ctx, client.KubernetesClient, "fission-storage")
+		if err != nil {
+			return "", err
+		}
+		storagesvcURL := "http://" + storageSvc
+		client := storageSvcClient.MakeClient(storagesvcURL)
+		return client.GetUrl(archiveID), nil
+	} else if storageType == "s3" {
+		storageBucket := resp.Header.Get("X-FISSION-BUCKET")
+		s3url := fmt.Sprintf("https://%s.s3.amazonaws.com/%s", storageBucket, archiveID)
+		return s3url, nil
+	}
+	return "", nil
+}
 func GetContents(filePath string) ([]byte, error) {
 	code, err := os.ReadFile(filePath)
 	if err != nil {
@@ -133,6 +169,42 @@ func DownloadURL(fileUrl string) (io.ReadCloser, error) {
 	return resp.Body, nil
 }
 
+func DownloadStrorageURL(ctx context.Context, client cmd.Client, fileUrl string) (io.ReadCloser, error) {
+	var resp *http.Response
+	storageSvc, err := util.GetSvcName(ctx, client.KubernetesClient, "fission-storage")
+	if err != nil {
+		return nil, err
+	}
+
+	if strings.HasPrefix(fileUrl, "http://"+storageSvc+"/v1/archive?id=") {
+		url, err := url.Parse(fileUrl)
+		if err != nil {
+			return nil, err
+		}
+		id := url.Query().Get("id")
+		storageAccessURL, err := util.GetStorageURL(ctx, client)
+		if err != nil {
+			return nil, err
+		}
+
+		client := storageSvcClient.MakeClient(storageAccessURL.String())
+		resp, err = client.GetFile(ctx, id)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		resp, err = http.Get(fileUrl)
+	}
+
+	if err != nil {
+		return nil, err
+	}
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("%v - HTTP response returned non 200 status", resp.StatusCode)
+	}
+	return resp.Body, nil
+}
+
 func WriteArchiveToFile(fileName string, reader io.Reader) error {
 	tmpDir, err := utils.GetTempDir()
 	if err != nil {
diff --git a/pkg/fission-cli/cmd/spec/apply.go b/pkg/fission-cli/cmd/spec/apply.go
index 1313d07a..377e80cf 100644
--- a/pkg/fission-cli/cmd/spec/apply.go
+++ b/pkg/fission-cli/cmd/spec/apply.go
@@ -32,7 +32,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
@@ -71,7 +70,7 @@ func (opts *ApplySubCommand) do(input cli.Input) error {
 func (opts *ApplySubCommand) insertNamespace(input cli.Input, fr *FissionResources) error {
 
 	result := utils.MultiErrorWithFormat()
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -196,7 +195,7 @@ func (opts *ApplySubCommand) run(input cli.Input) error {
 		}
 
 		// make changes to the cluster based on the specs
-		pkgMetas, as, err := applyResources(input.Context(), opts.Client(), specDir, fr, deleteResources, input.Bool(flagkey.SpecAllowConflicts))
+		pkgMetas, as, err := applyResources(input, opts.Client(), specDir, fr, deleteResources, input.Bool(flagkey.SpecAllowConflicts))
 		if err != nil {
 			return errors.Wrap(err, "error applying specs")
 		}
@@ -349,7 +348,7 @@ func pluralize(num int, word string) string {
 }
 
 // applyArchives figures out the set of archives that need to be uploaded, and uploads them.
-func applyArchives(ctx context.Context, fclient client.Interface, specDir string, fr *FissionResources) error {
+func applyArchives(input cli.Input, fclient cmd.Client, specDir string, fr *FissionResources) error {
 
 	// archive:// URL -> archive map.
 	archiveFiles := make(map[string]fv1.Archive)
@@ -369,11 +368,11 @@ func applyArchives(ctx context.Context, fclient client.Interface, specDir string
 
 	// get list of packages, make content-indexed map of available archives
 	availableArchives := make(map[string]string) // (sha256 -> url)
-	pkgs, err := fclient.V1().Package().List(metav1.NamespaceAll)
+	pkgs, err := fclient.FissionClientSet.CoreV1().Packages(metav1.NamespaceAll).List(input.Context(), metav1.ListOptions{})
 	if err != nil {
 		return err
 	}
-	for _, pkg := range pkgs {
+	for _, pkg := range pkgs.Items {
 		for _, ar := range []fv1.Archive{pkg.Spec.Source, pkg.Spec.Deployment} {
 			if ar.Type == fv1.ArchiveTypeUrl && len(ar.URL) > 0 {
 				availableArchives[ar.Checksum.Sum] = ar.URL
@@ -395,7 +394,7 @@ func applyArchives(ctx context.Context, fclient client.Interface, specDir string
 			// doesn't exist, upload
 			fmt.Printf("uploading archive %v\n", name)
 			// ar.URL is actually a local filename at this stage
-			uploadedAr, err := pkgutil.UploadArchiveFile(ctx, fclient, ar.URL)
+			uploadedAr, err := pkgutil.UploadArchiveFile(input.Context(), fclient, ar.URL)
 			if err != nil {
 				return err
 			}
@@ -422,23 +421,23 @@ func applyArchives(ctx context.Context, fclient client.Interface, specDir string
 }
 
 // applyResources applies the given set of fission resources.
-func applyResources(ctx context.Context, fclient client.Interface, specDir string, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, map[string]ResourceApplyStatus, error) {
+func applyResources(input cli.Input, fclient cmd.Client, specDir string, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, map[string]ResourceApplyStatus, error) {
 
 	applyStatus := make(map[string]ResourceApplyStatus)
 
 	// upload archives that need to be uploaded. Changes archive references in fr.Packages.
-	err := applyArchives(ctx, fclient, specDir, fr)
+	err := applyArchives(input, fclient, specDir, fr)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	_, ras, err := applyEnvironments(fclient, fr, delete, specAllowConflicts)
+	_, ras, err := applyEnvironments(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "environment apply failed")
 	}
 	applyStatus["environment"] = *ras
 
-	pkgMeta, ras, err := applyPackages(fclient, fr, delete, specAllowConflicts)
+	pkgMeta, ras, err := applyPackages(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "package apply failed")
 	}
@@ -467,31 +466,31 @@ func applyResources(ctx context.Context, fclient client.Interface, specDir strin
 		fr.Functions[i].Spec.Package.PackageRef.ResourceVersion = m.ResourceVersion
 	}
 
-	_, ras, err = applyFunctions(fclient, fr, delete, specAllowConflicts)
+	_, ras, err = applyFunctions(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "function apply failed")
 	}
 	applyStatus["function"] = *ras
 
-	_, ras, err = applyHTTPTriggers(fclient, fr, delete, specAllowConflicts)
+	_, ras, err = applyHTTPTriggers(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "HTTPTrigger apply failed")
 	}
 	applyStatus["HTTPTrigger"] = *ras
 
-	_, ras, err = applyKubernetesWatchTriggers(fclient, fr, delete, specAllowConflicts)
+	_, ras, err = applyKubernetesWatchTriggers(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "KubernetesWatchTrigger apply failed")
 	}
 	applyStatus["KubernetesWatchTrigger"] = *ras
 
-	_, ras, err = applyTimeTriggers(fclient, fr, delete, specAllowConflicts)
+	_, ras, err = applyTimeTriggers(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "TimeTrigger apply failed")
 	}
 	applyStatus["TimeTrigger"] = *ras
 
-	_, ras, err = applyMessageQueueTriggers(fclient, fr, delete, specAllowConflicts)
+	_, ras, err = applyMessageQueueTriggers(input.Context(), fclient, fr, delete, specAllowConflicts)
 	if err != nil {
 		return nil, nil, errors.Wrap(err, "MessageQueueTrigger apply failed")
 	}
@@ -626,7 +625,7 @@ func hasDeploymentConfig(m *metav1.ObjectMeta, fr *FissionResources) bool {
 	return false
 }
 
-func waitForPackageBuild(fclient client.Interface, pkg *fv1.Package) (*fv1.Package, error) {
+func waitForPackageBuild(ctx context.Context, fclient cmd.Client, pkg *fv1.Package) (*fv1.Package, error) {
 	start := time.Now()
 	for {
 		if pkg.Status.BuildStatus != fv1.BuildStatusRunning {
@@ -640,16 +639,16 @@ func waitForPackageBuild(fclient client.Interface, pkg *fv1.Package) (*fv1.Packa
 		time.Sleep(time.Second)
 
 		var err error
-		pkg, err = fclient.V1().Package().Get(&pkg.ObjectMeta)
+		pkg, err = fclient.FissionClientSet.CoreV1().Packages(pkg.ObjectMeta.Namespace).Get(ctx, pkg.ObjectMeta.Name, metav1.GetOptions{})
 		if err != nil {
 			return nil, err
 		}
 	}
 }
 
-func applyPackages(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyPackages(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().Package().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().Packages(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -657,9 +656,9 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
 	// filter
 	objs := make([]fv1.Package, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -711,7 +710,7 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
 				// We may be racing against the package builder to update the
 				// package (a previous version might have been getting built).  So,
 				// wait for the package to have a non-running build status.
-				pkg, err := waitForPackageBuild(fclient, &o)
+				pkg, err := waitForPackageBuild(ctx, fclient, &o)
 				if err != nil {
 					// log and ignore
 					console.Warn(fmt.Sprintf("Error waiting for package '%v' build, ignoring", o.ObjectMeta.Name))
@@ -723,23 +722,24 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
 					pkg.Status.BuildStatus = fv1.BuildStatusPending
 				}
 
-				newmeta, err := fclient.V1().Package().Update(pkg)
+				newmeta, err := fclient.FissionClientSet.CoreV1().Packages(pkg.ObjectMeta.Namespace).Update(ctx, pkg, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 					// TODO check for resourceVersion conflict errors and retry
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
+
 			// create
-			newmeta, err := fclient.V1().Package().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().Packages(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -749,7 +749,7 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().Package().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().Packages(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -762,9 +762,9 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool,
 	return metadataMap, &ras, nil
 }
 
-func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyFunctions(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().Function().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -772,9 +772,9 @@ func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool,
 	// filter
 	objs := make([]fv1.Function, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -811,22 +811,22 @@ func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool,
 			} else {
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().Function().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().Functions(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
 			// create
-			newmeta, err := fclient.V1().Function().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().Functions(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -836,7 +836,7 @@ func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool,
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().Function().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().Functions(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -849,9 +849,9 @@ func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool,
 	return metadataMap, &ras, nil
 }
 
-func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyEnvironments(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().Environment().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().Environments(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -859,9 +859,9 @@ func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bo
 	// filter
 	objs := make([]fv1.Environment, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -898,22 +898,22 @@ func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bo
 			} else {
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().Environment().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().Environments(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
 			// create
-			newmeta, err := fclient.V1().Environment().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().Environments(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -923,7 +923,7 @@ func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bo
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().Environment().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().Environments(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Namespace, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -936,9 +936,9 @@ func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bo
 	return metadataMap, &ras, nil
 }
 
-func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyHTTPTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().HTTPTrigger().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().HTTPTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -946,9 +946,9 @@ func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bo
 	// filter
 	objs := make([]fv1.HTTPTrigger, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -983,24 +983,34 @@ func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bo
 				// nothing to do on the server
 				metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
 			} else {
+
+				err := util.CheckHTTPTriggerDuplicates(ctx, fclient, &o)
+				if err != nil {
+					return nil, nil, err
+				}
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().HTTPTrigger().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().HTTPTriggers(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
+
+			err := util.CheckHTTPTriggerDuplicates(ctx, fclient, &o)
+			if err != nil {
+				return nil, nil, err
+			}
 			// create
-			newmeta, err := fclient.V1().HTTPTrigger().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().HTTPTriggers(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -1010,7 +1020,7 @@ func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bo
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().HTTPTrigger().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().HTTPTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -1023,9 +1033,9 @@ func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bo
 	return metadataMap, &ras, nil
 }
 
-func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyKubernetesWatchTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().KubeWatcher().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().KubernetesWatchTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -1033,9 +1043,9 @@ func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources
 	// filter
 	objs := make([]fv1.KubernetesWatchTrigger, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -1072,22 +1082,22 @@ func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources
 			} else {
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().KubeWatcher().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().KubernetesWatchTriggers(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
 			// create
-			newmeta, err := fclient.V1().KubeWatcher().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().KubernetesWatchTriggers(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -1097,7 +1107,7 @@ func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().KubeWatcher().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().KubernetesWatchTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -1110,9 +1120,9 @@ func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources
 	return metadataMap, &ras, nil
 }
 
-func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyTimeTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().TimeTrigger().List(metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().TimeTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -1120,9 +1130,9 @@ func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bo
 	// filter
 	objs := make([]fv1.TimeTrigger, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -1159,22 +1169,22 @@ func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bo
 			} else {
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().TimeTrigger().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().TimeTriggers(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
 			// create
-			newmeta, err := fclient.V1().TimeTrigger().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().TimeTriggers(o.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -1184,7 +1194,7 @@ func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bo
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().TimeTrigger().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().TimeTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
@@ -1197,9 +1207,9 @@ func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bo
 	return metadataMap, &ras, nil
 }
 
-func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
+func applyMessageQueueTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources, delete bool, specAllowConflicts bool) (map[string]metav1.ObjectMeta, *ResourceApplyStatus, error) {
 	// get list
-	allObjs, err := fclient.V1().MessageQueueTrigger().List("", metav1.NamespaceAll)
+	allObjs, err := fclient.FissionClientSet.CoreV1().MessageQueueTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, nil, err
 	}
@@ -1207,9 +1217,9 @@ func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, d
 	// filter
 	objs := make([]fv1.MessageQueueTrigger, 0)
 	if specAllowConflicts {
-		objs = allObjs
+		objs = allObjs.Items
 	} else {
-		for _, o := range allObjs {
+		for _, o := range allObjs.Items {
 			if hasDeploymentConfig(&o.ObjectMeta, fr) {
 				objs = append(objs, o)
 			}
@@ -1246,22 +1256,22 @@ func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, d
 			} else {
 				// update
 				o.ObjectMeta.ResourceVersion = existingObj.ObjectMeta.ResourceVersion
-				newmeta, err := fclient.V1().MessageQueueTrigger().Update(&o)
+				newmeta, err := fclient.FissionClientSet.CoreV1().MessageQueueTriggers(o.ObjectMeta.Namespace).Update(ctx, &o, metav1.UpdateOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
-				ras.Updated = append(ras.Updated, newmeta)
+				ras.Updated = append(ras.Updated, &newmeta.ObjectMeta)
 				// keep track of metadata in case we need to create a reference to it
-				metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+				metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 			}
 		} else {
 			// create
-			newmeta, err := fclient.V1().MessageQueueTrigger().Create(&o)
+			newmeta, err := fclient.FissionClientSet.CoreV1().MessageQueueTriggers(o.ObjectMeta.Namespace).Create(ctx, &o, metav1.CreateOptions{})
 			if err != nil {
 				return nil, nil, err
 			}
-			ras.Created = append(ras.Created, newmeta)
-			metadataMap[mapKey(&o.ObjectMeta)] = *newmeta
+			ras.Created = append(ras.Created, &newmeta.ObjectMeta)
+			metadataMap[mapKey(&o.ObjectMeta)] = newmeta.ObjectMeta
 		}
 	}
 
@@ -1271,7 +1281,7 @@ func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, d
 		for _, o := range objs {
 			_, wanted := desired[mapKey(&o.ObjectMeta)]
 			if !wanted {
-				err := fclient.V1().MessageQueueTrigger().Delete(&o.ObjectMeta)
+				err := fclient.FissionClientSet.CoreV1().MessageQueueTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 				if err != nil {
 					return nil, nil, err
 				}
diff --git a/pkg/fission-cli/cmd/spec/buildwatch.go b/pkg/fission-cli/cmd/spec/buildwatch.go
index 69f29bec..e752467d 100644
--- a/pkg/fission-cli/cmd/spec/buildwatch.go
+++ b/pkg/fission-cli/cmd/spec/buildwatch.go
@@ -25,7 +25,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/package/util"
 )
 
@@ -33,8 +33,7 @@ type (
 	// packageBuildWatcher is used to watch a set of in-progress builds.
 	packageBuildWatcher struct {
 		// fission client
-		fclient client.Interface
-
+		fclient cmd.Client
 		// set of packages already printed, ensures we don't duplicate the notifications
 		finished map[string]bool
 
@@ -43,7 +42,7 @@ type (
 	}
 )
 
-func makePackageBuildWatcher(fclient client.Interface) *packageBuildWatcher {
+func makePackageBuildWatcher(fclient cmd.Client) *packageBuildWatcher {
 	return &packageBuildWatcher{
 		fclient:  fclient,
 		finished: make(map[string]bool),
@@ -67,7 +66,7 @@ func (w *packageBuildWatcher) watch(ctx context.Context) {
 		}
 
 		// pull list of packages (TODO: convert to watch)
-		pkgs, err := w.fclient.V1().Package().List(metav1.NamespaceAll)
+		pkgs, err := w.fclient.FissionClientSet.CoreV1().Packages(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			fmt.Printf("Getting list of packages: %v", err)
 			os.Exit(1)
@@ -77,7 +76,7 @@ func (w *packageBuildWatcher) watch(ctx context.Context) {
 		// build status (either succeeded or failed; not "none")
 		keepWaiting := false
 		buildpkgs := make([]fv1.Package, 0)
-		for _, pkg := range pkgs {
+		for _, pkg := range pkgs.Items {
 			_, ok := w.pkgMeta[mapKey(&pkg.ObjectMeta)]
 			if !ok {
 				continue
diff --git a/pkg/fission-cli/cmd/spec/destroy.go b/pkg/fission-cli/cmd/spec/destroy.go
index 9a831a76..efa622e1 100644
--- a/pkg/fission-cli/cmd/spec/destroy.go
+++ b/pkg/fission-cli/cmd/spec/destroy.go
@@ -17,13 +17,14 @@ limitations under the License.
 package spec
 
 import (
+	"context"
 	"fmt"
 	"strings"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
@@ -68,14 +69,14 @@ func (opts *DestroySubCommand) run(input cli.Input) error {
 		emptyFr.DeploymentConfig = fr.DeploymentConfig
 
 		// "apply" the empty state
-		err = forceDeleteResources(opts.Client(), &emptyFr)
+		err = forceDeleteResources(input.Context(), opts.Client(), &emptyFr)
 		if err != nil {
 			return errors.Wrap(err, "error deleting resources")
 		}
 		return nil
 	}
 	forceDelete := input.Bool(flagkey.ForceDelete)
-	err = deleteResources(opts.Client(), fr, forceDelete)
+	err = deleteResources(input.Context(), opts.Client(), fr, forceDelete)
 	if err != nil {
 		return errors.Wrap(err, "error deleting resources")
 	}
@@ -83,41 +84,41 @@ func (opts *DestroySubCommand) run(input cli.Input) error {
 	return nil
 }
 
-func forceDeleteResources(fclient client.Interface, fr *FissionResources) error {
+func forceDeleteResources(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	var err error
 
-	_, _, err = applyHTTPTriggers(fclient, fr, true, false)
+	_, _, err = applyHTTPTriggers(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "HTTPTrigger delete failed")
 	}
 
-	_, _, err = applyKubernetesWatchTriggers(fclient, fr, true, false)
+	_, _, err = applyKubernetesWatchTriggers(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "KubernetesWatchTrigger delete failed")
 	}
 
-	_, _, err = applyTimeTriggers(fclient, fr, true, false)
+	_, _, err = applyTimeTriggers(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "TimeTrigger delete failed")
 	}
 
-	_, _, err = applyMessageQueueTriggers(fclient, fr, true, false)
+	_, _, err = applyMessageQueueTriggers(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "MessageQueueTrigger delete failed")
 	}
 
-	_, _, err = applyFunctions(fclient, fr, true, false)
+	_, _, err = applyFunctions(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "function delete failed")
 	}
 
-	_, _, err = applyPackages(fclient, fr, true, false)
+	_, _, err = applyPackages(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "package delete failed")
 	}
 
-	_, _, err = applyEnvironments(fclient, fr, true, false)
+	_, _, err = applyEnvironments(ctx, fclient, fr, true, false)
 	if err != nil {
 		return errors.Wrap(err, "environment delete failed")
 	}
@@ -131,7 +132,7 @@ func (opts *DestroySubCommand) insertNSToResource(input cli.Input, fr *FissionRe
 
 	result := utils.MultiErrorWithFormat()
 
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
@@ -175,41 +176,41 @@ func (opts *DestroySubCommand) insertNSToResource(input cli.Input, fr *FissionRe
 	return result.ErrorOrNil()
 }
 
-func deleteResources(fclient client.Interface, fr *FissionResources, forceDelete bool) error {
+func deleteResources(ctx context.Context, fclient cmd.Client, fr *FissionResources, forceDelete bool) error {
 
 	var err error
 
-	err = destroyHTTPTriggers(fclient, fr)
+	err = destroyHTTPTriggers(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "HTTPTrigger delete failed")
 	}
 
-	err = destroyKubernetesWatchTriggers(fclient, fr)
+	err = destroyKubernetesWatchTriggers(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "KubernetesWatchTrigger delete failed")
 	}
 
-	err = destroyTimeTriggers(fclient, fr)
+	err = destroyTimeTriggers(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "TimeTrigger delete failed")
 	}
 
-	err = destroyMessageQueueTriggers(fclient, fr)
+	err = destroyMessageQueueTriggers(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "MessageQueueTrigger delete failed")
 	}
 
-	err = destroyFunctions(fclient, fr)
+	err = destroyFunctions(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "function delete failed")
 	}
 
-	err = destroyPackages(fclient, fr)
+	err = destroyPackages(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "package delete failed")
 	}
 
-	err = destroyEnvironments(fclient, fr)
+	err = destroyEnvironments(ctx, fclient, fr)
 	if err != nil {
 		return errors.Wrap(err, "environment delete failed")
 	}
@@ -217,9 +218,9 @@ func deleteResources(fclient client.Interface, fr *FissionResources, forceDelete
 	return nil
 }
 
-func destroyHTTPTriggers(fclient client.Interface, fr *FissionResources) error {
+func destroyHTTPTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 	for _, o := range fr.HttpTriggers {
-		err := fclient.V1().HTTPTrigger().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().HTTPTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete httptrigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -233,10 +234,10 @@ func destroyHTTPTriggers(fclient client.Interface, fr *FissionResources) error {
 	return nil
 }
 
-func destroyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources) error {
+func destroyKubernetesWatchTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.KubernetesWatchTriggers {
-		err := fclient.V1().KubeWatcher().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().KubernetesWatchTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete watch: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -251,10 +252,10 @@ func destroyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResourc
 	return nil
 }
 
-func destroyTimeTriggers(fclient client.Interface, fr *FissionResources) error {
+func destroyTimeTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.TimeTriggers {
-		err := fclient.V1().TimeTrigger().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().TimeTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete Time trigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -269,10 +270,10 @@ func destroyTimeTriggers(fclient client.Interface, fr *FissionResources) error {
 	return nil
 }
 
-func destroyMessageQueueTriggers(fclient client.Interface, fr *FissionResources) error {
+func destroyMessageQueueTriggers(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.MessageQueueTriggers {
-		err := fclient.V1().MessageQueueTrigger().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().MessageQueueTriggers(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete Message trigger: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -287,10 +288,10 @@ func destroyMessageQueueTriggers(fclient client.Interface, fr *FissionResources)
 	return nil
 }
 
-func destroyFunctions(fclient client.Interface, fr *FissionResources) error {
+func destroyFunctions(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.Functions {
-		err := fclient.V1().Function().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().Functions(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete Functions: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -305,10 +306,10 @@ func destroyFunctions(fclient client.Interface, fr *FissionResources) error {
 	return nil
 }
 
-func destroyPackages(fclient client.Interface, fr *FissionResources) error {
+func destroyPackages(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.Packages {
-		err := fclient.V1().Package().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().Packages(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete Package: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
@@ -323,10 +324,10 @@ func destroyPackages(fclient client.Interface, fr *FissionResources) error {
 	return nil
 }
 
-func destroyEnvironments(fclient client.Interface, fr *FissionResources) error {
+func destroyEnvironments(ctx context.Context, fclient cmd.Client, fr *FissionResources) error {
 
 	for _, o := range fr.Environments {
-		err := fclient.V1().Environment().Delete(&o.ObjectMeta)
+		err := fclient.FissionClientSet.CoreV1().Environments(o.ObjectMeta.Namespace).Delete(ctx, o.ObjectMeta.Name, metav1.DeleteOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			console.Verbose(2, fmt.Sprintf("could not delete Env: %s Namespace: %s", o.ObjectMeta.Name, o.ObjectMeta.Namespace))
 			err = nil
diff --git a/pkg/fission-cli/cmd/spec/list.go b/pkg/fission-cli/cmd/spec/list.go
index fd63d90d..129f4c1f 100644
--- a/pkg/fission-cli/cmd/spec/list.go
+++ b/pkg/fission-cli/cmd/spec/list.go
@@ -17,6 +17,7 @@ limitations under the License.
 package spec
 
 import (
+	"context"
 	"fmt"
 	"os"
 	"strings"
@@ -24,9 +25,9 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
@@ -60,27 +61,27 @@ func (opts *ListSubCommand) run(input cli.Input) error {
 		deployID = fr.DeploymentConfig.UID
 	}
 
-	_, currentNS, err := util.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
+	_, currentNS, err := opts.GetResourceNamespace(input, flagkey.NamespaceEnvironment)
 	if err != nil {
 		return fv1.AggregateValidationErrors("Environment", err)
 	}
 
 	if input.Bool(flagkey.AllNamespaces) {
-		return opts.getResource(input, "", deployID)
-	} else {
-		return opts.getResource(input, currentNS, deployID)
+		currentNS = metav1.NamespaceAll
 	}
 
+	return opts.getResource(input, currentNS, deployID)
+
 }
 
 func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deployID string) (err error) {
 	var allfn []fv1.Function
 	printNS := namespace
-	if printNS == "" {
+	if printNS == metav1.NamespaceAll {
 		printNS = "all"
 	}
 
-	allfn, err = getAllFunctions(opts.Client(), namespace)
+	allfn, err = getAllFunctions(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Functions from %s namespaces", printNS))
 	}
@@ -88,7 +89,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowFunctions(specfns)
 
 	var allenvs []fv1.Environment
-	allenvs, err = getAllEnvironments(opts.Client(), namespace)
+	allenvs, err = getAllEnvironments(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Environments from  %s namespaces", printNS))
 	}
@@ -96,7 +97,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowEnvironments(specenvs)
 
 	var pkglists []fv1.Package
-	pkglists, err = getAllPackages(opts.Client(), namespace)
+	pkglists, err = getAllPackages(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Packages from  %s namespaces", printNS))
 	}
@@ -104,7 +105,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowPackages(specPkgs)
 
 	var canaryCfgs []fv1.CanaryConfig
-	canaryCfgs, err = getAllCanaryConfigs(opts.Client(), namespace)
+	canaryCfgs, err = getAllCanaryConfigs(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Canary Config from  %s namespaces", printNS))
 	}
@@ -112,7 +113,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowCanaryConfigs(specCanaryCfgs)
 
 	var hts []fv1.HTTPTrigger
-	hts, err = getAllHTTPTriggers(opts.Client(), namespace)
+	hts, err = getAllHTTPTriggers(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting HTTP Triggers from  %s namespaces", printNS))
 	}
@@ -120,7 +121,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowHTTPTriggers(specHTTPTriggers)
 
 	var mqts []fv1.MessageQueueTrigger
-	mqts, err = getAllMessageQueueTriggers(opts.Client(), input.String(flagkey.MqtMQType), namespace)
+	mqts, err = getAllMessageQueueTriggers(input.Context(), opts.Client(), input.String(flagkey.MqtMQType), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting MessageQueue Triggers from  %s namespaces", printNS))
 	}
@@ -128,7 +129,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowMQTriggers(specMessageQueueTriggers)
 
 	var tts []fv1.TimeTrigger
-	tts, err = getAllTimeTriggers(opts.Client(), namespace)
+	tts, err = getAllTimeTriggers(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Time Triggers from  %s namespaces", printNS))
 	}
@@ -136,7 +137,7 @@ func (opts *ListSubCommand) getResource(input cli.Input, namespace string, deplo
 	ShowTimeTriggers(specTimeTriggers)
 
 	var kws []fv1.KubernetesWatchTrigger
-	kws, err = getAllKubeWatchTriggers(opts.Client(), namespace)
+	kws, err = getAllKubeWatchTriggers(input.Context(), opts.Client(), namespace)
 	if err != nil {
 		return errors.Wrap(err, fmt.Sprintf("error getting Kube Watchers from  %s namespaces", printNS))
 	}
@@ -420,73 +421,73 @@ func ShowAppliedKubeWatchers(ws []fv1.KubernetesWatchTrigger) {
 }
 
 // getAllFunctions get lists of functions in provided namespaces
-func getAllFunctions(client client.Interface, namespace string) ([]fv1.Function, error) {
-	fns, err := client.V1().Function().List(namespace)
+func getAllFunctions(ctx context.Context, client cmd.Client, namespace string) ([]fv1.Function, error) {
+	fns, err := client.FissionClientSet.CoreV1().Functions(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Functions %v", err.Error())
 	}
-	return fns, nil
+	return fns.Items, nil
 }
 
 // getAllEnvironments get lists of environments in all namespaces
-func getAllEnvironments(client client.Interface, namespace string) ([]fv1.Environment, error) {
-	envs, err := client.V1().Environment().List(namespace)
+func getAllEnvironments(ctx context.Context, client cmd.Client, namespace string) ([]fv1.Environment, error) {
+	envs, err := client.FissionClientSet.CoreV1().Environments(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Environments %v", err.Error())
 	}
-	return envs, nil
+	return envs.Items, nil
 }
 
 // getAllPackages get lists of packages in all namespaces
-func getAllPackages(client client.Interface, namespace string) ([]fv1.Package, error) {
-	pkgList, err := client.V1().Package().List(namespace)
+func getAllPackages(ctx context.Context, client cmd.Client, namespace string) ([]fv1.Package, error) {
+	pkgList, err := client.FissionClientSet.CoreV1().Packages(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Packages %v", err.Error())
 	}
-	return pkgList, nil
+	return pkgList.Items, nil
 }
 
 // getAllCanaryConfigs get lists of canary configs in all namespaces
-func getAllCanaryConfigs(client client.Interface, namespace string) ([]fv1.CanaryConfig, error) {
-	canaryCfgs, err := client.V1().CanaryConfig().List(namespace)
+func getAllCanaryConfigs(ctx context.Context, client cmd.Client, namespace string) ([]fv1.CanaryConfig, error) {
+	canaryCfgs, err := client.FissionClientSet.CoreV1().CanaryConfigs(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Canary Configs %v", err.Error())
 	}
-	return canaryCfgs, nil
+	return canaryCfgs.Items, nil
 }
 
 // getAllHTTPTriggers get lists of HTTP Triggers in all namespaces
-func getAllHTTPTriggers(client client.Interface, namespace string) ([]fv1.HTTPTrigger, error) {
-	hts, err := client.V1().HTTPTrigger().List(namespace)
+func getAllHTTPTriggers(ctx context.Context, client cmd.Client, namespace string) ([]fv1.HTTPTrigger, error) {
+	hts, err := client.FissionClientSet.CoreV1().HTTPTriggers(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get HTTP Triggers %v", err.Error())
 	}
-	return hts, nil
+	return hts.Items, nil
 }
 
 // getAllMessageQueueTriggers get lists of MessageQueue Triggers in all namespaces
-func getAllMessageQueueTriggers(client client.Interface, mqttype string, namespace string) ([]fv1.MessageQueueTrigger, error) {
-	mqts, err := client.V1().MessageQueueTrigger().List(mqttype, namespace)
+func getAllMessageQueueTriggers(ctx context.Context, client cmd.Client, mqttype string, namespace string) ([]fv1.MessageQueueTrigger, error) {
+	mqts, err := client.FissionClientSet.CoreV1().MessageQueueTriggers(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get MessageQueue Triggers %v", err.Error())
 	}
-	return mqts, nil
+	return mqts.Items, nil
 }
 
 // getAllTimeTriggers get lists of Time Triggers in all namespaces
-func getAllTimeTriggers(client client.Interface, namespace string) ([]fv1.TimeTrigger, error) {
-	tts, err := client.V1().TimeTrigger().List(namespace)
+func getAllTimeTriggers(ctx context.Context, client cmd.Client, namespace string) ([]fv1.TimeTrigger, error) {
+	tts, err := client.FissionClientSet.CoreV1().TimeTriggers(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Time Triggers %v", err.Error())
 	}
-	return tts, nil
+	return tts.Items, nil
 }
 
 // getAllKubeWatchTriggers get lists of Kube Watchers in all namespaces
-func getAllKubeWatchTriggers(client client.Interface, namespace string) ([]fv1.KubernetesWatchTrigger, error) {
-	ws, err := client.V1().KubeWatcher().List(namespace)
+func getAllKubeWatchTriggers(ctx context.Context, client cmd.Client, namespace string) ([]fv1.KubernetesWatchTrigger, error) {
+	ws, err := client.FissionClientSet.CoreV1().KubernetesWatchTriggers(namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
 		return nil, errors.Errorf("Unable to get Kube Watchers %v", err.Error())
 	}
-	return ws, nil
+	return ws.Items, nil
 }
diff --git a/pkg/fission-cli/cmd/spec/spec.go b/pkg/fission-cli/cmd/spec/spec.go
index ce16d6fe..e3fe0766 100644
--- a/pkg/fission-cli/cmd/spec/spec.go
+++ b/pkg/fission-cli/cmd/spec/spec.go
@@ -31,6 +31,7 @@ import (
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec/types"
 	"github.com/fission/fission/pkg/fission-cli/console"
 	"github.com/fission/fission/pkg/fission-cli/util"
@@ -297,7 +298,7 @@ func (fr *FissionResources) validateFunctionReference(functions map[string]bool,
 }
 
 // Validate validates the spec file for irregular references
-func (fr *FissionResources) Validate(input cli.Input) ([]string, error) {
+func (fr *FissionResources) Validate(input cli.Input, client cmd.Client) ([]string, error) {
 	result := utils.MultiErrorWithFormat()
 	var warnings []string
 
@@ -397,25 +398,17 @@ func (fr *FissionResources) Validate(input cli.Input) ([]string, error) {
 			}
 		}
 
-		client, err := util.GetServer(input)
-		if err != nil {
-			return warnings, err
-		}
 		for _, cm := range f.Spec.ConfigMaps {
-			err := client.V1().Misc().ConfigMapExists(&metav1.ObjectMeta{
-				Name:      cm.Name,
-				Namespace: cm.Namespace,
-			})
+
+			err := util.ConfigMapExists(input.Context(), &metav1.ObjectMeta{Namespace: cm.Namespace, Name: cm.Name}, client.KubernetesClient)
 			if k8serrors.IsNotFound(err) {
 				warnings = append(warnings, fmt.Sprintf("Configmap %s is referred in the spec but not present in the cluster", cm.Name))
 			}
 		}
 
 		for _, s := range f.Spec.Secrets {
-			err := client.V1().Misc().SecretExists(&metav1.ObjectMeta{
-				Name:      s.Name,
-				Namespace: s.Namespace,
-			})
+			err := util.SecretExists(input.Context(), &metav1.ObjectMeta{Namespace: s.Namespace, Name: s.Name}, client.KubernetesClient)
+
 			if k8serrors.IsNotFound(err) {
 				warnings = append(warnings, fmt.Sprintf("Secret %s is referred in the spec but not present in the cluster", s.Name))
 			}
diff --git a/pkg/fission-cli/cmd/spec/validate.go b/pkg/fission-cli/cmd/spec/validate.go
index 5b230261..049e3910 100644
--- a/pkg/fission-cli/cmd/spec/validate.go
+++ b/pkg/fission-cli/cmd/spec/validate.go
@@ -18,6 +18,7 @@ package spec
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -29,7 +30,6 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
@@ -81,12 +81,12 @@ func (opts *ValidateSubCommand) run(input cli.Input, fr *FissionResources) (err
 
 	var warnings []string
 	// this does the rest of the checks, like dangling refs
-	warnings, err = fr.Validate(input)
+	warnings, err = fr.Validate(input, opts.Client())
 	if err != nil {
 		return errors.Wrap(err, "error validating specs")
 	}
 
-	err = resourceConflictCheck(opts.Client(), fr, input.Bool(flagkey.SpecAllowConflicts), "")
+	err = resourceConflictCheck(input.Context(), opts.Client(), fr, input.Bool(flagkey.SpecAllowConflicts), "")
 	if err != nil {
 		return errors.Wrap(err, "name conflict error")
 	}
@@ -104,11 +104,11 @@ func (opts *ValidateSubCommand) run(input cli.Input, fr *FissionResources) (err
 // the same name is already present in the same cluster namespace.
 // If a same name resource exists in the same namespace, a name
 // conflict error will be returned.
-func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowConflicts bool, namespace string) error {
+func resourceConflictCheck(ctx context.Context, c cmd.Client, fr *FissionResources, specAllowConflicts bool, namespace string) error {
 	deployUID := fr.DeploymentConfig.UID
 	result := utils.MultiErrorWithFormat()
 
-	fnList, err := getAllFunctions(c, namespace)
+	fnList, err := getAllFunctions(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Functions %v", err.Error())
 	}
@@ -121,7 +121,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	envList, err := getAllEnvironments(c, namespace)
+	envList, err := getAllEnvironments(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Environments %v", err.Error())
 	}
@@ -134,7 +134,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	pkgList, err := getAllPackages(c, namespace)
+	pkgList, err := getAllPackages(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Packages %v", err.Error())
 	}
@@ -147,7 +147,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	httptriggerList, err := getAllHTTPTriggers(c, namespace)
+	httptriggerList, err := getAllHTTPTriggers(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get HTTPTrigger %v", err.Error())
 	}
@@ -160,7 +160,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	mqtriggerList, err := getAllMessageQueueTriggers(c, "", namespace)
+	mqtriggerList, err := getAllMessageQueueTriggers(ctx, c, "", namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Message Queue Trigger %v", err.Error())
 	}
@@ -173,7 +173,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	timetriggerList, err := getAllTimeTriggers(c, namespace)
+	timetriggerList, err := getAllTimeTriggers(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Time Trigger %v", err.Error())
 	}
@@ -186,7 +186,7 @@ func resourceConflictCheck(c client.Interface, fr *FissionResources, specAllowCo
 		}
 	}
 
-	kubewatchtriggerList, err := getAllKubeWatchTriggers(c, namespace)
+	kubewatchtriggerList, err := getAllKubeWatchTriggers(ctx, c, namespace)
 	if err != nil {
 		return errors.Errorf("Unable to get Kubernetes Watch Trigger %v", err.Error())
 	}
diff --git a/pkg/fission-cli/cmd/support/dump.go b/pkg/fission-cli/cmd/support/dump.go
index 8366244d..70b42de0 100644
--- a/pkg/fission-cli/cmd/support/dump.go
+++ b/pkg/fission-cli/cmd/support/dump.go
@@ -29,7 +29,6 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/support/resources"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 	"github.com/fission/fission/pkg/utils"
 )
 
@@ -51,7 +50,6 @@ func (opts *DumpSubCommand) do(input cli.Input) error {
 
 	nozip := input.Bool(flagkey.SupportNoZip)
 	outputDir := input.String(flagkey.SupportOutput)
-	kubeContext := input.String(flagkey.KubeContext)
 	// check whether the dump directory exists.
 	_, err := os.Stat(outputDir)
 	if err != nil && os.IsNotExist(err) {
@@ -68,10 +66,7 @@ func (opts *DumpSubCommand) do(input cli.Input) error {
 		panic(errors.Wrap(err, "Error creating dump directory for dumping files"))
 	}
 
-	_, k8sClient, err := util.GetKubernetesClient(kubeContext)
-	if err != nil {
-		return err
-	}
+	k8sClient := opts.Client().KubernetesClient
 
 	ress := map[string]resources.Resource{
 		// kubernetes info
@@ -79,7 +74,7 @@ func (opts *DumpSubCommand) do(input cli.Input) error {
 		"kubernetes-nodes":   resources.NewKubernetesObjectDumper(k8sClient, resources.KubernetesNode, ""),
 
 		// fission info
-		"fission-version": resources.NewFissionVersion(opts.Client()),
+		"fission-version": resources.NewFissionVersion(opts.Client(), input),
 
 		// fission component logs & spec
 		"fission-components-svc-spec": resources.NewKubernetesObjectDumper(k8sClient, resources.KubernetesService,
diff --git a/pkg/fission-cli/cmd/support/resources/crd.go b/pkg/fission-cli/cmd/support/resources/crd.go
index 18e9ee34..ecc46329 100644
--- a/pkg/fission-cli/cmd/support/resources/crd.go
+++ b/pkg/fission-cli/cmd/support/resources/crd.go
@@ -23,7 +23,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
 )
 
@@ -39,11 +39,11 @@ const (
 )
 
 type CrdDumper struct {
-	client  client.Interface
+	client  cmd.Client
 	crdType string
 }
 
-func NewCrdDumper(client client.Interface, crdType string) Resource {
+func NewCrdDumper(client cmd.Client, crdType string) Resource {
 	return CrdDumper{client: client, crdType: crdType}
 }
 
@@ -51,62 +51,62 @@ func (res CrdDumper) Dump(ctx context.Context, dumpDir string) {
 
 	switch res.crdType {
 	case CrdEnvironment:
-		items, err := res.client.V1().Environment().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().Environments(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
 
 	case CrdFunction:
-		items, err := res.client.V1().Function().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
 
 	case CrdPackage:
-		items, err := res.client.V1().Package().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().Packages(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			item = pkgClean(item)
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
 
 	case CrdHttpTrigger:
-		items, err := res.client.V1().HTTPTrigger().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().HTTPTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
 
 	case CrdKubeWatcher:
-		items, err := res.client.V1().KubeWatcher().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().KubernetesWatchTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
@@ -114,14 +114,12 @@ func (res CrdDumper) Dump(ctx context.Context, dumpDir string) {
 	case CrdMessageQueueTrigger:
 		var triggers []fv1.MessageQueueTrigger
 
-		for _, mqType := range []string{fv1.MessageQueueTypeKafka} {
-			l, err := res.client.V1().MessageQueueTrigger().List(mqType, metav1.NamespaceAll)
-			if err != nil {
-				console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
-				break
-			}
-			triggers = append(triggers, l...)
+		l, err := res.client.FissionClientSet.CoreV1().MessageQueueTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
+		if err != nil {
+			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
+			break
 		}
+		triggers = append(triggers, l.Items...)
 
 		for _, item := range triggers {
 			f := getFileName(dumpDir, item.ObjectMeta)
@@ -129,13 +127,13 @@ func (res CrdDumper) Dump(ctx context.Context, dumpDir string) {
 		}
 
 	case CrdTimeTrigger:
-		items, err := res.client.V1().TimeTrigger().List(metav1.NamespaceAll)
+		items, err := res.client.FissionClientSet.CoreV1().TimeTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			console.Warn(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
 			return
 		}
 
-		for _, item := range items {
+		for _, item := range items.Items {
 			f := getFileName(dumpDir, item.ObjectMeta)
 			writeToFile(f, item)
 		}
diff --git a/pkg/fission-cli/cmd/support/resources/fissionversion.go b/pkg/fission-cli/cmd/support/resources/fissionversion.go
index 5e162d04..0334f9ed 100644
--- a/pkg/fission-cli/cmd/support/resources/fissionversion.go
+++ b/pkg/fission-cli/cmd/support/resources/fissionversion.go
@@ -21,20 +21,22 @@ import (
 	"fmt"
 	"path/filepath"
 
-	"github.com/fission/fission/pkg/controller/client"
+	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type FissionVersion struct {
-	client client.Interface
+	client cmd.Client
+	input  cli.Input
 }
 
-func NewFissionVersion(client client.Interface) Resource {
-	return FissionVersion{client: client}
+func NewFissionVersion(client cmd.Client, input cli.Input) Resource {
+	return FissionVersion{client: client, input: input}
 }
 
 func (res FissionVersion) Dump(ctx context.Context, dumpDir string) {
-	ver := util.GetVersion(ctx, res.client)
+	ver := util.GetVersion(ctx, res.input, res.client)
 	file := filepath.Clean(fmt.Sprintf("%v/%v", dumpDir, "fission-version.txt"))
 	writeToFile(file, ver)
 }
diff --git a/pkg/fission-cli/cmd/timetrigger/create.go b/pkg/fission-cli/cmd/timetrigger/create.go
index e12dd340..17f85fa9 100644
--- a/pkg/fission-cli/cmd/timetrigger/create.go
+++ b/pkg/fission-cli/cmd/timetrigger/create.go
@@ -28,7 +28,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd/spec"
 	"github.com/fission/fission/pkg/fission-cli/console"
@@ -68,7 +67,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) (err error) {
 		return errors.New("Need a function name to create a trigger, use --function")
 	}
 
-	userProvidedNS, fnNamespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	userProvidedNS, fnNamespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
@@ -143,17 +142,14 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 		return nil
 	}
 
-	_, err := opts.Client().V1().TimeTrigger().Create(opts.trigger)
+	_, err := opts.Client().FissionClientSet.CoreV1().TimeTriggers(opts.trigger.Namespace).Create(input.Context(), opts.trigger, metav1.CreateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error creating Time trigger")
 	}
 
 	fmt.Printf("trigger '%v' created\n", opts.trigger.ObjectMeta.Name)
 
-	t, err := getAPITimeInfo(opts.Client())
-	if err != nil {
-		return err
-	}
+	t := util.GetServerInfo(input, opts.Client()).ServerTime.CurrentTime.UTC()
 
 	err = getCronNextNActivationTime(opts.trigger.Spec.Cron, t, 1)
 	if err != nil {
@@ -163,14 +159,6 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 	return nil
 }
 
-func getAPITimeInfo(client client.Interface) (time.Time, error) {
-	serverInfo, err := client.V1().Misc().ServerInfo()
-	if err != nil {
-		return time.Time{}, errors.Errorf("Error syncing server time information: %v", err)
-	}
-	return serverInfo.ServerTime.CurrentTime, nil
-}
-
 func getCronNextNActivationTime(cronSpec string, serverTime time.Time, round int) error {
 	sched, err := cron.Parse(cronSpec)
 	if err != nil {
diff --git a/pkg/fission-cli/cmd/timetrigger/delete.go b/pkg/fission-cli/cmd/timetrigger/delete.go
index 3eb1eb35..742ed438 100644
--- a/pkg/fission-cli/cmd/timetrigger/delete.go
+++ b/pkg/fission-cli/cmd/timetrigger/delete.go
@@ -20,12 +20,12 @@ import (
 	"fmt"
 
 	"github.com/pkg/errors"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type DeleteSubCommand struct {
@@ -38,23 +38,19 @@ func Delete(input cli.Input) error {
 
 func (opts *DeleteSubCommand) do(input cli.Input) (err error) {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
-	m := &metav1.ObjectMeta{
-		Name:      input.String(flagkey.TtName),
-		Namespace: namespace,
-	}
 
-	err = opts.Client().V1().TimeTrigger().Delete(m)
+	err = opts.Client().FissionClientSet.CoreV1().TimeTriggers(namespace).Delete(input.Context(), input.String(flagkey.TtName), metav1.DeleteOptions{})
 	if err != nil {
-		if input.Bool(flagkey.IgnoreNotFound) && util.IsNotFound(err) {
+		if input.Bool(flagkey.IgnoreNotFound) && kerrors.IsNotFound(err) {
 			return nil
 		}
 		return errors.Wrap(err, "error deleting trigger")
 	}
 
-	fmt.Printf("trigger '%v' deleted\n", m.Name)
+	fmt.Printf("trigger '%v' deleted\n", input.String(flagkey.TtName))
 	return nil
 }
diff --git a/pkg/fission-cli/cmd/timetrigger/list.go b/pkg/fission-cli/cmd/timetrigger/list.go
index 7b96340c..05001308 100644
--- a/pkg/fission-cli/cmd/timetrigger/list.go
+++ b/pkg/fission-cli/cmd/timetrigger/list.go
@@ -22,12 +22,11 @@ import (
 	"text/tabwriter"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	v1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
-	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ListSubCommand struct {
@@ -39,17 +38,15 @@ func List(input cli.Input) error {
 }
 
 func (opts *ListSubCommand) do(input cli.Input) (err error) {
-	_, ttNs, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, ttNs, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
 
-	var tts []v1.TimeTrigger
 	if input.Bool(flagkey.AllNamespaces) {
-		tts, err = opts.Client().V1().TimeTrigger().List("")
-	} else {
-		tts, err = opts.Client().V1().TimeTrigger().List(ttNs)
+		ttNs = metav1.NamespaceAll
 	}
+	tts, err := opts.Client().FissionClientSet.CoreV1().TimeTriggers(ttNs).List(input.Context(), metav1.ListOptions{})
 
 	if err != nil {
 		return errors.Wrap(err, "list Time triggers")
@@ -58,7 +55,7 @@ func (opts *ListSubCommand) do(input cli.Input) (err error) {
 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
 
 	fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "CRON", "FUNCTION_NAME")
-	for _, tt := range tts {
+	for _, tt := range tts.Items {
 		fmt.Fprintf(w, "%v\t%v\t%v\n",
 			tt.ObjectMeta.Name, tt.Spec.Cron, tt.Spec.FunctionReference.Name)
 	}
diff --git a/pkg/fission-cli/cmd/timetrigger/update.go b/pkg/fission-cli/cmd/timetrigger/update.go
index 8a6ac466..d2f0832d 100644
--- a/pkg/fission-cli/cmd/timetrigger/update.go
+++ b/pkg/fission-cli/cmd/timetrigger/update.go
@@ -48,14 +48,12 @@ func (opts *UpdateSubCommand) do(input cli.Input) error {
 }
 
 func (opts *UpdateSubCommand) complete(input cli.Input) error {
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceTrigger)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceTrigger)
 	if err != nil {
 		return errors.Wrap(err, "error in deleting function ")
 	}
-	tt, err := opts.Client().V1().TimeTrigger().Get(&metav1.ObjectMeta{
-		Name:      input.String(flagkey.TtName),
-		Namespace: namespace,
-	})
+
+	tt, err := opts.Client().FissionClientSet.CoreV1().TimeTriggers(namespace).Get(input.Context(), input.String(flagkey.TtName), metav1.GetOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error getting time trigger")
 	}
@@ -70,7 +68,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 	fnName := input.String("function")
 	if len(fnName) > 0 {
 		functionList := []string{fnName}
-		err := util.CheckFunctionExistence(opts.Client(), functionList, namespace)
+		err := util.CheckFunctionExistence(input.Context(), opts.Client(), functionList, namespace)
 		if err != nil {
 			console.Warn(err.Error())
 		}
@@ -88,14 +86,14 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
 }
 
 func (opts *UpdateSubCommand) run(input cli.Input) error {
-	_, err := opts.Client().V1().TimeTrigger().Update(opts.trigger)
+	_, err := opts.Client().FissionClientSet.CoreV1().TimeTriggers(opts.trigger.ObjectMeta.Namespace).Update(input.Context(), opts.trigger, metav1.UpdateOptions{})
 	if err != nil {
 		return errors.Wrap(err, "error updating Time trigger")
 	}
 
 	fmt.Printf("trigger '%v' updated\n", opts.trigger.ObjectMeta.Name)
 
-	t, err := getAPITimeInfo(opts.Client())
+	t := util.GetServerInfo(input, opts.Client()).ServerTime.CurrentTime.UTC()
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/token/create.go b/pkg/fission-cli/cmd/token/create.go
index 669cb77f..c08e04cd 100644
--- a/pkg/fission-cli/cmd/token/create.go
+++ b/pkg/fission-cli/cmd/token/create.go
@@ -64,9 +64,8 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
 
 	jsonValue, _ := json.Marshal(values)
 
-	kubeContext := input.String(flagkey.KubeContext)
 	// Portforward to the fission router
-	localRouterPort, err := util.SetupPortForward(input.Context(), util.GetFissionNamespace(), "application=fission-router", kubeContext)
+	localRouterPort, err := util.SetupPortForward(input.Context(), opts.Client(), util.GetFissionNamespace(), "application=fission-router")
 	if err != nil {
 		return err
 	}
diff --git a/pkg/fission-cli/cmd/version/version.go b/pkg/fission-cli/cmd/version/version.go
index cb1ef9a3..14b781dc 100644
--- a/pkg/fission-cli/cmd/version/version.go
+++ b/pkg/fission-cli/cmd/version/version.go
@@ -36,7 +36,7 @@ func Version(input cli.Input) error {
 }
 
 func (opts *VersionSubCommand) do(input cli.Input) error {
-	ver := util.GetVersion(input.Context(), opts.Client())
+	ver := util.GetVersion(input.Context(), input, opts.Client())
 	bs, err := yaml.Marshal(ver)
 	if err != nil {
 		return errors.Wrap(err, "error formatting versions")
diff --git a/pkg/fission-cli/util/portforward.go b/pkg/fission-cli/util/portforward.go
index b87029c2..335f775f 100644
--- a/pkg/fission-cli/util/portforward.go
+++ b/pkg/fission-cli/util/portforward.go
@@ -32,6 +32,7 @@ import (
 	"k8s.io/client-go/tools/portforward"
 	"k8s.io/client-go/transport/spdy"
 
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
 	"github.com/fission/fission/pkg/utils"
 )
@@ -43,7 +44,7 @@ const maxDuration time.Duration = 2000
 // is found by looking for a service in the same namespace and using
 // its targetPort. Once the port forward is started, wait for it to
 // start accepting connections before returning.
-func SetupPortForward(ctx context.Context, namespace, labelSelector string, kubeContext string) (string, error) {
+func SetupPortForward(ctx context.Context, client cmd.Client, namespace, labelSelector string) (string, error) {
 	console.Verbose(2, "Setting up port forward to %s in namespace %s",
 		labelSelector, namespace)
 
@@ -71,7 +72,7 @@ func SetupPortForward(ctx context.Context, namespace, labelSelector string, kube
 
 	console.Verbose(2, "Starting port forward from local port %v", localPort)
 
-	readyC, _, err := runPortForward(ctx, labelSelector, localPort, namespace, kubeContext)
+	readyC, _, err := runPortForward(ctx, client, labelSelector, localPort, namespace)
 	if err != nil {
 		fmt.Printf("Error forwarding to port %v: %s", localPort, err.Error())
 		return "", err
@@ -119,11 +120,7 @@ func findFreePort() (string, error) {
 }
 
 // runPortForward creates a local port forward to the specified pod
-func runPortForward(ctx context.Context, labelSelector string, localPort string, ns string, kubeContext string) (chan struct{}, chan struct{}, error) {
-	config, clientset, err := GetKubernetesClient(kubeContext)
-	if err != nil {
-		return nil, nil, err
-	}
+func runPortForward(ctx context.Context, client cmd.Client, labelSelector string, localPort string, ns string) (chan struct{}, chan struct{}, error) {
 
 	console.Verbose(2, "Connected to Kubernetes API")
 
@@ -133,7 +130,7 @@ func runPortForward(ctx context.Context, labelSelector string, localPort string,
 	}
 
 	// get the pod; if there is more than one, ask the user to disambiguate
-	podList, err := clientset.CoreV1().Pods(ns).
+	podList, err := client.KubernetesClient.CoreV1().Pods(ns).
 		List(ctx, metav1.ListOptions{LabelSelector: labelSelector})
 	if err != nil {
 		return nil, nil, errors.Wrapf(err, "error getting pod for port-forwarding with label selector %v", labelSelector)
@@ -179,7 +176,7 @@ func runPortForward(ctx context.Context, labelSelector string, localPort string,
 	}
 
 	// get the service and the target port
-	svcs, err := clientset.CoreV1().Services(podNameSpace).
+	svcs, err := client.KubernetesClient.CoreV1().Services(podNameSpace).
 		List(ctx, metav1.ListOptions{LabelSelector: labelSelector})
 	if err != nil {
 		return nil, nil, errors.Wrapf(err, "Error getting %v service", labelSelector)
@@ -199,7 +196,7 @@ func runPortForward(ctx context.Context, labelSelector string, localPort string,
 	readyChannel := make(chan struct{})
 
 	// create request URL
-	req := clientset.CoreV1().RESTClient().Post().Resource("pods").
+	req := client.KubernetesClient.CoreV1().RESTClient().Post().Resource("pods").
 		Namespace(podNameSpace).Name(podName).SubResource("portforward")
 	url := req.URL()
 
@@ -208,7 +205,7 @@ func runPortForward(ctx context.Context, labelSelector string, localPort string,
 	ports := []string{portCombo}
 
 	// actually start the port-forwarding process here
-	transport, upgrader, err := spdy.RoundTripperFor(config)
+	transport, upgrader, err := spdy.RoundTripperFor(client.RestConfig)
 	if err != nil {
 		return nil, nil, errors.Errorf("Failed to connect to Fission service on Kubernetes")
 	}
diff --git a/pkg/fission-cli/util/util.go b/pkg/fission-cli/util/util.go
index 1215c557..a3577cc8 100644
--- a/pkg/fission-cli/util/util.go
+++ b/pkg/fission-cli/util/util.go
@@ -19,11 +19,12 @@ package util
 import (
 	"context"
 	"fmt"
+	"io"
 	"net/url"
 	"os"
-	"os/user"
 	"path/filepath"
 	"regexp"
+	"sort"
 	"strconv"
 	"strings"
 
@@ -36,12 +37,12 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/kubernetes"
-	restclient "k8s.io/client-go/rest"
-	"k8s.io/client-go/tools/clientcmd"
 
+	fv1 "github.com/fission/fission/pkg/apis/core/v1"
 	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/controller/client/rest"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/console"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
 	"github.com/fission/fission/pkg/info"
@@ -54,13 +55,13 @@ func GetFissionNamespace() string {
 	return fissionNamespace
 }
 
-func GetApplicationUrl(ctx context.Context, selector string, kubeContext string) (string, error) {
+func GetApplicationUrl(ctx context.Context, client cmd.Client, selector string) (string, error) {
 	var serverUrl string
 	// Use FISSION_URL env variable if set; otherwise, port-forward to controller.
 	fissionUrl := os.Getenv("FISSION_URL")
 	if len(fissionUrl) == 0 {
 		fissionNamespace := GetFissionNamespace()
-		localPort, err := SetupPortForward(ctx, fissionNamespace, selector, kubeContext)
+		localPort, err := SetupPortForward(ctx, client, fissionNamespace, selector)
 		if err != nil {
 			return "", err
 		}
@@ -104,87 +105,11 @@ func KubifyName(old string) string {
 	return newName
 }
 
-func getLoadingRules() (loadingRules *clientcmd.ClientConfigLoadingRules, err error) {
-	loadingRules = clientcmd.NewDefaultClientConfigLoadingRules()
-
-	kubeConfigPath := os.Getenv("KUBECONFIG")
-	if len(kubeConfigPath) == 0 {
-		var homeDir string
-		usr, err := user.Current()
-		if err != nil {
-			// In case that user.Current() may be unable to work under some circumstances and return errors like
-			// "user: Current not implemented on darwin/amd64" due to cross-compilation problem. (https://github.com/golang/go/issues/6376).
-			// Instead of doing fatal here, we fallback to get home directory from the environment $HOME.
-			console.Warn(fmt.Sprintf("Could not get the current user's directory (%s), fallback to get it from env $HOME", err))
-			homeDir = os.Getenv("HOME")
-		} else {
-			homeDir = usr.HomeDir
-		}
-		kubeConfigPath = filepath.Join(homeDir, ".kube", "config")
-
-		if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
-			return nil, errors.New("Couldn't find kubeconfig file. " +
-				"Set the KUBECONFIG environment variable to your kubeconfig's path.")
-		}
-		loadingRules.ExplicitPath = kubeConfigPath
-		console.Verbose(2, "Using kubeconfig from %q", kubeConfigPath)
-	} else {
-		console.Verbose(2, "Using kubeconfig from environment %q", kubeConfigPath)
-	}
-	return loadingRules, nil
-}
-
-// GetKubernetesClient builds a new kubernetes client. If the KUBECONFIG
-// environment variable is empty or doesn't exist, ~/.kube/config is used for
-// the kube config path
-func GetKubernetesClient(kubeContext string) (*restclient.Config, kubernetes.Interface, error) {
-	loadingRules, err := getLoadingRules()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
-		loadingRules, &clientcmd.ConfigOverrides{CurrentContext: kubeContext}).ClientConfig()
-	if err != nil {
-		return nil, nil, errors.Wrap(err, "Failed to build Kubernetes config")
-	}
-
-	clientset, err := kubernetes.NewForConfig(config)
-	if err != nil {
-		return nil, nil, errors.Wrap(err, "Failed to connect to Kubernetes")
-	}
-
-	return config, clientset, nil
-}
-
-// GetKubernetesNamespace builds a new kubernetes client. If the KUBECONFIG
-// environment variable is empty or doesn't exist, ~/.kube/config is used for
-// the kube config path
-func GetKubernetesNamespace(kubeContext string) (currentNS string, err error) {
-	loadingRules, err := getLoadingRules()
-	if err != nil {
-		return "", err
-	}
-
-	namespace, _, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
-		loadingRules, &clientcmd.ConfigOverrides{CurrentContext: kubeContext}).Namespace()
-	if err != nil {
-		return "", errors.Wrap(err, "Failed to build Kubernetes config")
-	}
-
-	return namespace, nil
-}
-
 // given a list of functions, this checks if the functions actually exist on the cluster
-func CheckFunctionExistence(client client.Interface, functions []string, fnNamespace string) (err error) {
+func CheckFunctionExistence(ctx context.Context, client cmd.Client, functions []string, fnNamespace string) (err error) {
 	fnMissing := make([]string, 0)
 	for _, fnName := range functions {
-		meta := &metav1.ObjectMeta{
-			Name:      fnName,
-			Namespace: fnNamespace,
-		}
-
-		_, err := client.V1().Function().Get(meta)
+		_, err := client.FissionClientSet.CoreV1().Functions(fnNamespace).Get(ctx, fnName, metav1.GetOptions{})
 		if err != nil {
 			fnMissing = append(fnMissing, fnName)
 		}
@@ -197,7 +122,7 @@ func CheckFunctionExistence(client client.Interface, functions []string, fnNames
 	return nil
 }
 
-func GetVersion(ctx context.Context, client client.Interface) info.Versions {
+func GetVersion(ctx context.Context, input cli.Input, cmdClient cmd.Client) info.Versions {
 	// Fetch client versions
 	versions := info.Versions{
 		Client: map[string]info.BuildMeta{
@@ -211,11 +136,7 @@ func GetVersion(ctx context.Context, client client.Interface) info.Versions {
 		}
 	}
 
-	serverInfo, err := client.V1().Misc().ServerInfo()
-	if err != nil {
-		console.Warn(fmt.Sprintf("Error getting Fission API version: %v", err))
-		serverInfo = &info.ServerInfo{}
-	}
+	serverInfo := GetServerInfo(input, cmdClient)
 
 	// Fetch server versions
 	versions.Server = map[string]info.BuildMeta{
@@ -227,20 +148,28 @@ func GetVersion(ctx context.Context, client client.Interface) info.Versions {
 	return versions
 }
 
-func GetServer(input cli.Input) (c client.Interface, err error) {
-	serverUrl, err := GetServerURL(input)
+func GetServerInfo(input cli.Input, cmdClient cmd.Client) *info.ServerInfo {
+	serverUrl, err := GetServerURL(input, cmdClient)
 	if err != nil {
-		return nil, err
+		return &info.ServerInfo{}
+	}
+	restClient := rest.NewRESTClient(serverUrl)
+	client := client.MakeClientset(restClient)
+
+	serverInfo, err := client.V1().Misc().ServerInfo()
+	if err != nil {
+		console.Warn(fmt.Sprintf("Error getting Fission API version: %v", err))
+		serverInfo = &info.ServerInfo{}
 	}
-	return client.MakeClientset(rest.NewRESTClient(serverUrl)), nil
+
+	return serverInfo
 }
 
-func GetServerURL(input cli.Input) (serverUrl string, err error) {
+func GetServerURL(input cli.Input, client cmd.Client) (serverUrl string, err error) {
 	serverUrl = input.GlobalString(flagkey.Server)
-	kubeContext := input.String(flagkey.KubeContext)
 	if len(serverUrl) == 0 {
 		// starts local portforwarder etc.
-		serverUrl, err = GetApplicationUrl(input.Context(), "application=fission-api", kubeContext)
+		serverUrl, err = GetApplicationUrl(input.Context(), client, "application=fission-api")
 		if err != nil {
 			return "", err
 		}
@@ -472,8 +401,8 @@ func ApplyLabelsAndAnnotations(input cli.Input, objectMeta *metav1.ObjectMeta) e
 	return nil
 }
 
-func GetStorageURL(ctx context.Context, kubeContext string) (*url.URL, error) {
-	storageLocalPort, err := SetupPortForward(ctx, GetFissionNamespace(), "application=fission-storage", kubeContext)
+func GetStorageURL(ctx context.Context, client cmd.Client) (*url.URL, error) {
+	storageLocalPort, err := SetupPortForward(ctx, client, GetFissionNamespace(), "application=fission-storage")
 	if err != nil {
 		return nil, err
 	}
@@ -486,30 +415,151 @@ func GetStorageURL(ctx context.Context, kubeContext string) (*url.URL, error) {
 	return serverURL, nil
 }
 
-func GetResourceNamespace(input cli.Input, deprecatedFlag string) (namespace, currentNS string, err error) {
-	namespace = input.String(deprecatedFlag)
-	currentNS = namespace
-
-	if input.String(flagkey.Namespace) != "" {
-		namespace = input.String(flagkey.Namespace)
-		currentNS = namespace
-		console.Verbose(2, "Namespace for resource %s ", currentNS)
-		return namespace, currentNS, err
+// CheckHTTPTriggerDuplicates checks whether the tuple (Method, Host, URL) is duplicate or not.
+func CheckHTTPTriggerDuplicates(ctx context.Context, client cmd.Client, t *fv1.HTTPTrigger) error {
+	triggers, err := client.FissionClientSet.CoreV1().HTTPTriggers(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
+	if err != nil {
+		return err
 	}
-
-	if namespace == "" {
-		if os.Getenv("FISSION_DEFAULT_NAMESPACE") != "" {
-			currentNS = os.Getenv("FISSION_DEFAULT_NAMESPACE")
-		} else {
-			kubeContext := input.String(flagkey.KubeContext)
-			currentNS, err = GetKubernetesNamespace(kubeContext)
-			if err != nil {
-				return namespace, currentNS, err
+	for _, ht := range triggers.Items {
+		if ht.ObjectMeta.UID == t.ObjectMeta.UID {
+			// Same resource. No need to check.
+			continue
+		}
+		urlMatch := false
+		if (ht.Spec.RelativeURL != "" && ht.Spec.RelativeURL == t.Spec.RelativeURL) || (ht.Spec.Prefix != nil && t.Spec.Prefix != nil && *ht.Spec.Prefix != "" && *ht.Spec.Prefix == *t.Spec.Prefix) {
+			urlMatch = true
+		}
+		methodMatch := false
+		if ht.Spec.Method == t.Spec.Method && len(ht.Spec.Methods) == len(t.Spec.Methods) {
+			methodMatch = true
+			sort.Strings(ht.Spec.Methods)
+			sort.Strings(t.Spec.Methods)
+			for i, m1 := range ht.Spec.Methods {
+				if m1 != t.Spec.Methods[i] {
+					methodMatch = false
+				}
 			}
 		}
+		if urlMatch && methodMatch && ht.Spec.Method == t.Spec.Method && ht.Spec.Host == t.Spec.Host {
+			return fmt.Errorf("HTTPTrigger with same Host, URL & method already exists (%v)",
+				ht.ObjectMeta.Name)
+		}
+	}
+	return nil
+}
+
+func SecretExists(ctx context.Context, m *metav1.ObjectMeta, kClient kubernetes.Interface) error {
+
+	_, err := kClient.CoreV1().Secrets(m.Namespace).Get(ctx, m.Name, metav1.GetOptions{})
+	return err
+}
+
+func ConfigMapExists(ctx context.Context, m *metav1.ObjectMeta, kClient kubernetes.Interface) error {
+
+	_, err := kClient.CoreV1().ConfigMaps(m.Namespace).Get(ctx, m.Name, metav1.GetOptions{})
+	return err
+}
+
+func GetSvcName(ctx context.Context, kClient kubernetes.Interface, application string) (string, error) {
+	var podNamespace = os.Getenv("POD_NAMESPACE")
+	if podNamespace == "" {
+		podNamespace = "fission"
+	}
+
+	appLabelSelector := "application=" + application
+
+	services, err := kClient.CoreV1().Services(podNamespace).List(ctx, metav1.ListOptions{
+		LabelSelector: appLabelSelector,
+	})
+	if err != nil {
+		return "", err
+	}
+
+	if len(services.Items) > 1 || len(services.Items) == 0 {
+		return "", errors.Errorf("more than one service found for application=%s", application)
+	}
+	service := services.Items[0]
+	return service.Name + "." + podNamespace, nil
+}
+
+// FunctionPodLogs : Get logs for a function directly from pod
+func FunctionPodLogs(ctx context.Context, fnName, ns string, client cmd.Client) (err error) {
+
+	podNs := "fission-function"
+
+	if len(ns) == 0 {
+		ns = metav1.NamespaceDefault
+	} else if ns != metav1.NamespaceDefault {
+		podNs = ns
+	}
+
+	f, err := client.FissionClientSet.CoreV1().Functions(ns).Get(ctx, fnName, metav1.GetOptions{})
+	if err != nil {
+		return err
 	}
 
-	console.Verbose(2, "Namespace for resource %s ", currentNS)
+	// Get function Pods first
+	selector := map[string]string{
+		fv1.FUNCTION_UID:          string(f.ObjectMeta.UID),
+		fv1.ENVIRONMENT_NAME:      f.Spec.Environment.Name,
+		fv1.ENVIRONMENT_NAMESPACE: f.Spec.Environment.Namespace,
+	}
+	podList, err := client.KubernetesClient.CoreV1().Pods(podNs).List(ctx, metav1.ListOptions{
+		LabelSelector: labels.Set(selector).AsSelector().String(),
+	})
+	if err != nil {
+		return err
+	}
+
+	// Get the logs for last Pod executed
+	pods := podList.Items
+	sort.Slice(pods, func(i, j int) bool {
+		rv1, _ := strconv.ParseInt(pods[i].ObjectMeta.ResourceVersion, 10, 32)
+		rv2, _ := strconv.ParseInt(pods[j].ObjectMeta.ResourceVersion, 10, 32)
+		return rv1 > rv2
+	})
+
+	if len(pods) <= 0 {
+		return errors.New("no active pods found")
+
+	}
+
+	// get the pod with highest resource version
+	err = getContainerLog(ctx, client.KubernetesClient, f, &pods[0])
+	if err != nil {
+		return errors.Wrapf(err, "error getting container logs")
+
+	}
+	return err
+}
+
+func getContainerLog(ctx context.Context, kubernetesClient kubernetes.Interface, fn *fv1.Function, pod *v1.Pod) (err error) {
+	seq := strings.Repeat("=", 35)
 
-	return namespace, currentNS, nil
+	for _, container := range pod.Spec.Containers {
+		podLogOpts := v1.PodLogOptions{Container: container.Name} // Only the env container, not fetcher
+		podLogsReq := kubernetesClient.CoreV1().Pods(pod.Namespace).GetLogs(pod.ObjectMeta.Name, &podLogOpts)
+
+		podLogs, err := podLogsReq.Stream(ctx)
+		if err != nil {
+			return errors.Wrapf(err, "error streaming pod log")
+		}
+
+		msg := fmt.Sprintf("\n%v\nFunction: %v\nEnvironment: %v\nNamespace: %v\nPod: %v\nContainer: %v\nNode: %v\n%v\n", seq,
+			fn.ObjectMeta.Name, fn.Spec.Environment.Name, pod.Namespace, pod.Name, container.Name, pod.Spec.NodeName, seq)
+
+		if _, err := io.WriteString(os.Stdout, msg); err != nil {
+			return errors.Wrapf(err, "error copying pod log")
+		}
+
+		_, err = io.Copy(os.Stdout, podLogs)
+		if err != nil {
+			return errors.Wrapf(err, "error copying pod log")
+		}
+
+		podLogs.Close()
+	}
+
+	return nil
 }
diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go
index 72f2a7f0..231bd3ca 100644
--- a/pkg/healthcheck/healthcheck.go
+++ b/pkg/healthcheck/healthcheck.go
@@ -24,7 +24,8 @@ import (
 	"k8s.io/client-go/kubernetes"
 
 	fv1 "github.com/fission/fission/pkg/apis/core/v1"
-	"github.com/fission/fission/pkg/controller/client"
+	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
+	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
@@ -50,18 +51,11 @@ type Category struct {
 
 type Checker struct {
 	successMsg string
-	check      func(ctx context.Context) error
-}
-
-type Options struct {
-	KubeContext   string
-	FissionClient client.Interface
+	check      func(ctx context.Context, input cli.Input, client cmd.Client) error
 }
 
 type HealthChecker struct {
-	categories []*Category
-	*Options
-
+	categories       []*Category
 	kubeAPI          kubernetes.Interface
 	fissionNamespace string
 }
@@ -120,8 +114,8 @@ func (hc *HealthChecker) CheckServiceStatus(ctx context.Context, namespace strin
 	return nil
 }
 
-func (hc *HealthChecker) CheckFissionVersion(ctx context.Context) error {
-	ver := util.GetVersion(ctx, hc.FissionClient)
+func (hc *HealthChecker) CheckFissionVersion(ctx context.Context, input cli.Input, client cmd.Client) error {
+	ver := util.GetVersion(ctx, input, client)
 
 	clientVersion := ver.Client["fission/core"].Version
 	serverVersion := ver.Server["fission/core"].Version
@@ -148,7 +142,7 @@ func (hc *HealthChecker) allCategories() []*Category {
 			[]Checker{
 				{
 					successMsg: "kubernetes version is compatible",
-					check: func(ctx context.Context) (err error) {
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) (err error) {
 						return hc.CheckKubeVersion()
 					},
 				},
@@ -160,25 +154,25 @@ func (hc *HealthChecker) allCategories() []*Category {
 			[]Checker{
 				{
 					successMsg: "controller is running fine",
-					check: func(ctx context.Context) error {
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) error {
 						return hc.CheckServiceStatus(ctx, hc.fissionNamespace, "controller")
 					},
 				},
 				{
 					successMsg: "executor is running fine",
-					check: func(ctx context.Context) error {
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) error {
 						return hc.CheckServiceStatus(ctx, hc.fissionNamespace, "executor")
 					},
 				},
 				{
 					successMsg: "router is running fine",
-					check: func(ctx context.Context) error {
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) error {
 						return hc.CheckServiceStatus(ctx, hc.fissionNamespace, "router")
 					},
 				},
 				{
 					successMsg: "storagesvc is running fine",
-					check: func(ctx context.Context) error {
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) error {
 						return hc.CheckServiceStatus(ctx, hc.fissionNamespace, "storagesvc")
 					},
 				},
@@ -190,8 +184,8 @@ func (hc *HealthChecker) allCategories() []*Category {
 			[]Checker{
 				{
 					successMsg: "fission is up-to-date",
-					check: func(ctx context.Context) error {
-						return hc.CheckFissionVersion(ctx)
+					check: func(ctx context.Context, input cli.Input, client cmd.Client) error {
+						return hc.CheckFissionVersion(ctx, input, client)
 					},
 				},
 			},
@@ -200,15 +194,12 @@ func (hc *HealthChecker) allCategories() []*Category {
 	}
 }
 
-func NewHealthChecker(categoryIDs []CategoryID, options *Options) *HealthChecker {
+func NewHealthChecker(cmd cmd.Client, categoryIDs []CategoryID) *HealthChecker {
 	hc := &HealthChecker{
-		Options: options,
+		kubeAPI:          cmd.KubernetesClient,
+		fissionNamespace: "fission",
 	}
 
-	_, clientset, _ := util.GetKubernetesClient(hc.KubeContext)
-	hc.kubeAPI = clientset
-	hc.fissionNamespace = "fission"
-
 	hc.categories = hc.allCategories()
 
 	checkMap := map[CategoryID]struct{}{}
@@ -224,13 +215,13 @@ func NewHealthChecker(categoryIDs []CategoryID, options *Options) *HealthChecker
 	return hc
 }
 
-func RunChecks(ctx context.Context, hc *HealthChecker) {
+func RunChecks(ctx context.Context, input cli.Input, client cmd.Client, hc *HealthChecker) {
 	for _, c := range hc.categories {
 		if c.enabled {
 			fmt.Println(c.ID)
 			fmt.Println(strings.Repeat("-", 20))
 			for _, checker := range c.checkers {
-				err := checker.check(ctx)
+				err := checker.check(ctx, input, client)
 				if err != nil {
 					fmt.Printf("%s %s\n", failStatus, err)
 				} else {
diff --git a/pkg/router/functionReferenceResolver.go b/pkg/router/functionReferenceResolver.go
index 09c71f9b..febb9b77 100644
--- a/pkg/router/functionReferenceResolver.go
+++ b/pkg/router/functionReferenceResolver.go
@@ -122,9 +122,6 @@ func (frr *functionReferenceResolver) resolve(trigger fv1.HTTPTrigger) (*resolve
 }
 
 func (frr *functionReferenceResolver) getInformerByNamespace(namespace string) (k8sCache.SharedIndexInformer, error) {
-	if informer, ok := frr.funcInformer[metav1.NamespaceAll]; ok {
-		return informer, nil
-	}
 	if informer, ok := frr.funcInformer[namespace]; ok {
 		return informer, nil
 	}
diff --git a/pkg/storagesvc/archivePruner.go b/pkg/storagesvc/archivePruner.go
index 275ccac4..a08ebdd7 100644
--- a/pkg/storagesvc/archivePruner.go
+++ b/pkg/storagesvc/archivePruner.go
@@ -25,6 +25,7 @@ import (
 
 	"github.com/fission/fission/pkg/crd"
 	"github.com/fission/fission/pkg/generated/clientset/versioned"
+	"github.com/fission/fission/pkg/utils"
 )
 
 type ArchivePruner struct {
@@ -82,33 +83,35 @@ func (pruner *ArchivePruner) getOrphanArchives(ctx context.Context) {
 	var archiveID string
 
 	// get all pkgs from kubernetes
-	pkgList, err := pruner.crdClient.CoreV1().Packages(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
-	if err != nil {
-		pruner.logger.Error("error getting package list from kubernetes", zap.Error(err))
-		return
-	}
+	for _, namespace := range utils.GetNamespaces() {
+		pkgList, err := pruner.crdClient.CoreV1().Packages(namespace).List(ctx, metav1.ListOptions{})
+		if err != nil {
+			pruner.logger.Error("error getting package list from kubernetes", zap.Error(err))
+			return
+		}
 
-	// extract archives referenced by these pkgs
-	for _, pkg := range pkgList.Items {
-		if pkg.Spec.Deployment.URL != "" {
-			archiveID, err = getQueryParamValue(pkg.Spec.Deployment.URL, "id")
-			if err != nil {
-				pruner.logger.Error("error extracting value of archiveID from deployment url",
-					zap.Error(err),
-					zap.String("url", pkg.Spec.Deployment.URL))
-				return
+		// extract archives referenced by these pkgs
+		for _, pkg := range pkgList.Items {
+			if pkg.Spec.Deployment.URL != "" {
+				archiveID, err = getQueryParamValue(pkg.Spec.Deployment.URL, "id")
+				if err != nil {
+					pruner.logger.Error("error extracting value of archiveID from deployment url",
+						zap.Error(err),
+						zap.String("url", pkg.Spec.Deployment.URL))
+					return
+				}
+				archivesRefByPkgs = append(archivesRefByPkgs, archiveID)
 			}
-			archivesRefByPkgs = append(archivesRefByPkgs, archiveID)
-		}
-		if pkg.Spec.Source.URL != "" {
-			archiveID, err = getQueryParamValue(pkg.Spec.Source.URL, "id")
-			if err != nil {
-				pruner.logger.Error("error extracting value of archiveID from source url",
-					zap.Error(err),
-					zap.String("url", pkg.Spec.Source.URL))
-				return
+			if pkg.Spec.Source.URL != "" {
+				archiveID, err = getQueryParamValue(pkg.Spec.Source.URL, "id")
+				if err != nil {
+					pruner.logger.Error("error extracting value of archiveID from source url",
+						zap.Error(err),
+						zap.String("url", pkg.Spec.Source.URL))
+					return
+				}
+				archivesRefByPkgs = append(archivesRefByPkgs, archiveID)
 			}
-			archivesRefByPkgs = append(archivesRefByPkgs, archiveID)
 		}
 	}
 
diff --git a/pkg/storagesvc/client/client.go b/pkg/storagesvc/client/client.go
index 417c0f09..3eff1c4d 100644
--- a/pkg/storagesvc/client/client.go
+++ b/pkg/storagesvc/client/client.go
@@ -185,6 +185,21 @@ func (c *Client) Download(ctx context.Context, id string, filePath string) error
 	return nil
 }
 
+// Download fetches the file identified by ID to the local file path.
+// filePath must not exist.
+func (c *Client) GetFile(ctx context.Context, id string) (resp *http.Response, err error) {
+	// url for id
+	url := c.GetUrl(id)
+
+	// make request
+	resp, err = ctxhttp.Get(ctx, c.httpClient, url)
+	if err != nil {
+		return resp, err
+	}
+
+	return resp, err
+}
+
 func (c *Client) Delete(ctx context.Context, id string) error {
 	url := c.GetUrl(id)
 
diff --git a/pkg/utils/otel/log.go b/pkg/utils/otel/log.go
index 50c11444..2517facf 100644
--- a/pkg/utils/otel/log.go
+++ b/pkg/utils/otel/log.go
@@ -22,8 +22,8 @@ import (
 	"go.uber.org/zap"
 )
 
-func LoggerWithTraceID(context context.Context, logger *zap.Logger) *zap.Logger {
-	if span := trace.SpanContextFromContext(context); span.TraceID().IsValid() {
+func LoggerWithTraceID(ctx context.Context, logger *zap.Logger) *zap.Logger {
+	if span := trace.SpanContextFromContext(ctx); span.TraceID().IsValid() {
 		return logger.With(zap.String("trace_id", span.TraceID().String()))
 	}
 	return logger


Test patch:
diff --git a/pkg/controller/api_test.go b/pkg/controller/api_test.go
index 2aeefe20..e6d13b16 100644
--- a/pkg/controller/api_test.go
+++ b/pkg/controller/api_test.go
@@ -44,9 +44,9 @@ import (
 )
 
 var (
-	g struct {
-		cmd.CommandActioner
-	}
+	// g struct {
+	// 	cmd.CommandActioner
+	// }
 	testNS = metav1.NamespaceDefault
 )
 
@@ -105,41 +105,45 @@ func TestFunctionApi(t *testing.T) {
 			},
 		},
 	}
-	_, err := g.Client().V1().Function().Get(&metav1.ObjectMeta{
+
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+
+	_, err := dClient.V1().Function().Get(&metav1.ObjectMeta{
 		Name:      testFunc.ObjectMeta.Name,
 		Namespace: testNS,
 	})
 	assertNotFoundFailure(err, "function")
 
-	m, err := g.Client().V1().Function().Create(testFunc)
+	m, err := dClient.V1().Function().Create(testFunc)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().Function().Delete(m)
+		err := dClient.V1().Function().Delete(m)
 		panicIf(err)
 	}()
 
-	_, err = g.Client().V1().Function().Create(testFunc)
+	_, err = dClient.V1().Function().Create(testFunc)
 	assertNameReuseFailure(err, "function")
 
 	testFunc.ObjectMeta.ResourceVersion = m.ResourceVersion
 	testFunc.Spec.Package.FunctionName = "yyy"
-	_, err = g.Client().V1().Function().Update(testFunc)
+	_, err = dClient.V1().Function().Update(testFunc)
 	panicIf(err)
 
 	testFunc.ObjectMeta.ResourceVersion = ""
 	testFunc.ObjectMeta.Name = "bar"
-	m2, err := g.Client().V1().Function().Create(testFunc)
+	m2, err := dClient.V1().Function().Create(testFunc)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().Function().Delete(m2)
+		err := dClient.V1().Function().Delete(m2)
 		panicIf(err)
 	}()
 
-	funcs, err := g.Client().V1().Function().List(testNS)
+	funcs, err := dClient.V1().Function().List(testNS)
 	panicIf(err)
 	assert(len(funcs) == 2, fmt.Sprintf("created two functions, but found %v", len(funcs)))
 
-	funcs_url := g.Client().ServerURL() + "/v2/functions"
+	funcs_url := dClient.ServerURL() + "/v2/functions"
 	resp, err := http.Get(funcs_url)
 	panicIf(err)
 	defer resp.Body.Close()
@@ -169,23 +173,27 @@ func TestHTTPTriggerApi(t *testing.T) {
 			},
 		},
 	}
-	_, err := g.Client().V1().HTTPTrigger().Get(&metav1.ObjectMeta{
+
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+
+	_, err := dClient.V1().HTTPTrigger().Get(&metav1.ObjectMeta{
 		Name:      testTrigger.ObjectMeta.Name,
 		Namespace: testNS,
 	})
 	assertNotFoundFailure(err, "httptrigger")
 
-	m, err := g.Client().V1().HTTPTrigger().Create(testTrigger)
+	m, err := dClient.V1().HTTPTrigger().Create(testTrigger)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().HTTPTrigger().Delete(m)
+		err := dClient.V1().HTTPTrigger().Delete(m)
 		panicIf(err)
 	}()
 
-	_, err = g.Client().V1().HTTPTrigger().Create(testTrigger)
+	_, err = dClient.V1().HTTPTrigger().Create(testTrigger)
 	assertNameReuseFailure(err, "httptrigger")
 
-	tr, err := g.Client().V1().HTTPTrigger().Get(m)
+	tr, err := dClient.V1().HTTPTrigger().Get(m)
 	panicIf(err)
 	assert(len(testTrigger.Spec.Methods) == len(tr.Spec.Methods) &&
 		testTrigger.Spec.RelativeURL == tr.Spec.RelativeURL &&
@@ -194,23 +202,23 @@ func TestHTTPTriggerApi(t *testing.T) {
 
 	testTrigger.ObjectMeta.ResourceVersion = m.ResourceVersion
 	testTrigger.Spec.RelativeURL = "/hi"
-	_, err = g.Client().V1().HTTPTrigger().Update(testTrigger)
+	_, err = dClient.V1().HTTPTrigger().Update(testTrigger)
 	panicIf(err)
 
 	testTrigger.ObjectMeta.ResourceVersion = ""
 	testTrigger.ObjectMeta.Name = "yyy"
-	_, err = g.Client().V1().HTTPTrigger().Create(testTrigger)
+	_, err = dClient.V1().HTTPTrigger().Create(testTrigger)
 	assert(err != nil, "duplicate trigger should not be allowed")
 
 	testTrigger.Spec.RelativeURL = "/hi2"
-	m2, err := g.Client().V1().HTTPTrigger().Create(testTrigger)
+	m2, err := dClient.V1().HTTPTrigger().Create(testTrigger)
 	panicIf(err)
 	defer func() {
-		err = g.Client().V1().HTTPTrigger().Delete(m2)
+		err = dClient.V1().HTTPTrigger().Delete(m2)
 		panicIf(err)
 	}()
 
-	ts, err := g.Client().V1().HTTPTrigger().List(testNS)
+	ts, err := dClient.V1().HTTPTrigger().List(testNS)
 	panicIf(err)
 	assert(len(ts) == 2, fmt.Sprintf("created two triggers, but found %v", len(ts)))
 }
@@ -237,7 +245,9 @@ func createFissionFnForMultipleTrigger() {
 		},
 	}
 
-	_, err := g.Client().V1().Function().Create(testFunc)
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+	_, err := dClient.V1().Function().Create(testFunc)
 	panicIf(err)
 	defer func() {
 		panicIf(err)
@@ -245,7 +255,7 @@ func createFissionFnForMultipleTrigger() {
 
 	testFunc.Name = "foo2"
 
-	_, err = g.Client().V1().Function().Create(testFunc)
+	_, err = dClient.V1().Function().Create(testFunc)
 	panicIf(err)
 	defer func() {
 		panicIf(err)
@@ -272,9 +282,11 @@ func TestHTTPTriggerCreateMultipleTrigger(t *testing.T) {
 		},
 	}
 
-	m, err := g.Client().V1().HTTPTrigger().Create(testTrigger)
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+	m, err := dClient.V1().HTTPTrigger().Create(testTrigger)
 	panicIf(err)
-	defer panicIf(g.Client().V1().HTTPTrigger().Delete(m))
+	defer panicIf(dClient.V1().HTTPTrigger().Delete(m))
 
 	prefix_2 := "url_another"
 	testTrigger2 := &fv1.HTTPTrigger{
@@ -293,7 +305,7 @@ func TestHTTPTriggerCreateMultipleTrigger(t *testing.T) {
 		},
 	}
 
-	m2, err := g.Client().V1().HTTPTrigger().Create(testTrigger2)
+	m2, err := dClient.V1().HTTPTrigger().Create(testTrigger2)
 
 	if err != nil {
 		t.Fatal()
@@ -301,7 +313,7 @@ func TestHTTPTriggerCreateMultipleTrigger(t *testing.T) {
 
 	defer func() {
 		if m2 != nil {
-			err := g.Client().V1().HTTPTrigger().Delete(m2)
+			err := dClient.V1().HTTPTrigger().Delete(m2)
 			if err != nil {
 				logger.Error("Error deleting http trigger", zap.String("name", m2.Name), zap.Error(err))
 			}
@@ -324,42 +336,46 @@ func TestEnvironmentApi(t *testing.T) {
 			Resources: v1.ResourceRequirements{},
 		},
 	}
-	_, err := g.Client().V1().Environment().Get(&metav1.ObjectMeta{
+
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+
+	_, err := dClient.V1().Environment().Get(&metav1.ObjectMeta{
 		Name:      testEnv.ObjectMeta.Name,
 		Namespace: testNS,
 	})
 	assertNotFoundFailure(err, "environment")
 
-	m, err := g.Client().V1().Environment().Create(testEnv)
+	m, err := dClient.V1().Environment().Create(testEnv)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().Environment().Delete(m)
+		err := dClient.V1().Environment().Delete(m)
 		panicIf(err)
 	}()
 
-	_, err = g.Client().V1().Environment().Create(testEnv)
+	_, err = dClient.V1().Environment().Create(testEnv)
 	assertNameReuseFailure(err, "environment")
 
-	e, err := g.Client().V1().Environment().Get(m)
+	e, err := dClient.V1().Environment().Get(m)
 	panicIf(err)
 	assert(reflect.DeepEqual(testEnv.Spec, e.Spec), "env should match after reading")
 
 	testEnv.ObjectMeta.ResourceVersion = m.ResourceVersion
 	testEnv.Spec.Runtime.Image = "another-img"
-	_, err = g.Client().V1().Environment().Update(testEnv)
+	_, err = dClient.V1().Environment().Update(testEnv)
 	panicIf(err)
 
 	testEnv.ObjectMeta.ResourceVersion = ""
 	testEnv.ObjectMeta.Name = "bar"
 
-	m2, err := g.Client().V1().Environment().Create(testEnv)
+	m2, err := dClient.V1().Environment().Create(testEnv)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().Environment().Delete(m2)
+		err := dClient.V1().Environment().Delete(m2)
 		panicIf(err)
 	}()
 
-	ts, err := g.Client().V1().Environment().List(testNS)
+	ts, err := dClient.V1().Environment().List(testNS)
 	panicIf(err)
 	assert(len(ts) == 2, fmt.Sprintf("created two envs, but found %v", len(ts)))
 }
@@ -379,23 +395,27 @@ func TestWatchApi(t *testing.T) {
 			},
 		},
 	}
-	_, err := g.Client().V1().KubeWatcher().Get(&metav1.ObjectMeta{
+
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+
+	_, err := dClient.V1().KubeWatcher().Get(&metav1.ObjectMeta{
 		Name:      testWatch.ObjectMeta.Name,
 		Namespace: testNS,
 	})
 	assertNotFoundFailure(err, "watch")
 
-	m, err := g.Client().V1().KubeWatcher().Create(testWatch)
+	m, err := dClient.V1().KubeWatcher().Create(testWatch)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().KubeWatcher().Delete(m)
+		err := dClient.V1().KubeWatcher().Delete(m)
 		panicIf(err)
 	}()
 
-	_, err = g.Client().V1().KubeWatcher().Create(testWatch)
+	_, err = dClient.V1().KubeWatcher().Create(testWatch)
 	assertNameReuseFailure(err, "watch")
 
-	w, err := g.Client().V1().KubeWatcher().Get(m)
+	w, err := dClient.V1().KubeWatcher().Get(m)
 	panicIf(err)
 	assert(testWatch.Spec.Namespace == w.Spec.Namespace &&
 		testWatch.Spec.Type == w.Spec.Type &&
@@ -403,14 +423,14 @@ func TestWatchApi(t *testing.T) {
 		testWatch.Spec.FunctionReference.Name == w.Spec.FunctionReference.Name, "watch should match after reading")
 
 	testWatch.ObjectMeta.Name = "yyy"
-	m2, err := g.Client().V1().KubeWatcher().Create(testWatch)
+	m2, err := dClient.V1().KubeWatcher().Create(testWatch)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().KubeWatcher().Delete(m2)
+		err := dClient.V1().KubeWatcher().Delete(m2)
 		panicIf(err)
 	}()
 
-	ws, err := g.Client().V1().KubeWatcher().List(testNS)
+	ws, err := dClient.V1().KubeWatcher().List(testNS)
 	panicIf(err)
 	assert(len(ws) == 2, fmt.Sprintf("created two watches, but found %v", len(ws)))
 }
@@ -429,20 +449,24 @@ func TestTimeTriggerApi(t *testing.T) {
 			},
 		},
 	}
-	_, err := g.Client().V1().TimeTrigger().Get(&metav1.ObjectMeta{Name: testTrigger.ObjectMeta.Name})
+
+	restClient := rest.NewRESTClient("http://localhost:8888")
+	dClient := client.MakeClientset(restClient)
+
+	_, err := dClient.V1().TimeTrigger().Get(&metav1.ObjectMeta{Name: testTrigger.ObjectMeta.Name})
 	assertNotFoundFailure(err, "trigger")
 
-	m, err := g.Client().V1().TimeTrigger().Create(testTrigger)
+	m, err := dClient.V1().TimeTrigger().Create(testTrigger)
 	panicIf(err)
 	defer func() {
-		err := g.Client().V1().TimeTrigger().Delete(m)
+		err := dClient.V1().TimeTrigger().Delete(m)
 		panicIf(err)
 	}()
 
-	_, err = g.Client().V1().TimeTrigger().Create(testTrigger)
+	_, err = dClient.V1().TimeTrigger().Create(testTrigger)
 	assertNameReuseFailure(err, "trigger")
 
-	tr, err := g.Client().V1().TimeTrigger().Get(m)
+	tr, err := dClient.V1().TimeTrigger().Get(m)
 	panicIf(err)
 	assert(testTrigger.Spec.Cron == tr.Spec.Cron &&
 		testTrigger.Spec.FunctionReference.Type == tr.Spec.FunctionReference.Type &&
@@ -450,16 +474,16 @@ func TestTimeTriggerApi(t *testing.T) {
 
 	testTrigger.ObjectMeta.ResourceVersion = m.ResourceVersion
 	testTrigger.Spec.Cron = "@hourly"
-	_, err = g.Client().V1().TimeTrigger().Update(testTrigger)
+	_, err = dClient.V1().TimeTrigger().Update(testTrigger)
 	panicIf(err)
 
 	testTrigger.ObjectMeta.ResourceVersion = ""
 	testTrigger.ObjectMeta.Name = "yyy"
 	testTrigger.Spec.Cron = "Not valid cron spec"
-	_, err = g.Client().V1().TimeTrigger().Create(testTrigger)
+	_, err = dClient.V1().TimeTrigger().Create(testTrigger)
 	assertCronSpecFails(err)
 
-	ts, err := g.Client().V1().TimeTrigger().List(testNS)
+	ts, err := dClient.V1().TimeTrigger().List(testNS)
 	panicIf(err)
 	assert(len(ts) == 1, fmt.Sprintf("created two time triggers, but found %v", len(ts)))
 }
@@ -497,9 +521,10 @@ func TestMain(m *testing.M) {
 
 	time.Sleep(5 * time.Second)
 
-	restClient := rest.NewRESTClient("http://localhost:8888")
+	client, err := cmd.NewClient(cmd.ClientOptions{})
+	panicIf(err)
 	// TODO: use fake rest client for offline spec generation
-	cmd.SetClientset(client.MakeClientset(restClient))
+	cmd.SetClientset(*client)
 
 	resp, err := http.Get("http://localhost:8888/")
 	panicIf(err)
diff --git a/pkg/fission-cli/cmd/function/test.go b/pkg/fission-cli/cmd/function/test.go
index 5582d2c6..8768afc5 100644
--- a/pkg/fission-cli/cmd/function/test.go
+++ b/pkg/fission-cli/cmd/function/test.go
@@ -32,7 +32,6 @@ import (
 	"go.opentelemetry.io/otel"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"github.com/fission/fission/pkg/controller/client"
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
@@ -52,7 +51,7 @@ func Test(input cli.Input) error {
 
 func (opts *TestSubCommand) do(input cli.Input) error {
 
-	_, namespace, err := util.GetResourceNamespace(input, flagkey.NamespaceFunction)
+	_, namespace, err := opts.GetResourceNamespace(input, flagkey.NamespaceFunction)
 	if err != nil {
 		return errors.Wrap(err, "error in testing function ")
 	}
@@ -61,14 +60,13 @@ func (opts *TestSubCommand) do(input cli.Input) error {
 		Name:      input.String(flagkey.FnName),
 		Namespace: namespace,
 	}
-	kubeContext := input.String(flagkey.KubeContext)
 	routerURL := os.Getenv("FISSION_ROUTER")
 	if len(routerURL) != 0 {
 		console.Warn("The environment variable FISSION_ROUTER is no longer supported for this command")
 	}
 
 	// Portforward to the fission router
-	localRouterPort, err := util.SetupPortForward(input.Context(), util.GetFissionNamespace(), "application=fission-router", kubeContext)
+	localRouterPort, err := util.SetupPortForward(input.Context(), opts.Client(), util.GetFissionNamespace(), "application=fission-router")
 	if err != nil {
 		return err
 	}
@@ -150,15 +148,13 @@ func (opts *TestSubCommand) do(input cli.Input) error {
 	}
 
 	console.Errorf("Error calling function %s: %d; Please try again or fix the error: %s\n", m.Name, resp.StatusCode, string(body))
-	log, err := printPodLogs(opts.Client(), m)
+	err = printPodLogs(input.Context(), opts.Client(), m)
 	if err != nil {
 		console.Errorf("Error getting function logs from controller: %v. Try to get logs from log database.", err)
 		err = Log(input)
 		if err != nil {
 			return errors.Wrapf(err, "error retrieving function log from log database")
 		}
-	} else {
-		console.Info(log)
 	}
 	return errors.New("error getting function response")
 }
@@ -224,21 +220,12 @@ func doHTTPRequest(ctx context.Context, url string, headers []string, method, bo
 	return resp, nil
 }
 
-func printPodLogs(client client.Interface, fnMeta *metav1.ObjectMeta) (string, error) {
-	reader, statusCode, err := client.V1().Misc().PodLogs(fnMeta)
-	if err != nil {
-		return "", errors.Wrap(err, "error executing get logs request")
-	}
-	defer reader.Close()
+func printPodLogs(ctx context.Context, client cmd.Client, fnMeta *metav1.ObjectMeta) error {
+	err := util.FunctionPodLogs(ctx, fnMeta.Name, fnMeta.Namespace, client)
 
-	body, err := io.ReadAll(reader)
 	if err != nil {
-		return "", errors.Wrap(err, "error reading the response body")
-	}
-
-	if statusCode != http.StatusOK {
-		return string(body), errors.Errorf("error getting logs from controller, status code: '%v'", statusCode)
+		return errors.Wrap(err, "error executing get logs request")
 	}
 
-	return string(body), nil
+	return nil
 }
diff --git a/pkg/fission-cli/cmd/timetrigger/test.go b/pkg/fission-cli/cmd/timetrigger/test.go
index e9365370..cd30e77e 100644
--- a/pkg/fission-cli/cmd/timetrigger/test.go
+++ b/pkg/fission-cli/cmd/timetrigger/test.go
@@ -22,6 +22,7 @@ import (
 	"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
 	"github.com/fission/fission/pkg/fission-cli/cmd"
 	flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
+	"github.com/fission/fission/pkg/fission-cli/util"
 )
 
 type ShowSubCommand struct {
@@ -44,12 +45,9 @@ func (opts *ShowSubCommand) run(flaginput cli.Input) error {
 		return errors.New("need a cron spec like '0 30 * * * *', '@every 1h30m', or '@hourly'; use --cron")
 	}
 
-	t, err := getAPITimeInfo(opts.Client())
-	if err != nil {
-		return err
-	}
+	t := util.GetServerInfo(flaginput, opts.Client()).ServerTime.CurrentTime.UTC()
 
-	err = getCronNextNActivationTime(cronSpec, t, round)
+	err := getCronNextNActivationTime(cronSpec, t, round)
 	if err != nil {
 		return errors.Wrap(err, "error passing cron spec examination")
 	}
diff --git a/pkg/fission-cli/util/util_test.go b/pkg/fission-cli/util/util_test.go
index dedf0e78..cb510a3e 100644
--- a/pkg/fission-cli/util/util_test.go
+++ b/pkg/fission-cli/util/util_test.go
@@ -65,10 +65,10 @@ func TestGetEnvVarFromStringSlice(t *testing.T) {
 	}
 }
 
-func TestGetConfig(t *testing.T) {
-	response, err := GetKubernetesNamespace("")
-	if err != nil {
-		t.Log(err)
-	}
-	t.Log("Current NS: ", response)
-}
+// func TestGetConfig(t *testing.T) {
+// 	response, err := GetKubernetesNamespace("")
+// 	if err != nil {
+// 		t.Log(err)
+// 	}
+// 	t.Log("Current NS: ", response)
+// }