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 create" #13

Merged
merged 7 commits into from
May 8, 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
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{},
}
}