Skip to content

Commit

Permalink
Implement "kubedb create" (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mir Shahriar authored and tamalsaha committed May 8, 2017
1 parent 8e258ea commit 8588ea6
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 19 deletions.
20 changes: 20 additions & 0 deletions docs/kubedb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# kubedb

```bash
$ kubedb --help

kubedb controls k8sdb ThirdPartyResource objects.

Find more information at https://github.com/k8sdb/kubedb.

Basic Commands (Beginner):
create Create a resource by filename or stdin

Basic Commands (Intermediate):
get Display one or many resources

Other Commands:
help Help about any command

Use "kubedb <command> --help" for more information about a given command.
```
51 changes: 51 additions & 0 deletions docs/kubedb/create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# kubedb create

## Example

##### Help for create command

```bash
$ kubedb create --help

Create a resource by filename or stdin.

JSON and YAML formats are accepted.

Examples:
# Create a elastic using the data in elastic.json.
kubedb create -f ./elastic.json

# Create a elastic based on the JSON passed into stdin.
cat elastic.json | kubedb create -f -

Options:
-f, --filename=[]: Filename to use to create the resource
-R, --recursive=false: Process the directory used in -f, --filename recursively.

Usage:
kubedb create [options]

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

##### Create from file
```bash
$ kubedb create -f ./elastic.json

elastic "elasticsearch-demo" created
```

##### Create from stdin
```bash
$ cat ./elastic.json | kubedb create -f -

elastic "elasticsearch-demo" created
```

##### Create from folder
```bash
$ kubedb create -f resources -R

es "elasticsearch-demo" created
pg "postgres-demo" created
```
18 changes: 0 additions & 18 deletions docs/kubedb/get.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,6 @@

## Example

##### Get help
```bash
$ kubedb --help

kubedb controls k8sdb ThirdPartyResource objects.

Find more information at https://github.com/k8sdb/kubedb.

Basic Commands (Intermediate):
get Display one or many resources

Other Commands:
help Help about any command

Use "kubedb <command> --help" for more information about a given command.
```


##### Help for get command

```bash
Expand Down
6 changes: 6 additions & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ func NewKubedbCommand(in io.Reader, out, err io.Writer) *cobra.Command {
}

groups := templates.CommandGroups{
{
Message: "Basic Commands (Beginner):",
Commands: []*cobra.Command{
NewCmdCreate(out, err),
},
},
{
Message: "Basic Commands (Intermediate):",
Commands: []*cobra.Command{
Expand Down
134 changes: 134 additions & 0 deletions pkg/cmd/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package cmd

import (
"errors"
"io"

"github.com/k8sdb/kubedb/pkg/cmd/util"
"github.com/k8sdb/kubedb/pkg/kube"
"github.com/spf13/cobra"
"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/create.go

var (
create_long = templates.LongDesc(`
Create a resource by filename or stdin.
JSON and YAML formats are accepted.`)

create_example = templates.Examples(`
# Create a elastic using the data in elastic.json.
kubedb create -f ./elastic.json
# Create a elastic based on the JSON passed into stdin.
cat elastic.json | kubedb create -f -`)
)

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

cmd := &cobra.Command{
Use: "create",
Short: "Create a resource by filename or stdin",
Long: create_long,
Example: create_example,
Run: func(cmd *cobra.Command, args []string) {
if cmdutil.IsFilenameEmpty(options.Filenames) {
defaultRunFunc := cmdutil.DefaultSubCommandRun(errOut)
defaultRunFunc(cmd, args)
return
}
f := kube.NewKubeFactory(cmd)
cmdutil.CheckErr(RunCreate(f, out, options))
},
}

util.AddCreateFlags(cmd, options)
return cmd
}

func RunCreate(f cmdutil.Factory, out io.Writer, options *resource.FilenameOptions) error {
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}

mapper, typer, err := f.UnstructuredObject()
if err != nil {
return err
}

r := resource.NewBuilder(
mapper,
typer,
resource.ClientMapperFunc(f.UnstructuredClientForMapping),
runtime.UnstructuredJSONScheme).
Schema(util.Validator()).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, options).
Flatten().
Do()

err = r.Err()
if err != nil {
return err
}

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
}

showAlias := false
if len(infoList) > 1 {
showAlias = true
}

count := 0
for _, info := range infoList {
if err := createAndRefresh(info); err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err)
}
count++
resourceName := info.Mapping.Resource
if showAlias {
if alias, ok := util.ResourceShortFormFor(info.Mapping.Resource); ok {
resourceName = alias
}
}
cmdutil.PrintSuccess(mapper, false, out, resourceName, info.Name, false, "created")
}

if count == 0 {
return errors.New("no objects passed to create")
}
return nil
}

func createAndRefresh(info *resource.Info) error {
obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
if err != nil {
return err
}
info.Refresh(obj, true)
return nil
}
10 changes: 9 additions & 1 deletion pkg/cmd/util/flags.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package util

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/resource"
)

func AddGetFlags(cmd *cobra.Command) {
cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
Expand All @@ -10,3 +13,8 @@ func AddGetFlags(cmd *cobra.Command) {
cmd.Flags().BoolP("show-all", "a", false, "When printing, show all resources (default hide terminated pods.)")
cmd.Flags().Bool("show-labels", false, "When printing, show all labels as the last column (default hide labels column)")
}

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.")
}
13 changes: 13 additions & 0 deletions pkg/cmd/util/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ func GetSupportedResourceKind(resource string) (string, error) {
return resource, nil
}

func CheckSupportedResource(kind string) error {
switch kind {
case tapi.ResourceKindElastic:
case tapi.ResourceKindPostgres:
case tapi.ResourceKindDatabaseSnapshot:
case tapi.ResourceKindDeletedDatabase:
return nil
default:
return fmt.Errorf(`kubedb doesn't support a resource type "%v"`, kind)
}
return nil
}

func GetAllSupportedResources(f cmdutil.Factory) ([]string, error) {

resources := map[string]string{
Expand Down
17 changes: 17 additions & 0 deletions pkg/cmd/util/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package util

import (
"k8s.io/kubernetes/pkg/api/validation"
)

type ConjunctiveSchema []validation.Schema

func (c *ConjunctiveSchema) ValidateBytes(data []byte) error {
return nil
}

func Validator() validation.Schema {
return validation.ConjunctiveSchema{
validation.NoDoubleKeySchema{},
}
}

0 comments on commit 8588ea6

Please sign in to comment.