Unverified Commit b6b33c5b authored by Bryan Liles's avatar Bryan Liles Committed by GitHub
Browse files

Merge pull request #796 from bryanl/remove-component

Remove component in module with
parents 230769d7 d617aed0
...@@ -57,6 +57,8 @@ type Component interface { ...@@ -57,6 +57,8 @@ type Component interface {
// Params returns a list of all parameters for a component. If envName is a // Params returns a list of all parameters for a component. If envName is a
// blank string, it will report the local parameters. // blank string, it will report the local parameters.
Params(envName string) ([]ModuleParameter, error) Params(envName string) ([]ModuleParameter, error)
// Remove removes the component
Remove() error
// SetParams sets a component paramaters. // SetParams sets a component paramaters.
SetParam(path []string, value interface{}) error SetParam(path []string, value interface{}) error
// Summarize returns a summary of the component. // Summarize returns a summary of the component.
...@@ -87,7 +89,7 @@ func LocateComponent(ksApp app.App, module, name string) (Component, error) { ...@@ -87,7 +89,7 @@ func LocateComponent(ksApp app.App, module, name string) (Component, error) {
// Path returns returns the file system path for a component. // Path returns returns the file system path for a component.
func Path(a app.App, name string) (string, error) { func Path(a app.App, name string) (string, error) {
ns, localName := ExtractModuleComponent(a, name) ns, localName := extractModuleComponent(a, name)
fis, err := afero.ReadDir(a.Fs(), ns.Dir()) fis, err := afero.ReadDir(a.Fs(), ns.Dir())
if err != nil { if err != nil {
...@@ -122,7 +124,7 @@ func Path(a app.App, name string) (string, error) { ...@@ -122,7 +124,7 @@ func Path(a app.App, name string) (string, error) {
// ExtractComponent extracts a component from a path. // ExtractComponent extracts a component from a path.
func ExtractComponent(a app.App, path string) (Component, error) { func ExtractComponent(a app.App, path string) (Component, error) {
ns, componentName := ExtractModuleComponent(a, path) ns, componentName := extractModuleComponent(a, path)
members, err := ns.Components() members, err := ns.Components()
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -31,19 +31,35 @@ import ( ...@@ -31,19 +31,35 @@ import (
// the directory structure in a half-finished state. // the directory structure in a half-finished state.
func Delete(a app.App, name string) error { func Delete(a app.App, name string) error {
log.Debugf("deleting component %s", name) log.Debugf("deleting component %s", name)
componentPath, err := Path(a, name)
moduleName, componentName, err := extractPathParts(a, name)
if err != nil { if err != nil {
return err return err
} }
ns, _ := ExtractModuleComponent(a, name) m := NewModule(a, moduleName)
var c Component
components, err := m.Components()
if err != nil {
return err
}
for i := range components {
if components[i].Name(false) == componentName {
c = components[i]
}
}
if c == nil {
return errors.Errorf("unable to find component %q", name)
}
// Build the new component/params.libsonnet file. // Build the new component params.libsonnet file.
componentParamsFile, err := afero.ReadFile(a.Fs(), ns.ParamsPath()) componentParamsFile, err := afero.ReadFile(a.Fs(), m.ParamsPath())
if err != nil { if err != nil {
return err return err
} }
componentJsonnet, err := param.DeleteComponent(name, string(componentParamsFile)) componentJsonnet, err := param.DeleteComponent(c.Name(false), string(componentParamsFile))
if err != nil { if err != nil {
return err return err
} }
...@@ -71,8 +87,8 @@ func Delete(a app.App, name string) error { ...@@ -71,8 +87,8 @@ func Delete(a app.App, name string) error {
log.Infof("Removing component parameter references ...") log.Infof("Removing component parameter references ...")
// Remove the references in component/params.libsonnet. // Remove the references in component/params.libsonnet.
log.Debugf("... deleting references in %s", ns.ParamsPath()) log.Debugf("... deleting references in %s", m.ParamsPath())
err = afero.WriteFile(a.Fs(), ns.ParamsPath(), []byte(componentJsonnet), defaultFilePermissions) err = afero.WriteFile(a.Fs(), m.ParamsPath(), []byte(componentJsonnet), defaultFilePermissions)
if err != nil { if err != nil {
return err return err
} }
...@@ -84,8 +100,8 @@ func Delete(a app.App, name string) error { ...@@ -84,8 +100,8 @@ func Delete(a app.App, name string) error {
// //
// Delete the component file in components/. // Delete the component file in components/.
// //
log.Infof("Deleting component '%s' at path '%s'", name, componentPath) log.Infof("Deleting component %q", name)
if err := a.Fs().Remove(componentPath); err != nil { if err := c.Remove(); err != nil {
return err return err
} }
...@@ -110,8 +126,8 @@ func collectEnvParams(a app.App, env *app.EnvironmentConfig, componentName, envN ...@@ -110,8 +126,8 @@ func collectEnvParams(a app.App, env *app.EnvironmentConfig, componentName, envN
return ecr.Remove(componentName, string(envParamsFile)) return ecr.Remove(componentName, string(envParamsFile))
} }
/// updateEnvParam removes the component references in each environment's // updateEnvParam removes the component references in each environment's
// paramss.libsonnet. // params.libsonnet.
func updateEnvParam(a app.App, envs app.EnvironmentConfigs, envParams map[string]string) error { func updateEnvParam(a app.App, envs app.EnvironmentConfigs, envParams map[string]string) error {
for envName := range envs { for envName := range envs {
path := filepath.Join(a.Root(), "environments", envName, "params.libsonnet") path := filepath.Join(a.Root(), "environments", envName, "params.libsonnet")
......
...@@ -53,3 +53,33 @@ func TestDelete(t *testing.T) { ...@@ -53,3 +53,33 @@ func TestDelete(t *testing.T) {
) )
}) })
} }
func TestDeleteWithModule(t *testing.T) {
test.WithApp(t, "/app", func(a *mocks.App, fs afero.Fs) {
test.StageDir(t, fs, "delete", "/app")
envs := app.EnvironmentConfigs{
"default": &app.EnvironmentConfig{},
}
a.On("Environments").Return(envs, nil)
err := Delete(a, "nested.guestbook-ui")
require.NoError(t, err)
base := filepath.Join("/app", "components", "nested")
test.AssertNotExists(t, fs, filepath.Join(base, "guestbook-ui.jsonnet"))
test.AssertContents(
t,
fs,
"delete-params.libsonnet",
filepath.Join(base, "params.libsonnet"),
)
test.AssertContents(
t,
fs,
"delete-env-params-nested.libsonnet",
filepath.Join("/app", "environments", "default", "params.libsonnet"),
)
})
}
...@@ -79,6 +79,17 @@ func (j *Jsonnet) Type() string { ...@@ -79,6 +79,17 @@ func (j *Jsonnet) Type() string {
return TypeJsonnet return TypeJsonnet
} }
// Remove removes the component.
func (j *Jsonnet) Remove() error {
m := NewModule(j.app, j.module)
path := filepath.Join(m.Dir(), j.Name(false)+"."+j.Type())
if err := j.app.Fs().Remove(path); err != nil {
return errors.Wrapf(err, "removing %q", path)
}
return nil
}
// SetParam set parameter for a component. // SetParam set parameter for a component.
func (j *Jsonnet) SetParam(path []string, value interface{}) error { func (j *Jsonnet) SetParam(path []string, value interface{}) error {
paramsData, err := j.readModuleParams() paramsData, err := j.readModuleParams()
......
...@@ -119,7 +119,7 @@ func extractPathParts(ksApp app.App, path string) (string, string, error) { ...@@ -119,7 +119,7 @@ func extractPathParts(ksApp app.App, path string) (string, string, error) {
} }
path = strings.Replace(path, ".", string(filepath.Separator), -1) path = strings.Replace(path, ".", string(filepath.Separator), -1)
module, componentName := ExtractModuleComponent(ksApp, path) module, componentName := extractModuleComponent(ksApp, path)
base := filepath.Join(module.Dir(), componentName) base := filepath.Join(module.Dir(), componentName)
exts := []string{".yaml", ".jsonnet", ".json"} exts := []string{".yaml", ".jsonnet", ".json"}
......
...@@ -76,6 +76,20 @@ func (_m *Component) Params(envName string) ([]component.ModuleParameter, error) ...@@ -76,6 +76,20 @@ func (_m *Component) Params(envName string) ([]component.ModuleParameter, error)
return r0, r1 return r0, r1
} }
// Remove provides a mock function with given fields:
func (_m *Component) Remove() error {
ret := _m.Called()
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// SetParam provides a mock function with given fields: path, value // SetParam provides a mock function with given fields: path, value
func (_m *Component) SetParam(path []string, value interface{}) error { func (_m *Component) SetParam(path []string, value interface{}) error {
ret := _m.Called(path, value) ret := _m.Called(path, value)
......
...@@ -83,8 +83,8 @@ func NewModule(ksApp app.App, path string) *FilesystemModule { ...@@ -83,8 +83,8 @@ func NewModule(ksApp app.App, path string) *FilesystemModule {
return &FilesystemModule{app: ksApp, path: path} return &FilesystemModule{app: ksApp, path: path}
} }
// ExtractModuleComponent extracts a module and a component from a filesystem path. // extractModuleComponent extracts a module and a component from a filesystem path.
func ExtractModuleComponent(a app.App, path string) (Module, string) { func extractModuleComponent(a app.App, path string) (Module, string) {
dir, file := filepath.Split(path) dir, file := filepath.Split(path)
componentName := strings.TrimSuffix(file, filepath.Ext(file)) componentName := strings.TrimSuffix(file, filepath.Ext(file))
......
...@@ -169,7 +169,7 @@ func TestExtractModuleComponent(t *testing.T) { ...@@ -169,7 +169,7 @@ func TestExtractModuleComponent(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
test.WithApp(t, "/app", func(a *mocks.App, fs afero.Fs) { test.WithApp(t, "/app", func(a *mocks.App, fs afero.Fs) {
m, c := ExtractModuleComponent(a, tc.in) m, c := extractModuleComponent(a, tc.in)
assert.Equal(t, tc.m, m.Name()) assert.Equal(t, tc.m, m.Name())
assert.Equal(t, tc.c, c) assert.Equal(t, tc.c, c)
......
local params = import '../../components/params.libsonnet';
params {
components+: {
"guestbook-ui"+: {
name: 'guestbook-dev',
},
},
}
\ No newline at end of file
local params = import '../../components/params.libsonnet'; local params = import '../../components/params.libsonnet';
params { params {
components+: {}, components+: {
"nested.guestbook-ui"+: {
name: 'guestbook-dev',
},
},
} }
\ No newline at end of file
local env = std.extVar("__ksonnet/environments");
local params = std.extVar("__ksonnet/params").components["guestbook-ui"];
local k = import "k.libsonnet";
local deployment = k.apps.v1beta1.deployment;
local container = k.apps.v1beta1.deployment.mixin.spec.template.spec.containersType;
local containerPort = container.portsType;
local service = k.core.v1.service;
local servicePort = k.core.v1.service.mixin.spec.portsType;
local targetPort = params.containerPort;
local labels = {app: params.name};
local appService = service
.new(
params.name,
labels,
servicePort.new(params.servicePort, targetPort))
.withType(params.type);
local appDeployment = deployment
.new(
params.name,
params.replicas,
container
.new(params.name, params.image)
.withPorts(containerPort.new(targetPort)),
labels);
k.core.v1.list.new([appService, appDeployment])
\ No newline at end of file
{
global: {
// User-defined global parameters; accessible to all component and environments, Ex:
// replicas: 4,
},
components: {
// Component-level parameters, defined initially from 'ks prototype use ...'
// Each object below should correspond to a component in the components/ directory
"guestbook-ui": {
containerPort: 80,
image: "gcr.io/heptio-images/ks-guestbook-demo:0.1",
name: "guiroot",
replicas: 1,
servicePort: 80,
type: "ClusterIP",
obj: {a: "b"},
},
},
}
...@@ -4,5 +4,8 @@ params { ...@@ -4,5 +4,8 @@ params {
"guestbook-ui" +: { "guestbook-ui" +: {
name: "guestbook-dev", name: "guestbook-dev",
}, },
"nested.guestbook-ui" +: {
name: "guestbook-dev",
},
}, },
} }
...@@ -80,6 +80,17 @@ func (y *YAML) Type() string { ...@@ -80,6 +80,17 @@ func (y *YAML) Type() string {
return TypeYAML return TypeYAML
} }
// Remove removes the component.
func (y *YAML) Remove() error {
m := NewModule(y.app, y.module)
path := filepath.Join(m.Dir(), y.Name(false)+"."+y.Type())
if err := y.app.Fs().Remove(path); err != nil {
return errors.Wrapf(err, "removing %q", path)
}
return nil
}
// Params returns params for a component. // Params returns params for a component.
func (y *YAML) Params(envName string) ([]ModuleParameter, error) { func (y *YAML) Params(envName string) ([]ModuleParameter, error) {
y.log().WithField("env-name", envName).Debug("getting component params") y.log().WithField("env-name", envName).Debug("getting component params")
......
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