Unverified Commit ced90f35 authored by Derek Wilson's avatar Derek Wilson Committed by GitHub
Browse files

add option to env set for k8s version (#618)



enables --api-spec flag to `ks env set` command to enable changing the
kubernetes version for an environment
Signed-off-by: default avatarDerek Wilson <derek@heptio.com>
parent db8f92e4
......@@ -48,16 +48,21 @@ func RunEnvSet(m map[string]interface{}) error {
return et.Run()
}
// func types for renaming and updating environments
type envRenameFn func(a app.App, from, to string, override bool) error
type updateEnvFn func(a app.App, envName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error
// EnvSet sets targets for an environment.
type EnvSet struct {
app app.App
envName string
newName string
newNsName string
newServer string
envRenameFn func(a app.App, from, to string, override bool) error
updateEnvFn func(a app.App, envName string, spec *app.EnvironmentSpec, override bool) error
app app.App
envName string
newName string
newNsName string
newServer string
newAPISpec string
envRenameFn envRenameFn
updateEnvFn updateEnvFn
}
// NewEnvSet creates an instance of EnvSet.
......@@ -65,11 +70,12 @@ func NewEnvSet(m map[string]interface{}) (*EnvSet, error) {
ol := newOptionLoader(m)
es := &EnvSet{
app: ol.LoadApp(),
envName: ol.LoadString(OptionEnvName),
newName: ol.LoadOptionalString(OptionNewEnvName),
newNsName: ol.LoadOptionalString(OptionNamespace),
newServer: ol.LoadOptionalString(OptionServer),
app: ol.LoadApp(),
envName: ol.LoadString(OptionEnvName),
newName: ol.LoadOptionalString(OptionNewEnvName),
newNsName: ol.LoadOptionalString(OptionNamespace),
newServer: ol.LoadOptionalString(OptionServer),
newAPISpec: ol.LoadOptionalString(OptionSpecFlag),
envRenameFn: env.Rename,
updateEnvFn: updateEnv,
......@@ -113,7 +119,7 @@ func (es *EnvSet) updateName(isOverride bool) error {
}
func (es *EnvSet) updateEnvSpec(env *app.EnvironmentSpec) error {
if es.newNsName == "" && es.newServer == "" {
if es.newNsName == "" && es.newServer == "" && es.newAPISpec == "" {
return nil
}
......@@ -125,9 +131,9 @@ func (es *EnvSet) updateEnvSpec(env *app.EnvironmentSpec) error {
env.Destination.Server = es.newServer
}
return updateEnv(es.app, es.envName, env, env.IsOverride())
return es.updateEnvFn(es.app, es.envName, es.newAPISpec, env, env.IsOverride())
}
func updateEnv(a app.App, envName string, spec *app.EnvironmentSpec, override bool) error {
return a.AddEnvironment(envName, "", spec, override)
func updateEnv(a app.App, envName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error {
return a.AddEnvironment(envName, k8sAPISpec, spec, override)
}
......@@ -24,153 +24,155 @@ import (
"github.com/stretchr/testify/require"
)
func TestEnvSet_name(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "old_env_name"
newName := "new_env_name"
in := map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNewEnvName: newName,
}
a, err := NewEnvSet(in)
require.NoError(t, err)
a.envRenameFn = func(a app.App, from, to string, override bool) error {
assert.Equal(t, envName, from)
assert.Equal(t, newName, to)
assert.False(t, override)
return nil
}
spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{},
}
appMock.On("Environment", envName).Return(spec, nil)
err = a.Run()
require.NoError(t, err)
})
}
func TestEnvSet_namespace(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "env_name"
oldNamespace := "old_namespace"
namespace := "new_name_sapce"
in := map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNamespace: namespace,
}
a, err := NewEnvSet(in)
require.NoError(t, err)
spec := &app.EnvironmentSpec{
func TestEnvSet(t *testing.T) {
envName := "old_env_name"
newName := "new_env_name"
oldNamespace := "old_namespace"
namespace := "new_namesapce"
oldServer := "old_server"
server := "new_server"
newk8sAPISpec := "version:new_api_spec"
environmentMockFn := func(name string) *app.EnvironmentSpec {
return &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: oldNamespace,
Server: oldServer,
},
}
}
updatedSpec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: namespace,
},
}
appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", envName, "", updatedSpec, false).Return(nil)
err = a.Run()
require.NoError(t, err)
})
}
func TestEnvSet_server(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "env_name"
oldServer := "old_server"
server := "new_server"
in := map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionServer: server,
}
a, err := NewEnvSet(in)
require.NoError(t, err)
spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Server: oldServer,
cases := []struct {
name string
in map[string]interface{}
spec *app.EnvironmentSpec
envRenameFn func(t *testing.T) envRenameFn
updateEnvFn func(t *testing.T) updateEnvFn
}{
{
name: "rename environment",
in: map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNewEnvName: newName,
},
envRenameFn: func(t *testing.T) envRenameFn {
return func(a app.App, from, to string, override bool) error {
assert.Equal(t, envName, from)
assert.Equal(t, newName, to)
assert.False(t, override)
return nil
}
},
},
}
updatedSpec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Server: server,
{
name: "set new namespace",
in: map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNamespace: namespace,
},
updateEnvFn: func(t *testing.T) updateEnvFn {
return func(a app.App, envName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error {
assert.Equal(t, spec, &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: namespace,
Server: oldServer,
},
})
return nil
}
},
},
{
name: "set new server",
in: map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionServer: server,
},
updateEnvFn: func(t *testing.T) updateEnvFn {
return func(a app.App, envName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error {
assert.Equal(t, spec, &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: oldNamespace,
Server: server,
},
})
return nil
}
},
},
{
name: "set new api spec",
in: map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionSpecFlag: newk8sAPISpec,
},
updateEnvFn: func(t *testing.T) updateEnvFn {
return func(a app.App, envName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error {
assert.Equal(t, newk8sAPISpec, k8sAPISpec)
return nil
}
},
},
{
name: "set everything at once",
in: map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNewEnvName: newName,
OptionNamespace: namespace,
OptionServer: server,
OptionSpecFlag: newk8sAPISpec,
},
updateEnvFn: func(t *testing.T) updateEnvFn {
return func(a app.App, newName, k8sAPISpec string, spec *app.EnvironmentSpec, override bool) error {
assert.Equal(t, spec, &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: namespace,
Server: server,
},
})
assert.Equal(t, newk8sAPISpec, k8sAPISpec)
return nil
}
},
envRenameFn: func(t *testing.T) envRenameFn {
return func(a app.App, from, to string, override bool) error {
assert.Equal(t, envName, from)
assert.Equal(t, newName, to)
assert.False(t, override)
return nil
}
},
},
}
appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", envName, "", updatedSpec, false).Return(nil)
err = a.Run()
require.NoError(t, err)
})
}
func TestEnvSet_all(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
envName := "old_env_name"
newName := "new_env_name"
oldNamespace := "old_namespace"
namespace := "new_name_sapce"
oldServer := "old_server"
server := "new_server"
in := map[string]interface{}{
OptionApp: appMock,
OptionEnvName: envName,
OptionNewEnvName: newName,
OptionNamespace: namespace,
OptionServer: server,
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
a, err := NewEnvSet(tc.in)
require.NoError(t, err)
a, err := NewEnvSet(in)
require.NoError(t, err)
if tc.envRenameFn != nil {
a.envRenameFn = tc.envRenameFn(t)
}
a.envRenameFn = func(a app.App, from, to string, override bool) error {
assert.Equal(t, envName, from)
assert.Equal(t, newName, to)
assert.False(t, override)
if tc.updateEnvFn != nil {
a.updateEnvFn = tc.updateEnvFn(t)
}
return nil
}
appMock.On("Environment", tc.in[OptionEnvName]).Return(environmentMockFn, nil)
spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: oldNamespace,
Server: oldServer,
},
}
err = a.Run()
require.NoError(t, err)
updatedSpec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: namespace,
Server: server,
},
})
}
appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", newName, "", updatedSpec, false).Return(nil)
err = a.Run()
require.NoError(t, err)
})
}
......
......@@ -28,6 +28,7 @@ const (
vEnvSetName = "env-set-name"
vEnvSetNamespace = "env-set-namespace"
vEnvSetServer = "env-set-server"
vEnvSetAPISpec = "env-set-spec-flag"
)
var (
......@@ -66,6 +67,7 @@ func newEnvSetCmd(a app.App) *cobra.Command {
actions.OptionNewEnvName: viper.GetString(vEnvSetName),
actions.OptionNamespace: viper.GetString(vEnvSetNamespace),
actions.OptionServer: viper.GetString(vEnvSetServer),
actions.OptionSpecFlag: viper.GetString(vEnvSetAPISpec),
}
return runAction(actionEnvSet, m)
......@@ -84,5 +86,8 @@ func newEnvSetCmd(a app.App) *cobra.Command {
"Cluster server for environment")
viper.BindPFlag(vEnvSetServer, envSetCmd.Flags().Lookup(flagServer))
envSetCmd.Flags().String(flagAPISpec, "",
"Kubernetes version for environment")
viper.BindPFlag(vEnvSetAPISpec, envSetCmd.Flags().Lookup(flagAPISpec))
return envSetCmd
}
......@@ -25,7 +25,7 @@ func Test_envSetCmd(t *testing.T) {
cases := []cmdTestCase{
{
name: "in general",
args: []string{"env", "set", "default", "--name", "new-name", "--namespace", "new-namespace", "--server", "new-server"},
args: []string{"env", "set", "default", "--name", "new-name", "--namespace", "new-namespace", "--server", "new-server", "--api-spec", "new-api-spec"},
action: actionEnvSet,
expected: map[string]interface{}{
actions.OptionApp: nil,
......@@ -33,6 +33,7 @@ func Test_envSetCmd(t *testing.T) {
actions.OptionNewEnvName: "new-name",
actions.OptionNamespace: "new-namespace",
actions.OptionServer: "new-server",
actions.OptionSpecFlag: "new-api-spec",
},
},
{
......
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