diff --git a/pkg/kubectl/cmd/create/BUILD b/pkg/kubectl/cmd/create/BUILD index daf072674d480..74b4e57255f31 100644 --- a/pkg/kubectl/cmd/create/BUILD +++ b/pkg/kubectl/cmd/create/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/create/create.go b/pkg/kubectl/cmd/create/create.go index 502b792f7facb..688938d77f548 100644 --- a/pkg/kubectl/cmd/create/create.go +++ b/pkg/kubectl/cmd/create/create.go @@ -20,7 +20,6 @@ import ( "fmt" "io" "net/url" - "os" "runtime" "strings" @@ -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" @@ -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 { @@ -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) diff --git a/pkg/kubectl/cmd/delete/BUILD b/pkg/kubectl/cmd/delete/BUILD index 0550c1d978c45..72961456bc9ee 100644 --- a/pkg/kubectl/cmd/delete/BUILD +++ b/pkg/kubectl/cmd/delete/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/delete/delete.go b/pkg/kubectl/cmd/delete/delete.go index 2e3dd69df7c6c..f21876fac8f21 100644 --- a/pkg/kubectl/cmd/delete/delete.go +++ b/pkg/kubectl/cmd/delete/delete.go @@ -18,6 +18,7 @@ package delete import ( "fmt" + "net/url" "strings" "time" @@ -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" @@ -107,6 +109,7 @@ type DeleteOptions struct { WaitForDeletion bool Quiet bool WarnClusterScope bool + Raw string GracePeriod int Timeout time.Duration @@ -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"}, } @@ -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 @@ -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) } diff --git a/pkg/kubectl/cmd/delete/delete_flags.go b/pkg/kubectl/cmd/delete/delete_flags.go index 0cab48b174e9a..d34104f51d3e0 100644 --- a/pkg/kubectl/cmd/delete/delete_flags.go +++ b/pkg/kubectl/cmd/delete/delete_flags.go @@ -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 { @@ -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 } @@ -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 @@ -153,6 +160,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags { fieldSelector := "" timeout := time.Duration(0) wait := true + raw := "" filenames := []string{} recursive := false @@ -175,6 +183,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags { Timeout: &timeout, Wait: &wait, Output: &output, + Raw: &raw, } } diff --git a/pkg/kubectl/cmd/delete/delete_test.go b/pkg/kubectl/cmd/delete/delete_test.go index cd75175d01841..01f85c220ac71 100644 --- a/pkg/kubectl/cmd/delete/delete_test.go +++ b/pkg/kubectl/cmd/delete/delete_test.go @@ -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) } @@ -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) } @@ -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) } diff --git a/pkg/kubectl/cmd/get/BUILD b/pkg/kubectl/cmd/get/BUILD index f1e4d1a64bd6d..eecc0fe365e6d 100644 --- a/pkg/kubectl/cmd/get/BUILD +++ b/pkg/kubectl/cmd/get/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/get/get.go b/pkg/kubectl/cmd/get/get.go index c0dd9f332d696..4bf13074b2be0 100644 --- a/pkg/kubectl/cmd/get/get.go +++ b/pkg/kubectl/cmd/get/get.go @@ -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" @@ -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) @@ -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 { diff --git a/pkg/kubectl/cmd/replace/BUILD b/pkg/kubectl/cmd/replace/BUILD index 2da401f7d7b6c..eb72a22238546 100644 --- a/pkg/kubectl/cmd/replace/BUILD +++ b/pkg/kubectl/cmd/replace/BUILD @@ -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", diff --git a/pkg/kubectl/cmd/replace/replace.go b/pkg/kubectl/cmd/replace/replace.go index b09e95ddc7881..dedf1fbe90355 100644 --- a/pkg/kubectl/cmd/replace/replace.go +++ b/pkg/kubectl/cmd/replace/replace.go @@ -19,8 +19,10 @@ package replace import ( "fmt" "io/ioutil" + "net/url" "os" "path/filepath" + "strings" "time" "github.com/spf13/cobra" @@ -32,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/resource" + "k8s.io/kubectl/pkg/rawhttp" "k8s.io/kubectl/pkg/util/templates" "k8s.io/kubectl/pkg/validation" "k8s.io/kubernetes/pkg/kubectl" @@ -82,6 +85,7 @@ type ReplaceOptions struct { Namespace string EnforceNamespace bool + Raw string Recorder genericclioptions.Recorder @@ -109,7 +113,7 @@ func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Validate(cmd)) - cmdutil.CheckErr(o.Run()) + cmdutil.CheckErr(o.Run(f)) }, } @@ -120,6 +124,8 @@ func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr cmdutil.AddValidateFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd) + cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to PUT to the server. Uses the transport specified by the kubeconfig file.") + return cmd } @@ -197,10 +203,38 @@ func (o *ReplaceOptions) Validate(cmd *cobra.Command) error { return cmdutil.UsageErrorf(cmd, "Must specify --filename to replace") } + if len(o.Raw) > 0 { + if len(o.DeleteOptions.FilenameOptions.Filenames) != 1 { + return cmdutil.UsageErrorf(cmd, "--raw can only use a single local file or stdin") + } + if strings.Index(o.DeleteOptions.FilenameOptions.Filenames[0], "http://") == 0 || strings.Index(o.DeleteOptions.FilenameOptions.Filenames[0], "https://") == 0 { + return cmdutil.UsageErrorf(cmd, "--raw cannot read from a url") + } + if o.DeleteOptions.FilenameOptions.Recursive { + return cmdutil.UsageErrorf(cmd, "--raw and --recursive are mutually exclusive") + } + if len(cmdutil.GetFlagString(cmd, "output")) > 0 { + return cmdutil.UsageErrorf(cmd, "--raw and --output are mutually exclusive") + } + if _, err := url.ParseRequestURI(o.Raw); err != nil { + return cmdutil.UsageErrorf(cmd, "--raw must be a valid URL path: %v", err) + } + } + return nil } -func (o *ReplaceOptions) Run() error { +func (o *ReplaceOptions) Run(f cmdutil.Factory) 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 { + restClient, err := f.RESTClient() + if err != nil { + return err + } + return rawhttp.RawPut(restClient, o.IOStreams, o.Raw, o.DeleteOptions.Filenames[0]) + } + if o.DeleteOptions.ForceDeletion { return o.forceReplace() } diff --git a/staging/publishing/import-restrictions.yaml b/staging/publishing/import-restrictions.yaml index 9f210ba350925..0339e38a1ca67 100644 --- a/staging/publishing/import-restrictions.yaml +++ b/staging/publishing/import-restrictions.yaml @@ -128,6 +128,7 @@ allowedImports: - k8s.io/api - k8s.io/apimachinery + - k8s.io/cli-runtime - k8s.io/client-go - k8s.io/kubectl - k8s.io/utils diff --git a/staging/publishing/rules.yaml b/staging/publishing/rules.yaml index b861a36ab6d93..a05ba5657fc41 100644 --- a/staging/publishing/rules.yaml +++ b/staging/publishing/rules.yaml @@ -622,6 +622,8 @@ rules: branch: master - repository: apimachinery branch: master + - repository: cli-runtime + branch: master - repository: client-go branch: master - source: diff --git a/staging/src/k8s.io/client-go/rest/request.go b/staging/src/k8s.io/client-go/rest/request.go index 0bdb0b55f989c..84fb62500bed2 100644 --- a/staging/src/k8s.io/client-go/rest/request.go +++ b/staging/src/k8s.io/client-go/rest/request.go @@ -649,6 +649,9 @@ func (r *Request) Stream() (io.ReadCloser, error) { if err != nil { return nil, err } + if r.body != nil { + req.Body = ioutil.NopCloser(r.body) + } if r.ctx != nil { req = req.WithContext(r.ctx) } diff --git a/staging/src/k8s.io/kubectl/BUILD b/staging/src/k8s.io/kubectl/BUILD index 00ad4ffc7faf9..69c319f05059d 100644 --- a/staging/src/k8s.io/kubectl/BUILD +++ b/staging/src/k8s.io/kubectl/BUILD @@ -9,6 +9,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//staging/src/k8s.io/kubectl/pkg/rawhttp:all-srcs", "//staging/src/k8s.io/kubectl/pkg/util/certificate:all-srcs", "//staging/src/k8s.io/kubectl/pkg/util/deployment:all-srcs", "//staging/src/k8s.io/kubectl/pkg/util/event:all-srcs", diff --git a/staging/src/k8s.io/kubectl/go.mod b/staging/src/k8s.io/kubectl/go.mod index 5448f877aebcc..fa7c44031dad6 100644 --- a/staging/src/k8s.io/kubectl/go.mod +++ b/staging/src/k8s.io/kubectl/go.mod @@ -11,7 +11,6 @@ require ( github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de github.com/mitchellh/go-wordwrap v1.0.0 - github.com/pkg/errors v0.8.0 // indirect github.com/russross/blackfriday v1.5.2 github.com/sirupsen/logrus v1.4.2 // indirect github.com/spf13/cobra v0.0.4 @@ -20,6 +19,7 @@ require ( gotest.tools v2.2.0+incompatible // indirect k8s.io/api v0.0.0 k8s.io/apimachinery v0.0.0 + k8s.io/cli-runtime v0.0.0 k8s.io/client-go v0.0.0 k8s.io/klog v0.3.1 k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a @@ -34,6 +34,7 @@ replace ( golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9 k8s.io/api => ../api k8s.io/apimachinery => ../apimachinery + k8s.io/cli-runtime => ../cli-runtime k8s.io/client-go => ../client-go k8s.io/kubectl => ../kubectl ) diff --git a/staging/src/k8s.io/kubectl/go.sum b/staging/src/k8s.io/kubectl/go.sum index 2f03774020c36..59eb5b27b21cc 100644 --- a/staging/src/k8s.io/kubectl/go.sum +++ b/staging/src/k8s.io/kubectl/go.sum @@ -5,6 +5,10 @@ github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -20,27 +24,46 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QL github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 h1:bRzFpEzvausOAt4va+I/22BZ1vXDtERngp0BNYDKej0= +github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20160524151835-7d79101e329e h1:JHB7F/4TJCrYBW8+GZO8VkWDj1jxcWuCl6uxKODiyi4= github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -51,11 +74,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -66,9 +92,12 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -89,6 +118,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -116,9 +146,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= @@ -128,8 +160,11 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30 h1:TRb4wNWoBVrH9plmkp2q86FIDppkbrEXdXlxU3a3BMI= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a h1:2jUDc9gJja832Ftp+QbDV0tVhQHMISFn01els+2ZAcw= k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= +sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/staging/src/k8s.io/kubectl/pkg/rawhttp/BUILD b/staging/src/k8s.io/kubectl/pkg/rawhttp/BUILD new file mode 100644 index 0000000000000..85dd4c3701dbe --- /dev/null +++ b/staging/src/k8s.io/kubectl/pkg/rawhttp/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["raw.go"], + importmap = "k8s.io/kubernetes/vendor/k8s.io/kubectl/pkg/rawhttp", + importpath = "k8s.io/kubectl/pkg/rawhttp", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library", + "//staging/src/k8s.io/client-go/rest:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/staging/src/k8s.io/kubectl/pkg/rawhttp/raw.go b/staging/src/k8s.io/kubectl/pkg/rawhttp/raw.go new file mode 100644 index 0000000000000..9bd366f7a5c23 --- /dev/null +++ b/staging/src/k8s.io/kubectl/pkg/rawhttp/raw.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rawhttp + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/rest" +) + +// RawPost uses the REST client to POST content +func RawPost(restClient *rest.RESTClient, streams genericclioptions.IOStreams, url, filename string) error { + return raw(restClient, streams, url, filename, "POST") +} + +// RawPut uses the REST client to PUT content +func RawPut(restClient *rest.RESTClient, streams genericclioptions.IOStreams, url, filename string) error { + return raw(restClient, streams, url, filename, "PUT") +} + +// RawGet uses the REST client to GET content +func RawGet(restClient *rest.RESTClient, streams genericclioptions.IOStreams, url string) error { + return raw(restClient, streams, url, "", "GET") +} + +// RawDelete uses the REST client to DELETE content +func RawDelete(restClient *rest.RESTClient, streams genericclioptions.IOStreams, url, filename string) error { + return raw(restClient, streams, url, filename, "DELETE") +} + +// raw makes a simple HTTP request to the provided path on the server using the default credentials. +func raw(restClient *rest.RESTClient, streams genericclioptions.IOStreams, url, filename, requestType string) error { + var data io.ReadCloser + switch { + case len(filename) == 0: + data = ioutil.NopCloser(bytes.NewBuffer([]byte{})) + + case filename == "-": + data = ioutil.NopCloser(streams.In) + + default: + var err error + data, err = os.Open(filename) + if err != nil { + return err + } + } + + var request *rest.Request + switch requestType { + case "GET": + request = restClient.Get().RequestURI(url) + case "PUT": + request = restClient.Put().RequestURI(url).Body(data) + case "POST": + request = restClient.Post().RequestURI(url).Body(data) + case "DELETE": + request = restClient.Delete().RequestURI(url).Body(data) + + default: + return fmt.Errorf("unknown requestType: %q", requestType) + } + + stream, err := request.Stream() + if err != nil { + return err + } + defer stream.Close() + + _, err = io.Copy(streams.Out, stream) + if err != nil && err != io.EOF { + return err + } + return nil +} diff --git a/test/cmd/core.sh b/test/cmd/core.sh index 40ab6643243d3..6235a5314867c 100755 --- a/test/cmd/core.sh +++ b/test/cmd/core.sh @@ -687,8 +687,20 @@ run_create_secret_tests() { # Post-condition: jsonpath for .metadata.namespace should be empty for object since --namespace was not explicitly specified kube::test::if_empty_string "${output_message}" - kubectl create configmap tester-create-cm -o json --dry-run | kubectl create "${kube_flags[@]}" --raw /api/v1/namespaces/default/configmaps -f - - kubectl delete -ndefault "${kube_flags[@]}" configmap tester-create-cm + + # check to make sure that replace correctly PUTs to a URL + kubectl create configmap tester-update-cm -o json --dry-run | kubectl create "${kube_flags[@]}" --raw /api/v1/namespaces/default/configmaps -f - + output_message=$(kubectl create configmap tester-update-cm --from-literal=key1=config1 -o json --dry-run | kubectl replace "${kube_flags[@]}" --raw /api/v1/namespaces/default/configmaps/tester-update-cm -f -) + # the message should show the body returned which will include a UID not present in the input + kube::test::if_has_string "${output_message}" 'uid' + # if the PUT was well-formed, the server will now have a key and value we can retrieve on GET + output_message=$(kubectl get "${kube_flags[@]}" --raw /api/v1/namespaces/default/configmaps/tester-update-cm 2>&1 "${kube_flags[@]}") + kube::test::if_has_string "${output_message}" 'config1' + + # if DELETE raw works correctly, this will delete the configmap + kubectl delete "${kube_flags[@]}" --raw /api/v1/namespaces/default/configmaps/tester-update-cm + output_message=$(! kubectl get "${kube_flags[@]}" configmap tester-update-cm 2>&1 "${kube_flags[@]}") + kube::test::if_has_string "${output_message}" 'configmaps "tester-update-cm" not found' set +o nounset set +o errexit diff --git a/vendor/modules.txt b/vendor/modules.txt index 060f47e2704c8..0a1ffe0c53639 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1637,6 +1637,7 @@ k8s.io/kube-proxy/config/v1alpha1 # k8s.io/kube-scheduler v0.0.0 => ./staging/src/k8s.io/kube-scheduler k8s.io/kube-scheduler/config/v1alpha1 # k8s.io/kubectl v0.0.0 => ./staging/src/k8s.io/kubectl +k8s.io/kubectl/pkg/rawhttp k8s.io/kubectl/pkg/util/certificate k8s.io/kubectl/pkg/util/deployment k8s.io/kubectl/pkg/util/event