Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement "kubedb delete" #15

Merged
merged 5 commits into from
May 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/kubedb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Basic Commands (Beginner):

Basic Commands (Intermediate):
get Display one or many resources
delete Delete resources by filenames, stdin, resources and names, or by resources and label selector

Other Commands:
help Help about any command
Expand Down
66 changes: 66 additions & 0 deletions docs/kubedb/delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# kubedb delete

## Example

##### Help for delete command

```bash
Delete resources by filenames, stdin, resources and names, or by resources and label selector. JSON and YAML formats are
accepted.

Note that the delete command does NOT do resource version checks

Examples:
# Delete a elastic using the type and name specified in elastic.json.
kubedb delete -f ./elastic.json

# Delete a postgres based on the type and name in the JSON passed into stdin.
cat postgres.json | kubedb delete -f -

# Delete elastic with label elastic.k8sdb.com/name=elasticsearch-demo.
kubedb delete elastic -l elastic.k8sdb.com/name=elasticsearch-demo

# Delete all deleteddatabase
kubedb delete deleteddatabase --all

Options:
--all=false: [-all] to select all the specified resources.
-f, --filename=[]: Filename to use to create the resource
-o, --output='': Output mode. Use "-o name" for shorter output (resource/name).
-R, --recursive=false: Process the directory used in -f, --filename recursively.
-l, --selector='': Selector (label query) to filter on.

Usage:
kubedb delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)]) [options]

Use "kubedb delete options" for a list of global command-line options (applies to all commands).
```

##### Delete
```bash
$ kubedb delete pg/postgres-demo

postgres "postgres-demo" deleted
```

##### Delete All
```bash
$ kubedb delete deleteddatabase --all

deleteddatabase "elasticsearch-demo" deleted
deleteddatabase "postgres-demo" deleted
```

##### Delete from file
```bash
$ kubedb delete -f ./elastic.json

elastic "elasticsearch-demo" deleted
```

##### Delete from stdin
```bash
$ cat ./elastic.json | kubedb delete -f -

elastic "elasticsearch-demo" deleted
```
1 change: 1 addition & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func NewKubedbCommand(in io.Reader, out, err io.Writer) *cobra.Command {
Message: "Basic Commands (Intermediate):",
Commands: []*cobra.Command{
NewCmdGet(out, err),
NewCmdDelete(out, err),
},
},
}
Expand Down
142 changes: 142 additions & 0 deletions pkg/cmd/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package cmd

import (
"fmt"
"io"
"strings"

"github.com/k8sdb/kubedb/pkg/cmd/util"
"github.com/k8sdb/kubedb/pkg/kube"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
)

// ref: k8s.io/kubernetes/pkg/kubectl/cmd/delete.go

var (
delete_long = templates.LongDesc(`
Delete resources by filenames, stdin, resources and names, or by resources and label selector.
JSON and YAML formats are accepted.

Note that the delete command does NOT do resource version checks`)

delete_example = templates.Examples(`
# Delete a elastic using the type and name specified in elastic.json.
kubedb delete -f ./elastic.json

# Delete a postgres based on the type and name in the JSON passed into stdin.
cat postgres.json | kubedb delete -f -

# Delete elastic with label elastic.k8sdb.com/name=elasticsearch-demo.
kubedb delete elastic -l elastic.k8sdb.com/name=elasticsearch-demo

# Delete all deleteddatabase
kubedb delete deleteddatabase --all`)
)

func NewCmdDelete(out, errOut io.Writer) *cobra.Command {
options := &resource.FilenameOptions{}

cmd := &cobra.Command{
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
Short: "Delete resources by filenames, stdin, resources and names, or by resources and label selector",
Long: delete_long,
Example: delete_example,
Run: func(cmd *cobra.Command, args []string) {
f := kube.NewKubeFactory(cmd)
cmdutil.CheckErr(RunDelete(f, cmd, out, args, options))
},
}

util.AddFilenameOptionFlags(cmd, options)
util.AddDeleteFlags(cmd)
return cmd
}

func RunDelete(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string, options *resource.FilenameOptions) error {
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
deleteAll := cmdutil.GetFlagBool(cmd, "all")
mapper, typer, err := f.UnstructuredObject()
if err != nil {
return err
}

if len(args) > 0 {
resources := strings.Split(args[0], ",")
for i, r := range resources {
items := strings.Split(r, "/")
kind, err := util.GetSupportedResourceKind(items[0])
if err != nil {
return err
}
items[0] = kind
resources[i] = strings.Join(items, "/")
}
args[0] = strings.Join(resources, ",")
}

r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, options).
SelectorParam(cmdutil.GetFlagString(cmd, "selector")).
SelectAllParam(deleteAll).
ResourceTypeOrNameArgs(true, args...).RequireObject(true).
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}

shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
return deleteResult(r, out, shortOutput, mapper)
}

func deleteResult(r *resource.Result, out io.Writer, shortOutput bool, mapper meta.RESTMapper) error {
infoList := make([]*resource.Info, 0)
err := r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
kind := info.GetObjectKind().GroupVersionKind().Kind
if err := util.CheckSupportedResource(kind); err != nil {
return err
}

infoList = append(infoList, info)
return nil

})
if err != nil {
return err
}

found := 0
for _, info := range infoList {
found++
if err := deleteResource(info, out, shortOutput, mapper); err != nil {
return err
}
}

if found == 0 {
fmt.Fprintf(out, "No resources found\n")
}
return nil
}

func deleteResource(info *resource.Info, out io.Writer, shortOutput bool, mapper meta.RESTMapper) error {
if err := resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name); err != nil {
return cmdutil.AddSourceToErr("deleting", info.Source, err)
}
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, false, "deleted")
return nil
}
11 changes: 11 additions & 0 deletions pkg/cmd/util/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ func AddCreateFlags(cmd *cobra.Command, options *resource.FilenameOptions) {
cmd.Flags().StringSliceVarP(&options.Filenames, "filename", "f", options.Filenames, "Filename to use to create the resource")
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively.")
}

func AddDeleteFlags(cmd *cobra.Command) {
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on.")
cmd.Flags().Bool("all", false, "[-all] to select all the specified resources.")
cmd.Flags().StringP("output", "o", "", "Output mode. Use \"-o name\" for shorter output (resource/name).")
}

func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions) {
cmd.Flags().StringSliceVarP(&options.Filenames, "filename", "f", options.Filenames, "Filename to use to create the resource")
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively.")
}