vendor updates

This commit is contained in:
Serguei Bezverkhi
2018-03-06 17:33:18 -05:00
parent 4b3ebc171b
commit e9033989a0
5854 changed files with 248382 additions and 119809 deletions

View File

@ -54,19 +54,18 @@ go_test(
],
data = [
"//examples:config",
"//test/e2e/testing-manifests:all-srcs",
"//test/fixtures",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/set",
library = ":go_default_library",
embed = [":go_default_library"],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//pkg/printers:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/api/apps/v1:go_default_library",

View File

@ -34,7 +34,8 @@ var (
func NewCmdSet(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "set SUBCOMMAND",
Use: "set SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Set specific features on objects"),
Long: set_long,
Run: cmdutil.DefaultSubCommandRun(err),

View File

@ -26,7 +26,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
@ -116,15 +115,12 @@ type EnvOptions struct {
From string
Prefix string
Mapper meta.RESTMapper
Builder *resource.Builder
Infos []*resource.Info
Encoder runtime.Encoder
Cmd *cobra.Command
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
}
// NewCmdEnv implements the OpenShift cli env command
@ -135,7 +131,8 @@ func NewCmdEnv(f cmdutil.Factory, in io.Reader, out, errout io.Writer) *cobra.Co
In: in,
}
cmd := &cobra.Command{
Use: "env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N",
Use: "env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N",
DisableFlagsInUseLine: true,
Short: "Update environment variables on a pod template",
Long: envLong,
Example: fmt.Sprintf(envExample),
@ -153,7 +150,7 @@ func NewCmdEnv(f cmdutil.Factory, in io.Reader, out, errout io.Writer) *cobra.Co
cmd.Flags().BoolVar(&options.List, "list", options.List, "If true, display the environment and any changes in the standard format. this flag will removed when we have kubectl view env.")
cmd.Flags().BoolVar(&options.Resolve, "resolve", options.Resolve, "If true, show secret or configmap references when listing variables")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set env will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set env will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.All, "all", options.All, "If true, select all resources in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.Overwrite, "overwrite", true, "If true, allow environment to be overwritten, otherwise reject updates that overwrite existing environment.")
@ -177,6 +174,9 @@ func keyToEnvName(key string) string {
}
func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
resources, envArgs, ok := envutil.SplitEnvironmentFromResources(args)
if !ok {
return cmdutil.UsageErrorf(o.Cmd, "all resources must be specified before environment changes: %s", strings.Join(args, " "))
@ -185,9 +185,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
return cmdutil.UsageErrorf(cmd, "one or more resources must be specified as <resource> <name> or <resource>/<name>")
}
o.Mapper, _ = f.Object()
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
o.ContainerSelector = cmdutil.GetFlagString(cmd, "containers")
o.List = cmdutil.GetFlagBool(cmd, "list")
o.Resolve = cmdutil.GetFlagBool(cmd, "resolve")
@ -198,7 +196,6 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
o.From = cmdutil.GetFlagString(cmd, "from")
o.Prefix = cmdutil.GetFlagString(cmd, "prefix")
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.PrintObject = f.PrintObject
o.EnvArgs = envArgs
o.Resources = resources
@ -321,7 +318,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
if err != nil {
return err
}
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) ([]byte, error) {
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
info.Object = info.AsVersioned()
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
resolutionErrorsEncountered := false
@ -389,7 +386,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
})
if err == nil {
return runtime.Encode(o.Encoder, info.Object)
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
}
return nil, err
})
@ -412,8 +409,8 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
continue
}
if o.PrintObject != nil && (o.Local || o.DryRun) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if o.Local || o.DryRun {
if err := cmdutil.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -433,13 +430,13 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
}
if len(o.Output) > 0 {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := cmdutil.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue
}
f.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, false, "env updated")
cmdutil.PrintSuccess(o.ShortOutput, o.Out, info.Object, false, "env updated")
}
return utilerrors.NewAggregate(allErrs)
}

View File

@ -38,16 +38,16 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
)
func TestSetEnvLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -57,34 +57,34 @@ func TestSetEnvLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdEnv(f, os.Stdin, buf, buf)
cmd := NewCmdEnv(tf, os.Stdin, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := EnvOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../examples/storage/cassandra/cassandra-controller.yaml"}},
Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}},
Out: buf,
Local: true}
err := opts.Complete(f, cmd, []string{"env=prod"})
err := opts.Complete(tf, cmd, []string{"env=prod"})
if err == nil {
err = opts.RunEnv(f)
err = opts.RunEnv(tf)
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(buf.String(), "replicationcontrollers/cassandra") {
if !strings.Contains(buf.String(), "replicationcontroller/cassandra") {
t.Errorf("did not set env: %s", buf.String())
}
}
func TestSetMultiResourcesEnvLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -94,29 +94,27 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdEnv(f, os.Stdin, buf, buf)
cmd := NewCmdEnv(tf, os.Stdin, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := EnvOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}},
Out: buf,
Local: true}
err := opts.Complete(f, cmd, []string{"env=prod"})
err := opts.Complete(tf, cmd, []string{"env=prod"})
if err == nil {
err = opts.RunEnv(f)
err = opts.RunEnv(tf)
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expectedOut := "replicationcontrollers/first-rc\nreplicationcontrollers/second-rc\n"
expectedOut := "replicationcontroller/first-rc\nreplicationcontroller/second-rc\n"
if buf.String() != expectedOut {
t.Errorf("expected out:\n%s\nbut got:\n%s", expectedOut, buf.String())
}
@ -433,11 +431,10 @@ func TestSetEnvRemote(t *testing.T) {
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
@ -465,15 +462,15 @@ func TestSetEnvRemote(t *testing.T) {
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdEnv(f, out, out, out)
cmd := NewCmdEnv(tf, out, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := EnvOptions{
Out: out,
Local: false}
err := opts.Complete(f, cmd, input.args)
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.RunEnv(f)
err = opts.RunEnv(tf)
assert.NoError(t, err)
}
}

View File

@ -22,7 +22,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -37,10 +36,7 @@ import (
type ImageOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Infos []*resource.Info
Encoder runtime.Encoder
Decoder runtime.Decoder
Selector string
Out io.Writer
Err io.Writer
@ -54,8 +50,6 @@ type ImageOptions struct {
Cmd *cobra.Command
ResolveImage func(in string) (string, error)
PrintSuccess func(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
Resources []string
ContainerImages map[string]string
@ -92,7 +86,8 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N",
Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N",
DisableFlagsInUseLine: true,
Short: i18n.T("Update image of a pod template"),
Long: image_long,
Example: image_example,
@ -106,9 +101,9 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
cmdutil.AddPrinterFlags(cmd)
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().BoolVar(&options.All, "all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set image will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set image will NOT contact api-server but run locally.")
cmdutil.AddRecordFlag(cmd)
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
@ -116,16 +111,10 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Mapper, _ = f.Object()
o.PrintSuccess = f.PrintSuccess
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
o.Decoder = f.Decoder(true)
o.ShortOutput = cmdutil.GetFlagString(cmd, "output") == "name"
o.Record = cmdutil.GetRecordFlag(cmd)
o.ChangeCause = f.Command(cmd, false)
o.PrintObject = f.PrintObject
o.Local = cmdutil.GetFlagBool(cmd, "local")
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.Output = cmdutil.GetFlagString(cmd, "output")
o.ResolveImage = f.ResolveImage
@ -174,6 +163,9 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
func (o *ImageOptions) Validate() error {
errors := []error{}
if o.All && len(o.Selector) > 0 {
errors = append(errors, fmt.Errorf("cannot set --all and --selector at the same time"))
}
if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
errors = append(errors, fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>"))
}
@ -188,7 +180,7 @@ func (o *ImageOptions) Validate() error {
func (o *ImageOptions) Run() error {
allErrs := []error{}
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) ([]byte, error) {
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
transformed := false
info.Object = info.AsVersioned()
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
@ -228,7 +220,7 @@ func (o *ImageOptions) Run() error {
return nil
})
if transformed && err == nil {
return runtime.Encode(o.Encoder, info.Object)
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
}
return nil, err
})
@ -245,8 +237,8 @@ func (o *ImageOptions) Run() error {
continue
}
if o.PrintObject != nil && (o.Local || o.DryRun) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if o.Local || o.DryRun {
if err := cmdutil.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -272,12 +264,12 @@ func (o *ImageOptions) Run() error {
info.Refresh(obj, true)
if len(o.Output) > 0 {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := cmdutil.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue
}
o.PrintSuccess(o.Mapper, o.ShortOutput, o.Out, info.Mapping.Resource, info.Name, o.DryRun, "image updated")
cmdutil.PrintSuccess(o.ShortOutput, o.Out, info.Object, o.DryRun, "image updated")
}
return utilerrors.NewAggregate(allErrs)
}

View File

@ -37,16 +37,17 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
)
func TestImageLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -56,21 +57,19 @@ func TestImageLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdImage(f, buf, buf)
cmd := NewCmdImage(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := ImageOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../examples/storage/cassandra/cassandra-controller.yaml"}},
Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}},
Out: buf,
Local: true}
err := opts.Complete(f, cmd, []string{"cassandra=thingy"})
err := opts.Complete(tf, cmd, []string{"cassandra=thingy"})
if err == nil {
err = opts.Validate()
}
@ -80,7 +79,7 @@ func TestImageLocal(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(buf.String(), "replicationcontrollers/cassandra") {
if !strings.Contains(buf.String(), "replicationcontroller/cassandra") {
t.Errorf("did not set image: %s", buf.String())
}
}
@ -122,7 +121,7 @@ func TestSetImageValidation(t *testing.T) {
expectErr: "all containers are already specified by *, but saw more than one container_name=container_image pairs",
},
{
name: "sucess case",
name: "success case",
imageOptions: &ImageOptions{
Resources: []string{"a", "b", "c"},
FilenameOptions: resource.FilenameOptions{
@ -149,7 +148,9 @@ func TestSetImageValidation(t *testing.T) {
}
func TestSetMultiResourcesImageLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -159,21 +160,19 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdImage(f, buf, buf)
cmd := NewCmdImage(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := ImageOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}},
Out: buf,
Local: true}
err := opts.Complete(f, cmd, []string{"*=thingy"})
err := opts.Complete(tf, cmd, []string{"*=thingy"})
if err == nil {
err = opts.Validate()
}
@ -183,7 +182,7 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expectedOut := "replicationcontrollers/first-rc\nreplicationcontrollers/second-rc\n"
expectedOut := "replicationcontroller/first-rc\nreplicationcontroller/second-rc\n"
if buf.String() != expectedOut {
t.Errorf("expected out:\n%s\nbut got:\n%s", expectedOut, buf.String())
}
@ -500,11 +499,10 @@ func TestSetImageRemote(t *testing.T) {
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
@ -532,13 +530,13 @@ func TestSetImageRemote(t *testing.T) {
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdImage(f, out, out)
cmd := NewCmdImage(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
opts := ImageOptions{
Out: out,
Local: false}
err := opts.Complete(f, cmd, input.args)
err := opts.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = opts.Run()
assert.NoError(t, err)

View File

@ -23,7 +23,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
@ -62,9 +61,7 @@ var (
type ResourcesOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Infos []*resource.Info
Encoder runtime.Encoder
Out io.Writer
Err io.Writer
Selector string
@ -80,8 +77,6 @@ type ResourcesOptions struct {
Requests string
ResourceRequirements v1.ResourceRequirements
PrintSuccess func(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
Resources []string
}
@ -98,7 +93,8 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
}
cmd := &cobra.Command{
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update resource requests/limits on objects with pod templates"),
Long: fmt.Sprintf(resources_long, strings.Join(resourceTypesWithPodTemplate, ", ")),
Example: resources_example,
@ -114,10 +110,10 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
//kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().BoolVar(&options.All, "all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones,supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().StringVarP(&options.ContainerSelector, "containers", "c", "*", "The names of containers in the selected pod templates to change, all containers are selected by default - may use wildcards")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set resources will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set resources will NOT contact api-server but run locally.")
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
@ -127,15 +123,10 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
}
func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Mapper, _ = f.Object()
o.PrintSuccess = f.PrintSuccess
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
o.Output = cmdutil.GetFlagString(cmd, "output")
o.Record = cmdutil.GetRecordFlag(cmd)
o.Local = cmdutil.GetFlagBool(cmd, "local")
o.ChangeCause = f.Command(cmd, false)
o.PrintObject = f.PrintObject
o.Cmd = cmd
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
@ -177,6 +168,9 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
func (o *ResourcesOptions) Validate() error {
var err error
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if len(o.Limits) == 0 && len(o.Requests) == 0 {
return fmt.Errorf("you must specify an update to requests or limits (in the form of --requests/--limits)")
}
@ -191,7 +185,7 @@ func (o *ResourcesOptions) Validate() error {
func (o *ResourcesOptions) Run() error {
allErrs := []error{}
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) ([]byte, error) {
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
transformed := false
info.Object = info.AsVersioned()
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
@ -219,7 +213,7 @@ func (o *ResourcesOptions) Run() error {
return nil
})
if transformed && err == nil {
return runtime.Encode(o.Encoder, info.Object)
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
}
return nil, err
})
@ -238,7 +232,7 @@ func (o *ResourcesOptions) Run() error {
}
if o.Local || cmdutil.GetDryRunFlag(o.Cmd) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if err := cmdutil.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -263,12 +257,12 @@ func (o *ResourcesOptions) Run() error {
shortOutput := o.Output == "name"
if len(o.Output) > 0 && !shortOutput {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := cmdutil.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue
}
o.PrintSuccess(o.Mapper, shortOutput, o.Out, info.Mapping.Resource, info.Name, false, "resource requirements updated")
cmdutil.PrintSuccess(shortOutput, o.Out, info.Object, false, "resource requirements updated")
}
return utilerrors.NewAggregate(allErrs)
}

View File

@ -37,16 +37,17 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
)
func TestResourcesLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -56,25 +57,23 @@ func TestResourcesLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdResources(f, buf, buf)
cmd := NewCmdResources(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := ResourcesOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../examples/storage/cassandra/cassandra-controller.yaml"}},
Filenames: []string{"../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}},
Out: buf,
Local: true,
Limits: "cpu=200m,memory=512Mi",
Requests: "cpu=200m,memory=512Mi",
ContainerSelector: "*"}
err := opts.Complete(f, cmd, []string{})
err := opts.Complete(tf, cmd, []string{})
if err == nil {
err = opts.Validate()
}
@ -84,13 +83,15 @@ func TestResourcesLocal(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(buf.String(), "replicationcontrollers/cassandra") {
if !strings.Contains(buf.String(), "replicationcontroller/cassandra") {
t.Errorf("did not set resources: %s", buf.String())
}
}
func TestSetMultiResourcesLimitsLocal(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -100,15 +101,13 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdResources(f, buf, buf)
cmd := NewCmdResources(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := ResourcesOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}},
@ -118,7 +117,7 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
Requests: "cpu=200m,memory=512Mi",
ContainerSelector: "*"}
err := opts.Complete(f, cmd, []string{})
err := opts.Complete(tf, cmd, []string{})
if err == nil {
err = opts.Validate()
}
@ -128,7 +127,7 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expectedOut := "replicationcontrollers/first-rc\nreplicationcontrollers/second-rc\n"
expectedOut := "replicationcontroller/first-rc\nreplicationcontroller/second-rc\n"
if buf.String() != expectedOut {
t.Errorf("expected out:\n%s\nbut got:\n%s", expectedOut, buf.String())
}
@ -446,12 +445,10 @@ func TestSetResourcesRemote(t *testing.T) {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{testapi.Default.Codec()}, Typer: typer, Mapper: mapper}
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
@ -479,15 +476,14 @@ func TestSetResourcesRemote(t *testing.T) {
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
buf := new(bytes.Buffer)
cmd := NewCmdResources(f, buf, buf)
cmd := NewCmdResources(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "yaml")
opts := ResourcesOptions{
Out: buf,
Local: true,
Limits: "cpu=200m,memory=512Mi",
ContainerSelector: "*"}
err := opts.Complete(f, cmd, input.args)
err := opts.Complete(tf, cmd, input.args)
if err == nil {
err = opts.Validate()
}

View File

@ -49,13 +49,11 @@ type SelectorOptions struct {
selector *metav1.LabelSelector
out io.Writer
PrintSuccess func(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
PrintObject func(obj runtime.Object) error
ClientForMapping func(mapping *meta.RESTMapping) (resource.RESTClient, error)
builder *resource.Builder
mapper meta.RESTMapper
encoder runtime.Encoder
}
var (
@ -79,7 +77,8 @@ func NewCmdSelector(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]",
Use: "selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]",
DisableFlagsInUseLine: true,
Short: i18n.T("Set the selector on a resource"),
Long: fmt.Sprintf(selectorLong, validation.LabelValueMaxLength),
Example: selectorExample,
@ -115,12 +114,9 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
return err
}
o.PrintSuccess = f.PrintSuccess
o.changeCause = f.Command(cmd, false)
mapper, _ := f.Object()
o.mapper = mapper
o.encoder = f.JSONEncoder()
o.resources, o.selector, err = getResourcesAndSelector(args)
if err != nil {
@ -151,7 +147,7 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
}
o.PrintObject = func(obj runtime.Object) error {
return f.PrintObject(cmd, o.local, mapper, obj, o.out)
return cmdutil.PrintObject(cmd, obj, o.out)
}
o.ClientForMapping = func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.ClientForMapping(mapping)
@ -180,13 +176,13 @@ func (o *SelectorOptions) RunSelector() error {
return r.Visit(func(info *resource.Info, err error) error {
patch := &Patch{Info: info}
CalculatePatch(patch, o.encoder, func(info *resource.Info) ([]byte, error) {
CalculatePatch(patch, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
versioned := info.AsVersioned()
patch.Info.Object = versioned
selectErr := updateSelectorForObject(info.Object, *o.selector)
if selectErr == nil {
return runtime.Encode(o.encoder, info.Object)
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
}
return nil, selectErr
})
@ -217,7 +213,7 @@ func (o *SelectorOptions) RunSelector() error {
if len(o.output) > 0 && !shortOutput {
return o.PrintObject(patched)
}
o.PrintSuccess(o.mapper, shortOutput, o.out, info.Mapping.Resource, info.Name, o.dryrun, "selector updated")
cmdutil.PrintSuccess(shortOutput, o.out, info.Object, o.dryrun, "selector updated")
return nil
})
}

View File

@ -32,8 +32,8 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/printers"
)
func TestUpdateSelectorForObjectTypes(t *testing.T) {
@ -316,7 +316,8 @@ func TestGetResourcesAndSelector(t *testing.T) {
}
func TestSelectorTest(t *testing.T) {
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -326,20 +327,18 @@ func TestSelectorTest(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdSelector(f, buf)
cmd := NewCmdSelector(tf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
cmd.Flags().Set("filename", "../../../../examples/storage/cassandra/cassandra-service.yaml")
cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/statefulset/cassandra/service.yaml")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
cmd.Run(cmd, []string{"environment=qa"})
if !strings.Contains(buf.String(), "services/cassandra") {
if !strings.Contains(buf.String(), "service/cassandra") {
t.Errorf("did not set selector: %s", buf.String())
}
}

View File

@ -24,7 +24,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -56,8 +55,6 @@ var (
// serviceAccountConfig encapsulates the data required to perform the operation.
type serviceAccountConfig struct {
fileNameOptions resource.FilenameOptions
mapper meta.RESTMapper
encoder runtime.Encoder
out io.Writer
err io.Writer
dryRun bool
@ -68,9 +65,7 @@ type serviceAccountConfig struct {
output string
changeCause string
local bool
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
updatePodSpecForObject func(runtime.Object, func(*v1.PodSpec) error) (bool, error)
printSuccess func(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
infos []*resource.Info
serviceAccountName string
}
@ -83,11 +78,12 @@ func NewCmdServiceAccount(f cmdutil.Factory, out, err io.Writer) *cobra.Command
}
cmd := &cobra.Command{
Use: "serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT",
Aliases: []string{"sa"},
Short: i18n.T("Update ServiceAccount of a resource"),
Long: serviceaccountLong,
Example: serviceaccountExample,
Use: "serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT",
DisableFlagsInUseLine: true,
Aliases: []string{"sa"},
Short: i18n.T("Update ServiceAccount of a resource"),
Long: serviceaccountLong,
Example: serviceaccountExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(saConfig.Complete(f, cmd, args))
cmdutil.CheckErr(saConfig.Run())
@ -107,18 +103,14 @@ func NewCmdServiceAccount(f cmdutil.Factory, out, err io.Writer) *cobra.Command
// Complete configures serviceAccountConfig from command line args.
func (saConfig *serviceAccountConfig) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
saConfig.mapper, _ = f.Object()
saConfig.encoder = f.JSONEncoder()
saConfig.shortOutput = cmdutil.GetFlagString(cmd, "output") == "name"
saConfig.record = cmdutil.GetRecordFlag(cmd)
saConfig.changeCause = f.Command(cmd, false)
saConfig.dryRun = cmdutil.GetDryRunFlag(cmd)
saConfig.output = cmdutil.GetFlagString(cmd, "output")
saConfig.updatePodSpecForObject = f.UpdatePodSpecForObject
saConfig.PrintObject = f.PrintObject
saConfig.cmd = cmd
saConfig.printSuccess = f.PrintSuccess
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
@ -157,9 +149,9 @@ func (saConfig *serviceAccountConfig) Run() error {
podSpec.ServiceAccountName = saConfig.serviceAccountName
return nil
})
return runtime.Encode(saConfig.encoder, info.Object)
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
}
patches := CalculatePatches(saConfig.infos, saConfig.encoder, patchFn)
patches := CalculatePatches(saConfig.infos, cmdutil.InternalVersionJSONEncoder(), patchFn)
for _, patch := range patches {
info := patch.Info
if patch.Err != nil {
@ -167,7 +159,7 @@ func (saConfig *serviceAccountConfig) Run() error {
continue
}
if saConfig.local || saConfig.dryRun {
if err := saConfig.PrintObject(saConfig.cmd, saConfig.local, saConfig.mapper, patch.Info.AsVersioned(), saConfig.out); err != nil {
if err := cmdutil.PrintObject(saConfig.cmd, patch.Info.AsVersioned(), saConfig.out); err != nil {
return err
}
continue
@ -186,12 +178,12 @@ func (saConfig *serviceAccountConfig) Run() error {
}
}
if len(saConfig.output) > 0 {
if err := saConfig.PrintObject(saConfig.cmd, saConfig.local, saConfig.mapper, info.AsVersioned(), saConfig.out); err != nil {
if err := cmdutil.PrintObject(saConfig.cmd, info.AsVersioned(), saConfig.out); err != nil {
return err
}
continue
}
saConfig.printSuccess(saConfig.mapper, saConfig.shortOutput, saConfig.out, info.Mapping.Resource, info.Name, saConfig.dryRun, "serviceaccount updated")
cmdutil.PrintSuccess(saConfig.shortOutput, saConfig.out, info.Object, saConfig.dryRun, "serviceaccount updated")
}
return utilerrors.NewAggregate(patchErrs)
}

View File

@ -37,12 +37,11 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
)
const serviceAccount = "serviceaccount1"
@ -68,7 +67,7 @@ func TestSetServiceAccountLocal(t *testing.T) {
for i, input := range inputs {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
f, tf, _, _ := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -78,17 +77,16 @@ func TestSetServiceAccountLocal(t *testing.T) {
}
tf.Namespace = "test"
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(f, out, out)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("local", "true")
testapi.Default = testapi.Groups[input.apiGroup]
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
saConfig := serviceAccountConfig{fileNameOptions: resource.FilenameOptions{
Filenames: []string{input.yaml}},
out: out,
local: true}
err := saConfig.Complete(f, cmd, []string{serviceAccount})
err := saConfig.Complete(tf, cmd, []string{serviceAccount})
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
@ -99,7 +97,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
func TestSetServiceAccountMultiLocal(t *testing.T) {
testapi.Default = testapi.Groups[""]
f, tf, codec, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: ""},
NegotiatedSerializer: ns,
@ -109,28 +108,26 @@ func TestSetServiceAccountMultiLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(f, buf, buf)
cmd := NewCmdServiceAccount(tf, buf, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("local", "true")
mapper, typer := f.Object()
tf.Printer = &printers.NamePrinter{Decoders: []runtime.Decoder{codec}, Typer: typer, Mapper: mapper}
opts := serviceAccountConfig{fileNameOptions: resource.FilenameOptions{
Filenames: []string{"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"}},
out: buf,
local: true}
err := opts.Complete(f, cmd, []string{serviceAccount})
err := opts.Complete(tf, cmd, []string{serviceAccount})
if err == nil {
err = opts.Run()
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expectedOut := "replicationcontrollers/first-rc\nreplicationcontrollers/second-rc\n"
expectedOut := "replicationcontroller/first-rc\nreplicationcontroller/second-rc\n"
if buf.String() != expectedOut {
t.Errorf("expected out:\n%s\nbut got:\n%s", expectedOut, buf.String())
}
@ -315,11 +312,10 @@ func TestSetServiceAccountRemote(t *testing.T) {
for _, input := range inputs {
groupVersion := schema.GroupVersion{Group: input.apiGroup, Version: input.apiVersion}
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
ns := legacyscheme.Codecs
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{
GroupVersion: groupVersion,
NegotiatedSerializer: ns,
@ -347,13 +343,13 @@ func TestSetServiceAccountRemote(t *testing.T) {
VersionedAPIPath: path.Join(input.apiPrefix, testapi.Default.GroupVersion().String()),
}
out := new(bytes.Buffer)
cmd := NewCmdServiceAccount(f, out, out)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
cmd.Flags().Set("output", "yaml")
saConfig := serviceAccountConfig{
out: out,
local: false}
err := saConfig.Complete(f, cmd, input.args)
err := saConfig.Complete(tf, cmd, input.args)
assert.NoError(t, err)
err = saConfig.Run()
assert.NoError(t, err)
@ -369,7 +365,7 @@ func TestServiceAccountValidation(t *testing.T) {
{args: []string{serviceAccount}, errorString: resourceMissingErrString},
}
for _, input := range inputs {
f, tf, _, _ := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
@ -379,11 +375,11 @@ func TestServiceAccountValidation(t *testing.T) {
}
tf.Namespace = "test"
out := bytes.NewBuffer([]byte{})
cmd := NewCmdServiceAccount(f, out, out)
cmd := NewCmdServiceAccount(tf, out, out)
cmd.SetOutput(out)
saConfig := &serviceAccountConfig{}
err := saConfig.Complete(f, cmd, input.args)
err := saConfig.Complete(tf, cmd, input.args)
assert.EqualError(t, err, input.errorString)
}
}

View File

@ -23,7 +23,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -57,10 +56,7 @@ type updateSubjects func(existings []rbac.Subject, targets []rbac.Subject) (bool
type SubjectOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
Infos []*resource.Info
Encoder runtime.Encoder
Out io.Writer
Err io.Writer
Selector string
@ -74,7 +70,7 @@ type SubjectOptions struct {
Groups []string
ServiceAccounts []string
PrintObject func(mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(obj runtime.Object, out io.Writer) error
}
func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
@ -84,7 +80,8 @@ func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
}
cmd := &cobra.Command{
Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding"),
Long: subject_long,
Example: subject_example,
@ -98,9 +95,9 @@ func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
cmdutil.AddPrinterFlags(cmd)
usage := "the resource to update the subjects"
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().BoolVar(&options.All, "all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set subject will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set subject will NOT contact api-server but run locally.")
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringArrayVar(&options.Users, "user", []string{}, "Usernames to bind to the role")
cmd.Flags().StringArrayVar(&options.Groups, "group", []string{}, "Groups to bind to the role")
@ -110,13 +107,10 @@ func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
}
func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Local = cmdutil.GetFlagBool(cmd, "local")
o.Mapper, o.Typer = f.Object()
o.Encoder = f.JSONEncoder()
o.Output = cmdutil.GetFlagString(cmd, "output")
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.PrintObject = func(mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
return f.PrintObject(cmd, o.Local, mapper, obj, out)
o.PrintObject = func(obj runtime.Object, out io.Writer) error {
return cmdutil.PrintObject(cmd, obj, out)
}
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
@ -157,6 +151,9 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
}
func (o *SubjectOptions) Validate() error {
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if len(o.Users) == 0 && len(o.Groups) == 0 && len(o.ServiceAccounts) == 0 {
return fmt.Errorf("you must specify at least one value of user, group or serviceaccount")
}
@ -180,7 +177,7 @@ func (o *SubjectOptions) Validate() error {
func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
var err error
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) ([]byte, error) {
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
subjects := []rbac.Subject{}
for _, user := range sets.NewString(o.Users...).List() {
subject := rbac.Subject{
@ -219,7 +216,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
transformed, err := updateSubjectForObject(info.Object, subjects, fn)
if transformed && err == nil {
// TODO: switch UpdatePodSpecForObject to work on v1.PodSpec
return runtime.Encode(o.Encoder, info.AsVersioned())
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.AsVersioned())
}
return nil, err
})
@ -239,7 +236,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
}
if o.Local || o.DryRun {
if err := o.PrintObject(o.Mapper, info.Object, o.Out); err != nil {
if err := o.PrintObject(info.Object, o.Out); err != nil {
return err
}
continue
@ -254,9 +251,9 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
shortOutput := o.Output == "name"
if len(o.Output) > 0 && !shortOutput {
return o.PrintObject(o.Mapper, info.AsVersioned(), o.Out)
return o.PrintObject(info.AsVersioned(), o.Out)
}
f.PrintSuccess(o.Mapper, shortOutput, o.Out, info.Mapping.Resource, info.Name, false, "subjects updated")
cmdutil.PrintSuccess(shortOutput, o.Out, info.Object, false, "subjects updated")
}
return utilerrors.NewAggregate(allErrs)
}

View File

@ -28,7 +28,7 @@ import (
)
func TestValidate(t *testing.T) {
f, tf, _, _ := cmdtesting.NewAPIFactory()
tf := cmdtesting.NewTestFactory()
tf.Namespace = "test"
tests := map[string]struct {
@ -107,7 +107,6 @@ func TestValidate(t *testing.T) {
}
for name, test := range tests {
test.options.Mapper, _ = f.Object()
err := test.options.Validate()
if test.expectErr && err != nil {
continue