diff --git a/cmd/apply.go b/cmd/apply.go
index ab0065b3c9433f735eb8a81a32b0d8d9e5bf8413..8462118070a322b5da71c51cf32fc9f132714c52 100644
--- a/cmd/apply.go
+++ b/cmd/apply.go
@@ -57,7 +57,7 @@ func init() {
 }
 
 var applyCmd = &cobra.Command{
-	Use:   "apply [<env>|-f <file-or-dir>]",
+	Use:   "apply [env-name] [-f <file-or-dir>]",
 	Short: `Apply local configuration to remote cluster`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		flags := cmd.Flags()
@@ -85,27 +85,33 @@ var applyCmd = &cobra.Command{
 			return err
 		}
 
-		c.ClientPool, c.Discovery, err = restClientPool(cmd)
+		cwd, err := os.Getwd()
 		if err != nil {
 			return err
 		}
+		wd := metadata.AbsPath(cwd)
 
-		c.DefaultNamespace, _, err = clientConfig.Namespace()
+		envSpec, err := parseEnvCmd(cmd, args)
 		if err != nil {
 			return err
 		}
 
-		cwd, err := os.Getwd()
+		c.ClientPool, c.Discovery, err = restClientPool(cmd, envSpec.env)
 		if err != nil {
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		c.DefaultNamespace, err = defaultNamespace(clientConfig)
 		if err != nil {
 			return err
 		}
 
-		return c.Run(objs, metadata.AbsPath(cwd))
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
+		if err != nil {
+			return err
+		}
+
+		return c.Run(objs, wd)
 	},
 	Long: `Update (or optionally create) Kubernetes resources on the cluster using the
 local configuration. Use the '--create' flag to control whether we create them
@@ -122,6 +128,10 @@ files.`,
   # the cluster's location from '$KUBECONFIG'.
   ksonnet appy -f ./pod.yaml
 
+  # Create or update resources described in the JSON file. Changes are deployed
+  # to the cluster pointed at the 'dev' environment.
+  ksonnet apply dev -f ./pod.json
+
   # Update resources described in a YAML file, and running in cluster referred
   # to by './kubeconfig'.
   ksonnet apply --kubeconfig=./kubeconfig -f ./pod.yaml
diff --git a/cmd/delete.go b/cmd/delete.go
index 5ebe5ba30d0cee04b0e713a04264e6b9d959bd2c..e0dc3f564beef3ef7502c8eca3bfab7eb9d3b4ff 100644
--- a/cmd/delete.go
+++ b/cmd/delete.go
@@ -16,8 +16,11 @@
 package cmd
 
 import (
+	"os"
+
 	"github.com/spf13/cobra"
 
+	"github.com/ksonnet/kubecfg/metadata"
 	"github.com/ksonnet/kubecfg/pkg/kubecfg"
 )
 
@@ -32,7 +35,7 @@ func init() {
 }
 
 var deleteCmd = &cobra.Command{
-	Use:   "delete",
+	Use:   "delete [env-name] [-f <file-or-dir>]",
 	Short: "Delete Kubernetes resources described in local config",
 	RunE: func(cmd *cobra.Command, args []string) error {
 		flags := cmd.Flags()
@@ -45,7 +48,18 @@ var deleteCmd = &cobra.Command{
 			return err
 		}
 
-		c.ClientPool, c.Discovery, err = restClientPool(cmd)
+		cwd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		wd := metadata.AbsPath(cwd)
+
+		envSpec, err := parseEnvCmd(cmd, args)
+		if err != nil {
+			return err
+		}
+
+		c.ClientPool, c.Discovery, err = restClientPool(cmd, envSpec.env)
 		if err != nil {
 			return err
 		}
@@ -55,7 +69,7 @@ var deleteCmd = &cobra.Command{
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
 		if err != nil {
 			return err
 		}
diff --git a/cmd/diff.go b/cmd/diff.go
index 887631a0ce73267dfc30938167bbfb9bce420353..bfcd7287cdb8f02266818c777d04c9e88e29a92d 100644
--- a/cmd/diff.go
+++ b/cmd/diff.go
@@ -16,8 +16,11 @@
 package cmd
 
 import (
+	"os"
+
 	"github.com/spf13/cobra"
 
+	"github.com/ksonnet/kubecfg/metadata"
 	"github.com/ksonnet/kubecfg/pkg/kubecfg"
 )
 
@@ -30,7 +33,7 @@ func init() {
 }
 
 var diffCmd = &cobra.Command{
-	Use:   "diff [<env>|-f <file-or-dir>]",
+	Use:   "diff [env-name] [-f <file-or-dir>]",
 	Short: "Display differences between server and local config",
 	RunE: func(cmd *cobra.Command, args []string) error {
 		flags := cmd.Flags()
@@ -43,7 +46,18 @@ var diffCmd = &cobra.Command{
 			return err
 		}
 
-		c.ClientPool, c.Discovery, err = restClientPool(cmd)
+		cwd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		wd := metadata.AbsPath(cwd)
+
+		envSpec, err := parseEnvCmd(cmd, args)
+		if err != nil {
+			return err
+		}
+
+		c.ClientPool, c.Discovery, err = restClientPool(cmd, envSpec.env)
 		if err != nil {
 			return err
 		}
@@ -53,7 +67,7 @@ var diffCmd = &cobra.Command{
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
 		if err != nil {
 			return err
 		}
@@ -67,12 +81,16 @@ files.`,
 	Example: `  # Show diff between resources described in a local ksonnet application and
   # the cluster referenced by the 'dev' environment. Can be used in any
   # subdirectory of the application.
-  ksonnet diff -e=dev
+  ksonnet diff dev
 
   # Show diff between resources described in a YAML file and the cluster
   # referenced in '$KUBECONFIG'.
   ksonnet diff -f ./pod.yaml
 
+  # Show diff between resources described in a JSON file and the cluster
+  # referenced by the environment 'dev'.
+  ksonnet diff dev -f ./pod.json
+
   # Show diff between resources described in a YAML file and the cluster
   # referred to by './kubeconfig'.
   ksonnet diff --kubeconfig=./kubeconfig -f ./pod.yaml`,
diff --git a/cmd/env.go b/cmd/env.go
index adeec29bc8c4d62a12a609d0e7174a7928551623..68c3a8bcc962d7d8e6bb3be0113c62bb359cc108 100644
--- a/cmd/env.go
+++ b/cmd/env.go
@@ -101,12 +101,17 @@ var envAddCmd = &cobra.Command{
 		}
 		appRoot := metadata.AbsPath(appDir)
 
+		manager, err := metadata.Find(appRoot)
+		if err != nil {
+			return err
+		}
+
 		specFlag, err := flags.GetString(flagAPISpec)
 		if err != nil {
 			return err
 		}
 
-		c, err := kubecfg.NewEnvAddCmd(envName, envURI, specFlag, appRoot)
+		c, err := kubecfg.NewEnvAddCmd(envName, envURI, specFlag, manager)
 		if err != nil {
 			return err
 		}
@@ -168,7 +173,12 @@ var envRmCmd = &cobra.Command{
 		}
 		appRoot := metadata.AbsPath(appDir)
 
-		c, err := kubecfg.NewEnvRmCmd(envName, appRoot)
+		manager, err := metadata.Find(appRoot)
+		if err != nil {
+			return err
+		}
+
+		c, err := kubecfg.NewEnvRmCmd(envName, manager)
 		if err != nil {
 			return err
 		}
@@ -201,7 +211,12 @@ var envListCmd = &cobra.Command{
 		}
 		appRoot := metadata.AbsPath(appDir)
 
-		c, err := kubecfg.NewEnvListCmd(appRoot)
+		manager, err := metadata.Find(appRoot)
+		if err != nil {
+			return err
+		}
+
+		c, err := kubecfg.NewEnvListCmd(manager)
 		if err != nil {
 			return err
 		}
@@ -228,6 +243,11 @@ var envSetCmd = &cobra.Command{
 		}
 		appRoot := metadata.AbsPath(appDir)
 
+		manager, err := metadata.Find(appRoot)
+		if err != nil {
+			return err
+		}
+
 		desiredEnvName, err := flags.GetString(flagEnvName)
 		if err != nil {
 			return err
@@ -238,7 +258,7 @@ var envSetCmd = &cobra.Command{
 			return err
 		}
 
-		c, err := kubecfg.NewEnvSetCmd(envName, desiredEnvName, desiredEnvURI, appRoot)
+		c, err := kubecfg.NewEnvSetCmd(envName, desiredEnvName, desiredEnvURI, manager)
 		if err != nil {
 			return err
 		}
diff --git a/cmd/root.go b/cmd/root.go
index 46e8d74d2c76f9956c8268291d49abf26aaf0f14..775c4795c06c0a7897f74586e432c9f01f00d4c3 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -23,6 +23,7 @@ import (
 	"io"
 	"os"
 	"path/filepath"
+	"reflect"
 	"strings"
 
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -226,7 +227,14 @@ func dumpJSON(v interface{}) string {
 	return string(buf.Bytes())
 }
 
-func restClientPool(cmd *cobra.Command) (dynamic.ClientPool, discovery.DiscoveryInterface, error) {
+func restClientPool(cmd *cobra.Command, envName *string) (dynamic.ClientPool, discovery.DiscoveryInterface, error) {
+	if envName != nil {
+		err := overrideCluster(*envName)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
+
 	conf, err := clientConfig.ClientConfig()
 	if err != nil {
 		return nil, nil, err
@@ -245,6 +253,11 @@ func restClientPool(cmd *cobra.Command) (dynamic.ClientPool, discovery.Discovery
 	return pool, discoCache, nil
 }
 
+type envSpec struct {
+	env   *string
+	files []string
+}
+
 // addEnvCmdFlags adds the flags that are common to the family of commands
 // whose form is `[<env>|-f <file-name>]`, e.g., `apply` and `delete`.
 func addEnvCmdFlags(cmd *cobra.Command) {
@@ -253,12 +266,12 @@ func addEnvCmdFlags(cmd *cobra.Command) {
 
 // parseEnvCmd parses the family of commands that come in the form `[<env>|-f
 // <file-name>]`, e.g., `apply` and `delete`.
-func parseEnvCmd(cmd *cobra.Command, args []string) (*string, []string, error) {
+func parseEnvCmd(cmd *cobra.Command, args []string) (*envSpec, error) {
 	flags := cmd.Flags()
 
 	files, err := flags.GetStringArray(flagFile)
 	if err != nil {
-		return nil, nil, err
+		return nil, err
 	}
 
 	var env *string
@@ -266,25 +279,65 @@ func parseEnvCmd(cmd *cobra.Command, args []string) (*string, []string, error) {
 		env = &args[0]
 	}
 
-	return env, files, nil
+	return &envSpec{env: env, files: files}, nil
 }
 
-// expandEnvCmdObjs finds and expands templates for the family of commands of
-// the form `[<env>|-f <file-name>]`, e.g., `apply` and `delete`. That is, if
-// the user passes a list of files, we will expand all templates in those files,
-// while if a user passes an environment name, we will expand all component
-// files using that environment.
-func expandEnvCmdObjs(cmd *cobra.Command, args []string) ([]*unstructured.Unstructured, error) {
-	env, fileNames, err := parseEnvCmd(cmd, args)
+// overrideCluster ensures that the cluster URI specified in the environment is
+// associated in the user's kubeconfig file during deployment to a ksonnet
+// environment. We will error out if it is not.
+//
+// If the environment URI the user is attempting to deploy to is not the current
+// kubeconfig context, we must manually override the client-go --cluster flag
+// to ensure we are deploying to the correct cluster.
+func overrideCluster(envName string) error {
+	cwd, err := os.Getwd()
 	if err != nil {
-		return nil, err
+		return err
 	}
+	wd := metadata.AbsPath(cwd)
 
-	cwd, err := os.Getwd()
+	metadataManager, err := metadata.Find(wd)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
+	rawConfig, err := clientConfig.RawConfig()
+	if err != nil {
+		return err
+	}
+
+	var clusterURIs = make(map[string]string)
+	for name, cluster := range rawConfig.Clusters {
+		clusterURIs[cluster.Server] = name
+	}
+
+	//
+	// check to ensure that the environment we are trying to deploy to is
+	// created, and that the environment URI is located in kubeconfig.
+	//
+
+	log.Debugf("Validating deployment at '%s' with cluster URIs '%v'", envName, reflect.ValueOf(clusterURIs).MapKeys())
+	env, err := metadataManager.GetEnvironment(envName)
+	if err != nil {
+		return err
+	}
+
+	if _, ok := clusterURIs[env.URI]; ok {
+		clusterName := clusterURIs[env.URI]
+		log.Debugf("Overwriting --cluster flag with '%s'", clusterName)
+		overrides.Context.Cluster = clusterName
+		return nil
+	}
+
+	return fmt.Errorf("Attempting to deploy to environment '%s' at %s, but there are no clusters with that URI", envName, env.URI)
+}
+
+// expandEnvCmdObjs finds and expands templates for the family of commands of
+// the form `[<env>|-f <file-name>]`, e.g., `apply` and `delete`. That is, if
+// the user passes a list of files, we will expand all templates in those files,
+// while if a user passes an environment name, we will expand all component
+// files using that environment.
+func expandEnvCmdObjs(cmd *cobra.Command, envSpec *envSpec, cwd metadata.AbsPath) ([]*unstructured.Unstructured, error) {
 	expander, err := newExpander(cmd)
 	if err != nil {
 		return nil, err
@@ -296,23 +349,21 @@ func expandEnvCmdObjs(cmd *cobra.Command, args []string) ([]*unstructured.Unstru
 	// sure that the user either passed an environment name or a `-f` flag.
 	//
 
-	envPresent := env != nil
-	filesPresent := len(fileNames) > 0
+	envPresent := envSpec.env != nil
+	filesPresent := len(envSpec.files) > 0
 
-	// This is equivalent to: `if !xor(envPresent, filesPresent) {`
-	if envPresent && filesPresent {
-		return nil, fmt.Errorf("Either an environment name or a file list is required, but not both")
-	} else if !envPresent && !filesPresent {
-		return nil, fmt.Errorf("Must specify either an environment or a file list")
+	if !envPresent && !filesPresent {
+		return nil, fmt.Errorf("Must specify either an environment or a file list, or both")
 	}
 
-	if envPresent {
-		manager, err := metadata.Find(metadata.AbsPath(cwd))
+	fileNames := envSpec.files
+	if envPresent && !filesPresent {
+		manager, err := metadata.Find(cwd)
 		if err != nil {
 			return nil, err
 		}
 
-		libPath, envLibPath := manager.LibPaths(*env)
+		libPath, envLibPath := manager.LibPaths(*envSpec.env)
 		expander.FlagJpath = append([]string{string(libPath), string(envLibPath)}, expander.FlagJpath...)
 
 		fileNames, err = manager.ComponentPaths()
diff --git a/cmd/show.go b/cmd/show.go
index 9e4ac5c53d173ad4d0760667cfc9dec87f88262c..a01dbd14a142e2410dba40ef8176e4077d1eae61 100644
--- a/cmd/show.go
+++ b/cmd/show.go
@@ -16,8 +16,11 @@
 package cmd
 
 import (
+	"os"
+
 	"github.com/spf13/cobra"
 
+	"github.com/ksonnet/kubecfg/metadata"
 	"github.com/ksonnet/kubecfg/pkg/kubecfg"
 )
 
@@ -45,7 +48,18 @@ var showCmd = &cobra.Command{
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		cwd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		wd := metadata.AbsPath(cwd)
+
+		envSpec, err := parseEnvCmd(cmd, args)
+		if err != nil {
+			return err
+		}
+
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
 		if err != nil {
 			return err
 		}
diff --git a/cmd/update.go b/cmd/update.go
index ffe4514cfa18f640bb4b41611ee6f87c509a3039..f8a8d35ae13f16e02aea1c907edd6b490cf4afe9 100644
--- a/cmd/update.go
+++ b/cmd/update.go
@@ -66,7 +66,13 @@ local configuration. Accepts JSON, YAML, or Jsonnet.`,
 			return err
 		}
 
-		c.ClientPool, c.Discovery, err = restClientPool(cmd)
+		cwd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		wd := metadata.AbsPath(cwd)
+
+		c.ClientPool, c.Discovery, err = restClientPool(cmd, nil)
 		if err != nil {
 			return err
 		}
@@ -76,17 +82,17 @@ local configuration. Accepts JSON, YAML, or Jsonnet.`,
 			return err
 		}
 
-		cwd, err := os.Getwd()
+		envSpec, err := parseEnvCmd(cmd, args)
 		if err != nil {
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
 		if err != nil {
 			return err
 		}
 
-		return c.Run(objs, metadata.AbsPath(cwd))
+		return c.Run(objs, wd)
 	},
 	Long: `NOTE: Command 'update' is deprecated, use 'apply' instead.
 
diff --git a/cmd/validate.go b/cmd/validate.go
index f05f75e95ec3917bd5fbd1d4a48245f6454348ee..5e09884d9e23a869811a9d6f4ea467ce1e5f458d 100644
--- a/cmd/validate.go
+++ b/cmd/validate.go
@@ -16,8 +16,11 @@
 package cmd
 
 import (
+	"os"
+
 	"github.com/spf13/cobra"
 
+	"github.com/ksonnet/kubecfg/metadata"
 	"github.com/ksonnet/kubecfg/pkg/kubecfg"
 )
 
@@ -27,19 +30,30 @@ func init() {
 }
 
 var validateCmd = &cobra.Command{
-	Use:   "validate [<env>|-f <file-or-dir>]",
+	Use:   "validate [env-name] [-f <file-or-dir>]",
 	Short: "Compare generated manifest against server OpenAPI spec",
 	RunE: func(cmd *cobra.Command, args []string) error {
 		var err error
 
 		c := kubecfg.ValidateCmd{}
 
-		_, c.Discovery, err = restClientPool(cmd)
+		cwd, err := os.Getwd()
+		if err != nil {
+			return err
+		}
+		wd := metadata.AbsPath(cwd)
+
+		envSpec, err := parseEnvCmd(cmd, args)
 		if err != nil {
 			return err
 		}
 
-		objs, err := expandEnvCmdObjs(cmd, args)
+		_, c.Discovery, err = restClientPool(cmd, nil)
+		if err != nil {
+			return err
+		}
+
+		objs, err := expandEnvCmdObjs(cmd, envSpec, wd)
 		if err != nil {
 			return err
 		}
@@ -54,11 +68,15 @@ files.`,
 	Example: `  # Validate all resources described in a ksonnet application, expanding
   # ksonnet code with 'dev' environment where necessary (i.e., not YAML, JSON,
   # or non-ksonnet Jsonnet code).
-  ksonnet validate -e=dev
+  ksonnet validate dev
 
   # Validate resources described in a YAML file.
   ksonnet validate -f ./pod.yaml
 
+  # Validate resources described in the JSON file against existing resources
+  # in the cluster the 'dev' environment is pointing at.
+  ksonnet validate dev -f ./pod.yaml
+
   # Validate resources described in a Jsonnet file. Does not expand using
   # environment bindings.
   ksonnet validate -f ./pod.jsonnet`,
diff --git a/metadata/environment.go b/metadata/environment.go
index 797bec47f4bef712f9d1e074fc8a5435ba080d31..8d66ea8e1069a50716c4d78d5910775659eeb103 100644
--- a/metadata/environment.go
+++ b/metadata/environment.go
@@ -173,8 +173,8 @@ func (m *manager) DeleteEnvironment(name string) error {
 	return nil
 }
 
-func (m *manager) GetEnvironments() ([]Environment, error) {
-	envs := []Environment{}
+func (m *manager) GetEnvironments() ([]*Environment, error) {
+	envs := []*Environment{}
 
 	log.Info("Retrieving all environments")
 	err := afero.Walk(m.appFS, string(m.environmentsPath), func(path string, f os.FileInfo, err error) error {
@@ -207,7 +207,7 @@ func (m *manager) GetEnvironments() ([]Environment, error) {
 				}
 
 				log.Debugf("Found environment '%s', with uri '%s", envName, envSpec.URI)
-				envs = append(envs, Environment{Name: envName, Path: path, URI: envSpec.URI})
+				envs = append(envs, &Environment{Name: envName, Path: path, URI: envSpec.URI})
 			}
 		}
 
@@ -221,7 +221,22 @@ func (m *manager) GetEnvironments() ([]Environment, error) {
 	return envs, nil
 }
 
-func (m *manager) SetEnvironment(name string, desired Environment) error {
+func (m *manager) GetEnvironment(name string) (*Environment, error) {
+	envs, err := m.GetEnvironments()
+	if err != nil {
+		return nil, err
+	}
+
+	for _, env := range envs {
+		if env.Name == name {
+			return env, nil
+		}
+	}
+
+	return nil, fmt.Errorf("Environment '%s' does not exist", name)
+}
+
+func (m *manager) SetEnvironment(name string, desired *Environment) error {
 	// Check whether this environment exists
 	envExists, err := m.environmentExists(name)
 	if err != nil {
diff --git a/metadata/environment_test.go b/metadata/environment_test.go
index 3d9c9fd3b25cb39d1e09707d895d240e4df9adfc..b94d9f16c9f1196eb050ce4b00d419034b817ac8 100644
--- a/metadata/environment_test.go
+++ b/metadata/environment_test.go
@@ -137,13 +137,13 @@ func TestSetEnvironment(t *testing.T) {
 	set := Environment{Name: setName, URI: setURI}
 
 	// Test updating an environment that doesn't exist
-	err := m.SetEnvironment("notexists", set)
+	err := m.SetEnvironment("notexists", &set)
 	if err == nil {
 		t.Fatal("Expected error when setting an environment that does not exist")
 	}
 
 	// Test updating an environment to an environment that already exists
-	err = m.SetEnvironment(mockEnvName, Environment{Name: mockEnvName2})
+	err = m.SetEnvironment(mockEnvName, &Environment{Name: mockEnvName2})
 	if err == nil {
 		t.Fatalf("Expected error when setting \"%s\" to \"%s\", because env already exists", mockEnvName, mockEnvName2)
 	}
@@ -151,7 +151,7 @@ func TestSetEnvironment(t *testing.T) {
 	// Test changing the name and URI of a an existing environment.
 	// Ensure new env directory is created, and old directory no longer exists.
 	// Also ensure URI is set in spec.json
-	err = m.SetEnvironment(mockEnvName, set)
+	err = m.SetEnvironment(mockEnvName, &set)
 	if err != nil {
 		t.Fatalf("Could not set \"%s\", got:\n  %s", mockEnvName, err)
 	}
diff --git a/metadata/interface.go b/metadata/interface.go
index 2c45891ea604e1a6e35799ad5b508fc3bae0ccbb..3a1d780b784c944c81e0e1337aa0ffbe705e67c2 100644
--- a/metadata/interface.go
+++ b/metadata/interface.go
@@ -42,8 +42,9 @@ type Manager interface {
 	LibPaths(envName string) (libPath, envLibPath AbsPath)
 	CreateEnvironment(name, uri string, spec ClusterSpec) error
 	DeleteEnvironment(name string) error
-	GetEnvironments() ([]Environment, error)
-	SetEnvironment(name string, desired Environment) error
+	GetEnvironments() ([]*Environment, error)
+	GetEnvironment(name string) (*Environment, error)
+	SetEnvironment(name string, desired *Environment) error
 	//
 	// TODO: Fill in methods as we need them.
 	//
diff --git a/pkg/kubecfg/env.go b/pkg/kubecfg/env.go
index 7c86c2b851521befedd7d6fa13dc4f779b780b15..d78424376127760adf96786d83969e75dba5fcbf 100644
--- a/pkg/kubecfg/env.go
+++ b/pkg/kubecfg/env.go
@@ -30,27 +30,22 @@ type EnvAddCmd struct {
 	name string
 	uri  string
 
-	rootPath metadata.AbsPath
-	spec     metadata.ClusterSpec
+	spec    metadata.ClusterSpec
+	manager metadata.Manager
 }
 
-func NewEnvAddCmd(name, uri, specFlag string, rootPath metadata.AbsPath) (*EnvAddCmd, error) {
+func NewEnvAddCmd(name, uri, specFlag string, manager metadata.Manager) (*EnvAddCmd, error) {
 	spec, err := metadata.ParseClusterSpec(specFlag)
 	if err != nil {
 		return nil, err
 	}
 	log.Debugf("Generating ksonnetLib data with spec: %s", specFlag)
 
-	return &EnvAddCmd{name: name, uri: uri, spec: spec, rootPath: rootPath}, nil
+	return &EnvAddCmd{name: name, uri: uri, spec: spec, manager: manager}, nil
 }
 
 func (c *EnvAddCmd) Run() error {
-	manager, err := metadata.Find(c.rootPath)
-	if err != nil {
-		return err
-	}
-
-	return manager.CreateEnvironment(c.name, c.uri, c.spec)
+	return c.manager.CreateEnvironment(c.name, c.uri, c.spec)
 }
 
 // ==================================================================
@@ -58,39 +53,29 @@ func (c *EnvAddCmd) Run() error {
 type EnvRmCmd struct {
 	name string
 
-	rootPath metadata.AbsPath
+	manager metadata.Manager
 }
 
-func NewEnvRmCmd(name string, rootPath metadata.AbsPath) (*EnvRmCmd, error) {
-	return &EnvRmCmd{name: name, rootPath: rootPath}, nil
+func NewEnvRmCmd(name string, manager metadata.Manager) (*EnvRmCmd, error) {
+	return &EnvRmCmd{name: name, manager: manager}, nil
 }
 
 func (c *EnvRmCmd) Run() error {
-	manager, err := metadata.Find(c.rootPath)
-	if err != nil {
-		return err
-	}
-
-	return manager.DeleteEnvironment(c.name)
+	return c.manager.DeleteEnvironment(c.name)
 }
 
 // ==================================================================
 
 type EnvListCmd struct {
-	rootPath metadata.AbsPath
+	manager metadata.Manager
 }
 
-func NewEnvListCmd(rootPath metadata.AbsPath) (*EnvListCmd, error) {
-	return &EnvListCmd{rootPath: rootPath}, nil
+func NewEnvListCmd(manager metadata.Manager) (*EnvListCmd, error) {
+	return &EnvListCmd{manager: manager}, nil
 }
 
 func (c *EnvListCmd) Run(out io.Writer) error {
-	manager, err := metadata.Find(c.rootPath)
-	if err != nil {
-		return err
-	}
-
-	envs, err := manager.GetEnvironments()
+	envs, err := c.manager.GetEnvironments()
 	if err != nil {
 		return err
 	}
@@ -133,19 +118,14 @@ type EnvSetCmd struct {
 	desiredName string
 	desiredURI  string
 
-	rootPath metadata.AbsPath
+	manager metadata.Manager
 }
 
-func NewEnvSetCmd(name, desiredName, desiredURI string, rootPath metadata.AbsPath) (*EnvSetCmd, error) {
-	return &EnvSetCmd{name: name, desiredName: desiredName, desiredURI: desiredURI, rootPath: rootPath}, nil
+func NewEnvSetCmd(name, desiredName, desiredURI string, manager metadata.Manager) (*EnvSetCmd, error) {
+	return &EnvSetCmd{name: name, desiredName: desiredName, desiredURI: desiredURI, manager: manager}, nil
 }
 
 func (c *EnvSetCmd) Run() error {
-	manager, err := metadata.Find(c.rootPath)
-	if err != nil {
-		return err
-	}
-
 	desired := metadata.Environment{Name: c.desiredName, URI: c.desiredURI}
-	return manager.SetEnvironment(c.name, desired)
+	return c.manager.SetEnvironment(c.name, &desired)
 }