Skip to content

Commit

Permalink
make kubectl --raw consistent for create, update, get, delete
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Jul 9, 2019
1 parent 7054e3e commit 09c55bd
Show file tree
Hide file tree
Showing 20 changed files with 305 additions and 89 deletions.
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/create/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ go_library(
"//staging/src/k8s.io/client-go/kubernetes/typed/batch/v1beta1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/rbac/v1:go_default_library",
"//staging/src/k8s.io/component-base/cli/flag:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/rawhttp:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
Expand Down
39 changes: 6 additions & 33 deletions pkg/kubectl/cmd/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"fmt"
"io"
"net/url"
"os"
"runtime"
"strings"

Expand All @@ -36,6 +35,7 @@ import (
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/dynamic"
"k8s.io/kubectl/pkg/rawhttp"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
Expand Down Expand Up @@ -213,7 +213,11 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
// raw only makes sense for a single file resource multiple objects aren't likely to do what you want.
// the validator enforces this, so
if len(o.Raw) > 0 {
return o.raw(f)
restClient, err := f.RESTClient()
if err != nil {
return err
}
return rawhttp.RawPost(restClient, o.IOStreams, o.Raw, o.FilenameOptions.Filenames[0])
}

if o.EditBeforeCreate {
Expand Down Expand Up @@ -275,37 +279,6 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
return nil
}

// raw makes a simple HTTP request to the provided path on the server using the default
// credentials.
func (o *CreateOptions) raw(f cmdutil.Factory) error {
restClient, err := f.RESTClient()
if err != nil {
return err
}

var data io.ReadCloser
if o.FilenameOptions.Filenames[0] == "-" {
data = os.Stdin
} else {
data, err = os.Open(o.FilenameOptions.Filenames[0])
if err != nil {
return err
}
}
// TODO post content with stream. Right now it ignores body content
result := restClient.Post().RequestURI(o.Raw).Body(data).Do()
if err := result.Error(); err != nil {
return err
}
body, err := result.Raw()
if err != nil {
return err
}

fmt.Fprintf(o.Out, "%v", string(body))
return nil
}

// RunEditOnCreate performs edit on creation
func RunEditOnCreate(f cmdutil.Factory, printFlags *genericclioptions.PrintFlags, recordFlags *genericclioptions.RecordFlags, ioStreams genericclioptions.IOStreams, cmd *cobra.Command, options *resource.FilenameOptions) error {
editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, ioStreams)
Expand Down
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/delete/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ go_library(
"//staging/src/k8s.io/cli-runtime/pkg/printers:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/resource:go_default_library",
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/rawhttp:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
Expand Down
87 changes: 61 additions & 26 deletions pkg/kubectl/cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package delete

import (
"fmt"
"net/url"
"strings"
"time"

Expand All @@ -32,6 +33,7 @@ import (
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/dynamic"
"k8s.io/kubectl/pkg/rawhttp"
"k8s.io/kubectl/pkg/util/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
cmdwait "k8s.io/kubernetes/pkg/kubectl/cmd/wait"
Expand Down Expand Up @@ -107,6 +109,7 @@ type DeleteOptions struct {
WaitForDeletion bool
Quiet bool
WarnClusterScope bool
Raw string

GracePeriod int
Timeout time.Duration
Expand All @@ -133,7 +136,7 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
o := deleteFlags.ToOptions(nil, streams)
cmdutil.CheckErr(o.Complete(f, args, cmd))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunDelete())
cmdutil.CheckErr(o.RunDelete(f))
},
SuggestFor: []string{"rm"},
}
Expand Down Expand Up @@ -170,32 +173,34 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Co
o.GracePeriod = 1
}

r := f.NewBuilder().
Unstructured().
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
SelectAllParam(o.DeleteAll).
AllNamespaces(o.DeleteAllNamespaces).
ResourceTypeOrNameArgs(false, args...).RequireObject(false).
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
o.Result = r
if len(o.Raw) == 0 {
r := f.NewBuilder().
Unstructured().
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
SelectAllParam(o.DeleteAll).
AllNamespaces(o.DeleteAllNamespaces).
ResourceTypeOrNameArgs(false, args...).RequireObject(false).
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
o.Result = r

o.Mapper, err = f.ToRESTMapper()
if err != nil {
return err
}
o.Mapper, err = f.ToRESTMapper()
if err != nil {
return err
}

o.DynamicClient, err = f.DynamicClient()
if err != nil {
return err
o.DynamicClient, err = f.DynamicClient()
if err != nil {
return err
}
}

return nil
Expand All @@ -220,10 +225,40 @@ func (o *DeleteOptions) Validate() error {
fmt.Fprintf(o.ErrOut, "warning: --force is ignored because --grace-period is not 0.\n")
}

if len(o.Raw) > 0 {
if len(o.FilenameOptions.Filenames) > 1 {
return fmt.Errorf("--raw can only use a single local file or stdin")
} else if len(o.FilenameOptions.Filenames) == 1 {
if strings.Index(o.FilenameOptions.Filenames[0], "http://") == 0 || strings.Index(o.FilenameOptions.Filenames[0], "https://") == 0 {
return fmt.Errorf("--raw cannot read from a url")
}
}

if o.FilenameOptions.Recursive {
return fmt.Errorf("--raw and --recursive are mutually exclusive")
}
if len(o.Output) > 0 {
return fmt.Errorf("--raw and --output are mutually exclusive")
}
if _, err := url.ParseRequestURI(o.Raw); err != nil {
return fmt.Errorf("--raw must be a valid URL path: %v", err)
}
}

return nil
}

func (o *DeleteOptions) RunDelete() error {
func (o *DeleteOptions) RunDelete(f cmdutil.Factory) error {
if len(o.Raw) > 0 {
restClient, err := f.RESTClient()
if err != nil {
return err
}
if len(o.Filenames) == 0 {
return rawhttp.RawDelete(restClient, o.IOStreams, o.Raw, "")
}
return rawhttp.RawDelete(restClient, o.IOStreams, o.Raw, o.Filenames[0])
}
return o.DeleteResult(o.Result)
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/kubectl/cmd/delete/delete_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type DeleteFlags struct {
Timeout *time.Duration
Wait *bool
Output *string
Raw *string
}

func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams genericclioptions.IOStreams) *DeleteOptions {
Expand Down Expand Up @@ -93,6 +94,9 @@ func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams generic
if f.Wait != nil {
options.WaitForDeletion = *f.Wait
}
if f.Raw != nil {
options.Raw = *f.Raw
}

return options
}
Expand Down Expand Up @@ -135,6 +139,9 @@ func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
if f.Output != nil {
cmd.Flags().StringVarP(f.Output, "output", "o", *f.Output, "Output mode. Use \"-o name\" for shorter output (resource/name).")
}
if f.Raw != nil {
cmd.Flags().StringVar(f.Raw, "raw", *f.Raw, "Raw URI to DELETE to the server. Uses the transport specified by the kubeconfig file.")
}
}

// NewDeleteCommandFlags provides default flags and values for use with the "delete" command
Expand All @@ -153,6 +160,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
fieldSelector := ""
timeout := time.Duration(0)
wait := true
raw := ""

filenames := []string{}
recursive := false
Expand All @@ -175,6 +183,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
Timeout: &timeout,
Wait: &wait,
Output: &output,
Raw: &raw,
}
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/kubectl/cmd/delete/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func TestDeleteObjectNotFound(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = options.RunDelete()
err = options.RunDelete(nil)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
Expand Down Expand Up @@ -408,7 +408,7 @@ func TestDeleteAllNotFound(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = options.RunDelete()
err = options.RunDelete(nil)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
Expand Down Expand Up @@ -531,7 +531,7 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = options.RunDelete()
err = options.RunDelete(nil)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/get/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ go_library(
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/tools/watch:go_default_library",
"//staging/src/k8s.io/client-go/util/jsonpath:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/rawhttp:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/interrupt:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/printers:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
Expand Down
28 changes: 6 additions & 22 deletions pkg/kubectl/cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
kubernetesscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
watchtools "k8s.io/client-go/tools/watch"
"k8s.io/kubectl/pkg/rawhttp"
"k8s.io/kubectl/pkg/util/interrupt"
utilprinters "k8s.io/kubectl/pkg/util/printers"
"k8s.io/kubectl/pkg/util/templates"
Expand Down Expand Up @@ -439,7 +440,11 @@ func (o *GetOptions) transformRequests(req *rest.Request) {
// TODO: remove the need to pass these arguments, like other commands.
func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if len(o.Raw) > 0 {
return o.raw(f)
restClient, err := f.RESTClient()
if err != nil {
return err
}
return rawhttp.RawGet(restClient, o.IOStreams, o.Raw)
}
if o.Watch || o.WatchOnly {
return o.watch(f, cmd, args)
Expand Down Expand Up @@ -579,27 +584,6 @@ func (t *trackingWriterWrapper) Write(p []byte) (n int, err error) {
return t.Delegate.Write(p)
}

// raw makes a simple HTTP request to the provided path on the server using the default
// credentials.
func (o *GetOptions) raw(f cmdutil.Factory) error {
restClient, err := f.RESTClient()
if err != nil {
return err
}

stream, err := restClient.Get().RequestURI(o.Raw).Stream()
if err != nil {
return err
}
defer stream.Close()

_, err = io.Copy(o.Out, stream)
if err != nil && err != io.EOF {
return err
}
return nil
}

// watch starts a client-side watch of one or more resources.
// TODO: remove the need for arguments here.
func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
Expand Down
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/replace/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/resource:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/rawhttp:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/util/templates:go_default_library",
"//staging/src/k8s.io/kubectl/pkg/validation:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
Expand Down
Loading

0 comments on commit 09c55bd

Please sign in to comment.