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 {
}
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
for name, env := range environments {
override := ""
if env.IsOverride() {
override = "*"
}
rows = append(rows, []string{
name,
override,
env.KubernetesVersion,
env.Destination.Namespace,
env.Destination.Server,
......
// Copyright 2017 The kubecfg authors
// Copyright 2018 The ksonnet authors
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
......@@ -13,41 +13,52 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package kubecfg
package actions
import (
"github.com/ksonnet/ksonnet/metadata"
"github.com/ksonnet/ksonnet/env"
"github.com/ksonnet/ksonnet/metadata/app"
)
type EnvAddCmd struct {
name string
server string
namespace string
spec string
// RunEnvRm runs `env rm`
func RunEnvRm(ksApp app.App, envName string, isOverride bool) error {
ea, err := NewEnvRm(ksApp, envName, isOverride)
if err != nil {
return err
}
manager metadata.Manager
return ea.Run()
}
func NewEnvAddCmd(name, server, namespace, specFlag string, manager metadata.Manager) (*EnvAddCmd, error) {
return &EnvAddCmd{name: name, server: server, namespace: namespace, spec: specFlag, manager: manager}, nil
}
type envDeleteFn func(a app.App, name string, override bool) error
func (c *EnvAddCmd) Run() error {
return c.manager.CreateEnvironment(c.name, c.server, c.namespace, c.spec)
}
// EnvRm sets targets for an environment.
type EnvRm struct {
app app.App
envName string
isOverride bool
// ==================================================================
envDeleteFn envDeleteFn
}
type EnvRmCmd struct {
name string
// NewEnvRm creates an instance of EnvRm.
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 &EnvRmCmd{name: name, manager: manager}, nil
return ea, nil
}
func (c *EnvRmCmd) Run() error {
return c.manager.DeleteEnvironment(c.name)
// Run assigns targets to an environment.
func (er *EnvRm) Run() error {
return er.envDeleteFn(
er.app,
er.envName,
er.isOverride,
)
}
......@@ -13,27 +13,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by mockery v1.0.0
package mocks
package actions
import env "github.com/ksonnet/ksonnet/env"
import mock "github.com/stretchr/testify/mock"
import (
"testing"
// Manager is an autogenerated mock type for the Manager type
type Manager struct {
mock.Mock
}
"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 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
func (_m *Manager) Rename(from string, to string, config env.RenameConfig) error {
ret := _m.Called(from, to, config)
a.envDeleteFn = func(a app.App, name string, override bool) error {
assert.Equal(t, appMock, a)
assert.Equal(t, aName, name)
assert.Equal(t, aIsOverride, override)
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 nil
}
return r0
err = a.Run()
require.NoError(t, err)
})
}
......@@ -50,17 +50,20 @@ func RunEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) error {
// EnvSet sets targets for an environment.
type EnvSet struct {
app app.App
em env.Manager
envName string
newName 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.
func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error) {
es := &EnvSet{
app: ksApp,
em: env.DefaultManager,
envRename: env.Rename,
updateEnv: updateEnv,
envName: envName,
}
......@@ -73,19 +76,21 @@ func NewEnvSet(ksApp app.App, envName string, opts ...EnvSetOpt) (*EnvSet, error
// Run assigns targets to an environment.
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 es.updateNamespace()
return es.updateNamespace(env)
}
func (es *EnvSet) updateName() error {
func (es *EnvSet) updateName(isOverride bool) error {
if es.newName != "" {
config := env.RenameConfig{
App: es.app,
}
if err := es.em.Rename(es.envName, es.newName, config); err != nil {
if err := es.envRename(es.app, es.envName, es.newName, isOverride); err != nil {
return err
}
......@@ -95,16 +100,15 @@ func (es *EnvSet) updateName() error {
return nil
}
func (es *EnvSet) updateNamespace() error {
func (es *EnvSet) updateNamespace(env *app.EnvironmentSpec) 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)
env.Destination.Namespace = es.newNsName
return updateEnv(es.app, es.envName, env, env.IsOverride())
}
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
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/assert"
"github.com/stretchr/testify/require"
)
......@@ -35,14 +34,21 @@ func TestEnvSet_name(t *testing.T) {
a, err := NewEnvSet(appMock, envName, nameOpt)
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{
App: appMock,
return nil
}
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()
require.NoError(t, err)
......@@ -72,8 +78,7 @@ func TestEnvSet_namespace(t *testing.T) {
}
appMock.On("Environment", envName).Return(spec, nil)
appMock.On("AddEnvironment", envName, "", updatedSpec).Return(nil)
appMock.On("AddEnvironment", envName, "", updatedSpec, false).Return(nil)
err = a.Run()
require.NoError(t, err)
......@@ -92,6 +97,22 @@ func TestEnvSet_name_and_namespace(t *testing.T) {
a, err := NewEnvSet(appMock, envName, nsOpt, nameOpt)
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{
Destination: &app.EnvironmentDestinationSpec{
Namespace: "default",
......@@ -104,17 +125,8 @@ func TestEnvSet_name_and_namespace(t *testing.T) {
},
}
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
appMock.On("Environment", "default").Return(spec, nil)
appMock.On("AddEnvironment", newName, "", updatedSpec, false).Return(nil)
err = a.Run()
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
}
registries := []registry.Registry{gh}
return i.appInitFn(
i.fs,
i.name,
i.rootPath,
i.k8sSpecFlag,
i.serverURI,
i.namespace,
registries,
)
}
// 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"
amocks "github.com/ksonnet/ksonnet/metadata/app/mocks"
"github.com/ksonnet/ksonnet/pkg/registry"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestInit(t *testing.T) {
withApp(t, func(appMock *amocks.App) {
aFs := appMock.Fs()
aName := "my-app"
aRootPath := appMock.Root()
aK8sSpecFlag := "specFlag"
aServerURI := "http://example.com"
aNamespace := "default"
a, err := NewInit(aFs, aName, aRootPath, aK8sSpecFlag, aServerURI, aNamespace)
require.NoError(t, err)
a.appInitFn = func(fs afero.Fs, name, rootPath, k8sSpecFlag, serverURI, namespace string, registries []registry.Registry) error {
assert.Equal(t, aFs, fs)
assert.Equal(t, aName, name)
assert.Equal(t, aRootPath, rootPath)
assert.Equal(t, aK8sSpecFlag, k8sSpecFlag)
assert.Equal(t, aServerURI, serverURI)
assert.Equal(t, aNamespace, namespace)
assert.Len(t, registries, 1)
r := registries[0]
assert.Equal(t, "github", r.Protocol())
assert.Equal(t, "github.com/ksonnet/parts/tree/master/incubator", r.URI())
assert.Equal(t, "incubator", r.Name())
return nil
}
err = a.Run()
require.NoError(t, err)
})
}
NAME KUBERNETES-VERSION NAMESPACE SERVER