Commit 3a21334d authored by bryanl's avatar bryanl
Browse files

bug: fix updating env namespace


Signed-off-by: default avatarbryanl <bryanliles@gmail.com>
parent 79b140ea
// Copyright 2018 The ksonnet 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 actions
import (
"github.com/ksonnet/ksonnet/env"
"github.com/ksonnet/ksonnet/metadata/app"
)
// EnvSetNamespace is an option for setting a new namespace name.
func EnvSetNamespace(nsName string) EnvSetOpt {
return func(es *EnvSet) {
es.newNsName = nsName
}
}
// EnvSetName is an option for setting a new name.
func EnvSetName(name string) EnvSetOpt {
return func(es *EnvSet) {
es.newName = name
}
}
// EnvSetOpt is an option for configuring EnvSet.
type EnvSetOpt func(*EnvSet)
// RunEnvSet runs `env set`
func RunEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) error {
et, err := NewEnvSet(ksApp, envName, opts...)
if err != nil {
return err
}
return et.Run()
}
// EnvSet sets targets for an environment.
type EnvSet struct {
app app.App
em env.Manager
envName string
newName string
newNsName string
}
// NewEnvSet creates an instance of EnvSet.
func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error) {
es := &EnvSet{
app: ksApp,
em: env.DefaultManager,
envName: envName,
}
for _, opt := range opts {
opt(es)
}
return es, nil
}
// Run assigns targets to an environment.
func (es *EnvSet) Run() error {
if err := es.updateName(); err != nil {
return err
}
return es.updateNamespace()
}
func (es *EnvSet) updateName() error {
if es.newName != "" {
config := env.RenameConfig{
App: es.app,
}
if err := es.em.Rename(es.envName, es.newName, config); err != nil {
return err
}
es.envName = es.newName
}
return nil
}
func (es *EnvSet) updateNamespace() error {
if es.newNsName != "" {
spec, err := es.app.Environment(es.envName)
if err != nil {
return err
}
spec.Destination.Namespace = es.newNsName
return es.app.AddEnvironment(es.envName, "", spec)
}
return nil
}
// Copyright 2018 The ksonnet 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 actions
import (
"testing"
"github.com/ksonnet/ksonnet/env"
emocks "github.com/ksonnet/ksonnet/env/mocks"
"github.com/ksonnet/ksonnet/metadata/app"
amocks "github.com/ksonnet/ksonnet/metadata/app/mocks"
"github.com/stretchr/testify/require"
)
func TestEnvSet_name(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "default"
newName := "dev"
nameOpt := EnvSetName(newName)
a, err := NewEnvSet(appMock, envName, nameOpt)
require.NoError(t, err)
em := &emocks.Manager{}
config := env.RenameConfig{
App: appMock,
}
em.On("Rename", envName, newName, config).Return(nil)
a.em = em
err = a.Run()
require.NoError(t, err)
})
}
func TestEnvSet_namespace(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "default"
nsName := "ns2"
nsOpt := EnvSetNamespace(nsName)
a, err := NewEnvSet(appMock, envName, nsOpt)
require.NoError(t, err)
spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: "default",
},
}
updatedSpec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: nsName,
},
}
appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", envName, "", updatedSpec).Return(nil)
err = a.Run()
require.NoError(t, err)
})
}
func TestEnvSet_name_and_namespace(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "default"
newName := "dev"
nsName := "ns2"
nameOpt := EnvSetName(newName)
nsOpt := EnvSetNamespace(nsName)
a, err := NewEnvSet(appMock, envName, nsOpt, nameOpt)
require.NoError(t, err)
spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: "default",
},
}
updatedSpec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: nsName,
},
}
appMock.On("Environment", newName).Return(spec, nil)
appMock.On("AddEnvironment", newName, "", updatedSpec).Return(nil)
em := &emocks.Manager{}
config := env.RenameConfig{
App: appMock,
}
em.On("Rename", envName, newName, config).Return(nil)
a.em = em
err = a.Run()
require.NoError(t, err)
})
}
......@@ -54,14 +54,11 @@ func init() {
envCmd.AddCommand(envAddCmd)
envCmd.AddCommand(envRmCmd)
envCmd.AddCommand(envListCmd)
envCmd.AddCommand(envSetCmd)
// TODO: We need to make this default to checking the `kubeconfig` file.
envAddCmd.PersistentFlags().String(flagAPISpec, "version:v1.7.0",
"Manually specify API version from OpenAPI schema, cluster, or Kubernetes version")
envSetCmd.PersistentFlags().String(flagEnvName, "",
"Name used to uniquely identify the environment. Must not already exist within the ksonnet app")
}
var envCmd = &cobra.Command{
......@@ -277,57 +274,6 @@ current ksonnet app. Specifically, this will display the (1) *name*,
`,
}
var envSetCmd = &cobra.Command{
Use: "set <env-name>",
Short: envShortDesc["set"],
RunE: func(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()
if len(args) != 1 {
return fmt.Errorf("'env set' takes a single argument, that is the name of the environment")
}
originalName := args[0]
appDir, err := os.Getwd()
if err != nil {
return err
}
manager, err := metadata.Find(appDir)
if err != nil {
return err
}
name, err := flags.GetString(flagEnvName)
if err != nil {
return err
}
c, err := kubecfg.NewEnvSetCmd(originalName, name, manager)
if err != nil {
return err
}
return c.Run()
},
Long: `
The ` + "`set`" + ` command lets you change the fields of an existing environment.
You can currently only update your environment's name.
Note that changing the name of an environment will also update the corresponding
directory structure in ` + "`environments/`" + `.
### Related Commands
* ` + "`ks env list` " + `— ` + envShortDesc["list"] + `
### Syntax
`,
Example: `#Update the name of the environment 'us-west/staging'.
# Updating the name will update the directory structure in 'environments/'.
ks env set us-west/staging --name=us-east/staging`,
}
func commonEnvFlags(flags *pflag.FlagSet) (server, namespace, context string, err error) {
server, err = flags.GetString(flagEnvServer)
if err != nil {
......
// Copyright 2018 The ksonnet 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 (
"fmt"
"github.com/ksonnet/ksonnet/actions"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
vEnvSetName = "env-set-name"
vEnvSetNamespace = "env-set-namespace"
)
var envSetCmd = &cobra.Command{
Use: "set <env-name>",
Short: envShortDesc["set"],
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("'env set' takes a single argument, that is the name of the environment")
}
envName := args[0]
newName := viper.GetString(vEnvSetName)
nameOpt := actions.EnvSetName(newName)
newNsName := viper.GetString(vEnvSetNamespace)
nsOpt := actions.EnvSetNamespace(newNsName)
return actions.RunEnvSet(ka, envName, nameOpt, nsOpt)
},
Long: `
The ` + "`set`" + ` command lets you change the fields of an existing environment.
You can currently only update your environment's name.
Note that changing the name of an environment will also update the corresponding
directory structure in ` + "`environments/`" + `.
### Related Commands
* ` + "`ks env list` " + `— ` + envShortDesc["list"] + `
### Syntax
`,
Example: `#Update the name of the environment 'us-west/staging'.
# Updating the name will update the directory structure in 'environments/'.
ks env set us-west/staging --name=us-east/staging`,
}
func init() {
envCmd.AddCommand(envSetCmd)
envSetCmd.Flags().String(flagEnvName, "",
"Name used to uniquely identify the environment. Must not already exist within the ksonnet app")
viper.BindPFlag(vEnvSetName, envSetCmd.Flags().Lookup(flagName))
envSetCmd.Flags().String(flagNamespace, "",
"Namespace for environment.")
viper.BindPFlag(vEnvSetNamespace, envSetCmd.Flags().Lookup(flagNamespace))
}
......@@ -81,6 +81,16 @@ var _ = Describe("ks env", func() {
assertOutput("env/set/rename.txt", o.stdout)
})
})
Context("updating namespace", func() {
It("updates the namespace for an environment", func() {
o := a.runKs("env", "set", "default", "--namespace", "dev")
assertExitStatus(o, 0)
o = a.envDescribe("default")
assertOutput("env/set/rename-namespace.txt", o.stdout)
})
})
})
Describe("targets", func() {
......
name: default
kubernetesversion: v1.7.0
path: default
destination:
server: http://example.com
namespace: dev
targets: []
// Copyright 2018 The ksonnet 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 env
var (
// DefaultManager is the default manager for env.
DefaultManager = &defaultManager{}
)
// Manager is a manager for interfacing with env operations.
type Manager interface {
Rename(from, to string, config RenameConfig) error
}
type defaultManager struct{}
var _ Manager = (*defaultManager)(nil)
func (dm *defaultManager) Rename(from, to string, config RenameConfig) error {
return Rename(from, to, config)
}
// Copyright 2018 The ksonnet 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.
// Code generated by mockery v1.0.0
package mocks
import env "github.com/ksonnet/ksonnet/env"
import mock "github.com/stretchr/testify/mock"
// Manager is an autogenerated mock type for the Manager type
type Manager struct {
mock.Mock
}
// Rename provides a mock function with given fields: from, to, config
func (_m *Manager) Rename(from string, to string, config env.RenameConfig) error {
ret := _m.Called(from, to, config)
var r0 error
if rf, ok := ret.Get(0).(func(string, string, env.RenameConfig) error); ok {
r0 = rf(from, to, config)
} else {
r0 = ret.Error(0)
}
return r0
}
......@@ -51,18 +51,3 @@ func NewEnvRmCmd(name string, manager metadata.Manager) (*EnvRmCmd, error) {
func (c *EnvRmCmd) Run() error {
return c.manager.DeleteEnvironment(c.name)
}
type EnvSetCmd struct {
name string
desiredName string
manager metadata.Manager
}
func NewEnvSetCmd(name, desiredName string, manager metadata.Manager) (*EnvSetCmd, error) {
return &EnvSetCmd{name: name, desiredName: desiredName, manager: manager}, nil
}
func (c *EnvSetCmd) Run() error {
return c.manager.SetEnvironment(c.name, c.desiredName)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment