Unverified Commit 81968f61 authored by bryanl's avatar bryanl
Browse files

override environments


Signed-off-by: default avatarbryanl <bryanliles@gmail.com>
parent 428c62dc
// 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"
)
const (
baseLibsonnetFile = "base.libsonnet"
componentsDir = "components"
paramsFileName = "params.libsonnet"
)
// RunEnvAdd runs `env add`
func RunEnvAdd(ksApp app.App, envName, server, namespace, k8sSpecFlag string, isOverride bool) error {
ea, err := NewEnvAdd(ksApp, envName, server, namespace, k8sSpecFlag, isOverride)
if err != nil {
return err
}
return ea.Run()
}
// EnvAdd sets targets for an environment.
type EnvAdd struct {
app app.App
envName string
server string
namespace string
k8sSpecFlag string
isOverride bool
envCreateFn func(a app.App, d env.Destination, name, k8sSpecFlag string, overrideData, paramsData []byte, isOverride bool) error
}
// NewEnvAdd creates an instance of EnvAdd.
func NewEnvAdd(ksApp app.App, envName, server, namespace, k8sSpecFlag string, isOverride bool) (*EnvAdd, error) {
ea := &EnvAdd{
app: ksApp,
envName: envName,
server: server,
namespace: namespace,
k8sSpecFlag: k8sSpecFlag,
isOverride: isOverride,
envCreateFn: env.Create,
}
return ea, nil
}
// Run assigns targets to an environment.
func (ea *EnvAdd) Run() error {
destination := env.NewDestination(ea.server, ea.namespace)
return ea.envCreateFn(
ea.app,
destination,
ea.envName,
ea.k8sSpecFlag,
env.DefaultOverrideData(),
env.DefaultParamsData(),
ea.isOverride,
)
}
// 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"
"github.com/ksonnet/ksonnet/metadata/app"
amocks "github.com/ksonnet/ksonnet/metadata/app/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEnvAdd(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
aName := "my-app"
aServer := "http://example.com"
aNamespace := "default"
aK8sSpecFlag := "flag"
aIsOverride := false
a, err := NewEnvAdd(appMock, aName, aServer, aNamespace, aK8sSpecFlag, aIsOverride)
require.NoError(t, err)
a.envCreateFn = func(a app.App, d env.Destination, name, specFlag string, od, pd []byte, override bool) error {
expectedDest := env.NewDestination(aServer, aNamespace)
assert.Equal(t, expectedDest, d)
assert.Equal(t, appMock, a)
assert.Equal(t, aName, name)
assert.Equal(t, aK8sSpecFlag, specFlag)
assert.Equal(t, aIsOverride, override)
return nil
}
err = a.Run()
require.NoError(t, err)
})
}
...@@ -58,13 +58,19 @@ func (nl *EnvList) Run() error { ...@@ -58,13 +58,19 @@ func (nl *EnvList) Run() error {
} }
table := table.New(nl.out) table := table.New(nl.out)
table.SetHeader([]string{"name", "kubernetes-version", "namespace", "server"}) table.SetHeader([]string{"name", "override", "kubernetes-version", "namespace", "server"})
var rows [][]string var rows [][]string
for name, env := range environments { for name, env := range environments {
override := ""
if env.IsOverride() {
override = "*"
}
rows = append(rows, []string{ rows = append(rows, []string{
name, name,
override,
env.KubernetesVersion, env.KubernetesVersion,
env.Destination.Namespace, env.Destination.Namespace,
env.Destination.Server, env.Destination.Server,
......
// Copyright 2017 The kubecfg authors // Copyright 2018 The ksonnet authors
// //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
...@@ -13,41 +13,52 @@ ...@@ -13,41 +13,52 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package kubecfg package actions
import ( import (
"github.com/ksonnet/ksonnet/metadata" "github.com/ksonnet/ksonnet/env"
"github.com/ksonnet/ksonnet/metadata/app"
) )
type EnvAddCmd struct { // RunEnvRm runs `env rm`
name string func RunEnvRm(ksApp app.App, envName string, isOverride bool) error {
server string ea, err := NewEnvRm(ksApp, envName, isOverride)
namespace string if err != nil {
spec string return err
}
manager metadata.Manager return ea.Run()
} }
func NewEnvAddCmd(name, server, namespace, specFlag string, manager metadata.Manager) (*EnvAddCmd, error) { type envDeleteFn func(a app.App, name string, override bool) error
return &EnvAddCmd{name: name, server: server, namespace: namespace, spec: specFlag, manager: manager}, nil
}
func (c *EnvAddCmd) Run() error { // EnvRm sets targets for an environment.
return c.manager.CreateEnvironment(c.name, c.server, c.namespace, c.spec) type EnvRm struct {
} app app.App
envName string
isOverride bool
// ================================================================== envDeleteFn envDeleteFn
}
type EnvRmCmd struct { // NewEnvRm creates an instance of EnvRm.
name string func NewEnvRm(ksApp app.App, envName string, isOverride bool) (*EnvRm, error) {
ea := &EnvRm{
app: ksApp,
envName: envName,
isOverride: isOverride,
manager metadata.Manager envDeleteFn: env.Delete,
} }
func NewEnvRmCmd(name string, manager metadata.Manager) (*EnvRmCmd, error) { return ea, nil
return &EnvRmCmd{name: name, manager: manager}, nil
} }
func (c *EnvRmCmd) Run() error { // Run assigns targets to an environment.
return c.manager.DeleteEnvironment(c.name) func (er *EnvRm) Run() error {
return er.envDeleteFn(
er.app,
er.envName,
er.isOverride,
)
} }
...@@ -13,27 +13,34 @@ ...@@ -13,27 +13,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Code generated by mockery v1.0.0 package actions
package mocks
import env "github.com/ksonnet/ksonnet/env" import (
import mock "github.com/stretchr/testify/mock" "testing"
// Manager is an autogenerated mock type for the Manager type "github.com/ksonnet/ksonnet/metadata/app"
type Manager struct { amocks "github.com/ksonnet/ksonnet/metadata/app/mocks"
mock.Mock "github.com/stretchr/testify/assert"
} "github.com/stretchr/testify/require"
)
func TestEnvRm(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
aName := "my-app"
aIsOverride := false
a, err := NewEnvRm(appMock, aName, aIsOverride)
require.NoError(t, err)
// Rename provides a mock function with given fields: from, to, config a.envDeleteFn = func(a app.App, name string, override bool) error {
func (_m *Manager) Rename(from string, to string, config env.RenameConfig) error { assert.Equal(t, appMock, a)
ret := _m.Called(from, to, config) assert.Equal(t, aName, name)
assert.Equal(t, aIsOverride, override)
var r0 error return nil
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 err = a.Run()
require.NoError(t, err)
})
} }
...@@ -50,18 +50,21 @@ func RunEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) error { ...@@ -50,18 +50,21 @@ func RunEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) error {
// EnvSet sets targets for an environment. // EnvSet sets targets for an environment.
type EnvSet struct { type EnvSet struct {
app app.App app app.App
em env.Manager
envName string envName string
newName string newName string
newNsName string newNsName string
envRename func(a app.App, from, to string, override bool) error
updateEnv func(a app.App, envName string, spec *app.EnvironmentSpec, override bool) error
} }
// NewEnvSet creates an instance of EnvSet. // NewEnvSet creates an instance of EnvSet.
func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error) { func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error) {
es := &EnvSet{ es := &EnvSet{
app: ksApp, app: ksApp,
em: env.DefaultManager, envRename: env.Rename,
envName: envName, updateEnv: updateEnv,
envName: envName,
} }
for _, opt := range opts { for _, opt := range opts {
...@@ -73,19 +76,21 @@ func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error ...@@ -73,19 +76,21 @@ func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error
// Run assigns targets to an environment. // Run assigns targets to an environment.
func (es *EnvSet) Run() error { func (es *EnvSet) Run() error {
if err := es.updateName(); err != nil { env, err := es.app.Environment(es.envName)
if err != nil {
return err
}
if err := es.updateName(env.IsOverride()); err != nil {
return err return err
} }
return es.updateNamespace() return es.updateNamespace(env)
} }
func (es *EnvSet) updateName() error { func (es *EnvSet) updateName(isOverride bool) error {
if es.newName != "" { if es.newName != "" {
config := env.RenameConfig{ if err := es.envRename(es.app, es.envName, es.newName, isOverride); err != nil {
App: es.app,
}
if err := es.em.Rename(es.envName, es.newName, config); err != nil {
return err return err
} }
...@@ -95,16 +100,15 @@ func (es *EnvSet) updateName() error { ...@@ -95,16 +100,15 @@ func (es *EnvSet) updateName() error {
return nil return nil
} }
func (es *EnvSet) updateNamespace() error { func (es *EnvSet) updateNamespace(env *app.EnvironmentSpec) error {
if es.newNsName != "" { if es.newNsName != "" {
spec, err := es.app.Environment(es.envName) env.Destination.Namespace = es.newNsName
if err != nil { return updateEnv(es.app, es.envName, env, env.IsOverride())
return err
}
spec.Destination.Namespace = es.newNsName
return es.app.AddEnvironment(es.envName, "", spec)
} }
return nil return nil
} }
func updateEnv(a app.App, envName string, spec *app.EnvironmentSpec, override bool) error {
return a.AddEnvironment(envName, "", spec, override)
}
...@@ -18,10 +18,9 @@ package actions ...@@ -18,10 +18,9 @@ package actions
import ( import (
"testing" "testing"
"github.com/ksonnet/ksonnet/env"
emocks "github.com/ksonnet/ksonnet/env/mocks"
"github.com/ksonnet/ksonnet/metadata/app" "github.com/ksonnet/ksonnet/metadata/app"
amocks "github.com/ksonnet/ksonnet/metadata/app/mocks" amocks "github.com/ksonnet/ksonnet/metadata/app/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -35,14 +34,21 @@ func TestEnvSet_name(t *testing.T) { ...@@ -35,14 +34,21 @@ func TestEnvSet_name(t *testing.T) {
a, err := NewEnvSet(appMock, envName, nameOpt) a, err := NewEnvSet(appMock, envName, nameOpt)
require.NoError(t, err) require.NoError(t, err)
em := &emocks.Manager{} a.envRename = func(a app.App, from, to string, override bool) error {
assert.Equal(t, envName, from)
assert.Equal(t, newName, to)
assert.False(t, override)
config := env.RenameConfig{ return nil
App: appMock,
} }
em.On("Rename", envName, newName, config).Return(nil)
a.em = em spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{
Namespace: "default",
},
}
appMock.On("Environment", envName).Return(spec, nil)
err = a.Run() err = a.Run()
require.NoError(t, err) require.NoError(t, err)
...@@ -72,8 +78,7 @@ func TestEnvSet_namespace(t *testing.T) { ...@@ -72,8 +78,7 @@ func TestEnvSet_namespace(t *testing.T) {
} }
appMock.On("Environment", envName).Return(spec, nil) appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", envName, "", updatedSpec, false).Return(nil)
appMock.On("AddEnvironment", envName, "", updatedSpec).Return(nil)
err = a.Run() err = a.Run()
require.NoError(t, err) require.NoError(t, err)
...@@ -92,6 +97,22 @@ func TestEnvSet_name_and_namespace(t *testing.T) { ...@@ -92,6 +97,22 @@ func TestEnvSet_name_and_namespace(t *testing.T) {
a, err := NewEnvSet(appMock, envName, nsOpt, nameOpt) a, err := NewEnvSet(appMock, envName, nsOpt, nameOpt)
require.NoError(t, err) require.NoError(t, err)
a.envRename = 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
}
a.updateEnv = func(a app.App, name string, spec *app.EnvironmentSpec, override bool) error {
assert.Equal(t, envName, name)
assert.Equal(t, nsName, spec.Destination.Namespace)
assert.False(t, override)
return nil
}
spec := &app.EnvironmentSpec{ spec := &app.EnvironmentSpec{
Destination: &app.EnvironmentDestinationSpec{ Destination: &app.EnvironmentDestinationSpec{
Namespace: "default", Namespace: "default",
...@@ -104,17 +125,8 @@ func TestEnvSet_name_and_namespace(t *testing.T) { ...@@ -104,17 +125,8 @@ func TestEnvSet_name_and_namespace(t *testing.T) {
}, },
} }
appMock.On("Environment", newName).Return(spec, nil) appMock.On("Environment", "default").Return(spec, nil)
appMock.On("AddEnvironment", newName, "", updatedSpec).Return(nil) appMock.On("AddEnvironment", newName, "", updatedSpec, false).Return(nil)
em := &emocks.Manager{}
config := env.RenameConfig{
App: appMock,
}
em.On("Rename", envName, newName, config).Return(nil)
a.em = em
err = a.Run() err = a.Run()
require.NoError(t, err) require.NoError(t, err)
......
// 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/metadata/app"
"github.com/ksonnet/ksonnet/pkg/appinit"
"github.com/ksonnet/ksonnet/pkg/registry"
"github.com/spf13/afero"
)
const (
defaultIncubatorRegName = "incubator"
defaultIncubatorURI = "github.com/ksonnet/parts/tree/master/" + defaultIncubatorRegName
)
// RunInit creates a namespace.
func RunInit(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string) error {
i, err := NewInit(fs, name, rootPath, k8sSpecFlag, serverURI, namespace)
if err != nil {
return err
}
return i.Run()
}
type appInitFn func(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string, registries []registry.Registry) error
// Init creates a component namespace
type Init struct {
fs afero.Fs
name string
rootPath string
k8sSpecFlag string
serverURI string
namespace string
appInitFn appInitFn
}
// NewInit creates an instance of Init.
func NewInit(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string) (*Init, error) {
i := &Init{
fs: fs,
name: name,
rootPath: rootPath,
k8sSpecFlag: k8sSpecFlag,
serverURI: serverURI,
namespace: namespace,
appInitFn: appinit.Init,
}
return i, nil
}
// Run runs that ns create action.
func (i *Init) Run() error {
gh, err := registry.NewGitHub(&app.RegistryRefSpec{
Name: "incubator",
Protocol: registry.ProtocolGitHub,
URI: defaultIncubatorURI,
})
if err != nil {
return err
}