mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 15:37:24 +00:00
allow kubectl subcmds to process multiple resources
- use resource.Visit() to recursively process resources, as well as, aggregate errors where possible
This commit is contained in:
@@ -23,7 +23,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/util/errors"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -97,18 +97,10 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
ResourceTypeOrNameArgs(false, args...).
|
||||
Flatten().
|
||||
Do()
|
||||
infos, err := r.Infos()
|
||||
err = r.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(infos) > 1 {
|
||||
return fmt.Errorf("multiple resources provided: %v", args)
|
||||
}
|
||||
info := infos[0]
|
||||
mapping := info.ResourceMapping()
|
||||
if err := f.CanBeAutoscaled(mapping.GroupVersionKind.GroupKind()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the generator, setup and validate all required parameters
|
||||
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
||||
@@ -118,62 +110,84 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("generator %q not found.", generatorName))
|
||||
}
|
||||
names := generator.ParamNames()
|
||||
params := kubectl.MakeParams(cmd, names)
|
||||
name := info.Name
|
||||
params["default-name"] = name
|
||||
|
||||
params["scaleRef-kind"] = mapping.GroupVersionKind.Kind
|
||||
params["scaleRef-name"] = name
|
||||
params["scaleRef-apiVersion"] = mapping.GroupVersionKind.GroupVersion().String()
|
||||
|
||||
if err = kubectl.ValidateParams(names, params); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check for invalid flags used against the present generator.
|
||||
if err := kubectl.EnsureFlagsValid(cmd, generators, generatorName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate new object
|
||||
object, err := generator.Generate(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resourceMapper := &resource.Mapper{
|
||||
ObjectTyper: typer,
|
||||
RESTMapper: mapper,
|
||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||
Decoder: f.Decoder(true),
|
||||
}
|
||||
hpa, err := resourceMapper.InfoForObject(object, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, hpa) {
|
||||
if err := cmdutil.RecordChangeCause(hpa.Object, f.Command()); err != nil {
|
||||
count := 0
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
object = hpa.Object
|
||||
}
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa, f.JSONEncoder()); err != nil {
|
||||
return err
|
||||
}
|
||||
mapping := info.ResourceMapping()
|
||||
if err := f.CanBeAutoscaled(mapping.GroupVersionKind.GroupKind()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object, err = resource.NewHelper(hpa.Client, hpa.Mapping).Create(namespace, false, object)
|
||||
name := info.Name
|
||||
params := kubectl.MakeParams(cmd, names)
|
||||
params["default-name"] = name
|
||||
|
||||
params["scaleRef-kind"] = mapping.GroupVersionKind.Kind
|
||||
params["scaleRef-name"] = name
|
||||
params["scaleRef-apiVersion"] = mapping.GroupVersionKind.GroupVersion().String()
|
||||
|
||||
if err = kubectl.ValidateParams(names, params); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check for invalid flags used against the present generator.
|
||||
if err := kubectl.EnsureFlagsValid(cmd, generators, generatorName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate new object
|
||||
object, err := generator.Generate(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resourceMapper := &resource.Mapper{
|
||||
ObjectTyper: typer,
|
||||
RESTMapper: mapper,
|
||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||
Decoder: f.Decoder(true),
|
||||
}
|
||||
hpa, err := resourceMapper.InfoForObject(object, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, hpa) {
|
||||
if err := cmdutil.RecordChangeCause(hpa.Object, f.Command()); err != nil {
|
||||
return err
|
||||
}
|
||||
object = hpa.Object
|
||||
}
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa, f.JSONEncoder()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object, err = resource.NewHelper(hpa.Client, hpa.Mapping).Create(namespace, false, object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count++
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "autoscaled")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
if count == 0 {
|
||||
return fmt.Errorf("no objects passed to autoscale")
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "autoscaled")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -186,5 +200,5 @@ func validateFlags(cmd *cobra.Command) error {
|
||||
if cpu > 100 {
|
||||
errs = append(errs, fmt.Errorf("CPU utilization (%%) cannot exceed 100"))
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
@@ -154,15 +154,32 @@ func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.
|
||||
|
||||
// RunConvert implements the generic Convert command
|
||||
func (o *ConvertOptions) RunConvert() error {
|
||||
infos, err := o.builder.Do().Infos()
|
||||
r := o.builder.Do()
|
||||
err := r.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objects, err := resource.AsVersionedObject(infos, false, o.outputVersion.String(), o.encoder)
|
||||
count := 0
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
infos := []*resource.Info{info}
|
||||
objects, err := resource.AsVersionedObject(infos, false, o.outputVersion.String(), o.encoder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count++
|
||||
return o.printer.PrintObj(objects, o.out)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return o.printer.PrintObj(objects, o.out)
|
||||
if count == 0 {
|
||||
return fmt.Errorf("no objects passed to convert")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -140,20 +140,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
ResourceTypeOrNameArgs(false, args...).
|
||||
Flatten().
|
||||
Do()
|
||||
infos, err := r.Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(infos) > 1 {
|
||||
return fmt.Errorf("multiple resources provided: %v", args)
|
||||
}
|
||||
info := infos[0]
|
||||
mapping := info.ResourceMapping()
|
||||
if err := f.CanBeExposed(mapping.GroupVersionKind.GroupKind()); err != nil {
|
||||
return err
|
||||
}
|
||||
// Get the input object
|
||||
inputObject, err := r.Object()
|
||||
err = r.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -166,101 +153,118 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("generator %q not found.", generatorName))
|
||||
}
|
||||
names := generator.ParamNames()
|
||||
params := kubectl.MakeParams(cmd, names)
|
||||
name := info.Name
|
||||
if len(name) > validation.DNS952LabelMaxLength {
|
||||
name = name[:validation.DNS952LabelMaxLength]
|
||||
}
|
||||
params["default-name"] = name
|
||||
|
||||
// For objects that need a pod selector, derive it from the exposed object in case a user
|
||||
// didn't explicitly specify one via --selector
|
||||
if s, found := params["selector"]; found && kubectl.IsZero(s) {
|
||||
s, err := f.MapBasedSelectorForObject(inputObject)
|
||||
if err != nil {
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't retrieve selectors via --selector flag or introspection: %s", err))
|
||||
}
|
||||
params["selector"] = s
|
||||
}
|
||||
|
||||
// For objects that need a port, derive it from the exposed object in case a user
|
||||
// didn't explicitly specify one via --port
|
||||
if port, found := params["port"]; found && kubectl.IsZero(port) {
|
||||
ports, err := f.PortsForObject(inputObject)
|
||||
if err != nil {
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find port via --port flag or introspection: %s", err))
|
||||
}
|
||||
switch len(ports) {
|
||||
case 0:
|
||||
return cmdutil.UsageError(cmd, "couldn't find port via --port flag or introspection")
|
||||
case 1:
|
||||
params["port"] = ports[0]
|
||||
default:
|
||||
params["ports"] = strings.Join(ports, ",")
|
||||
}
|
||||
}
|
||||
if kubectl.IsZero(params["labels"]) {
|
||||
labels, err := f.LabelsForObject(inputObject)
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params["labels"] = kubectl.MakeLabels(labels)
|
||||
}
|
||||
if err = kubectl.ValidateParams(names, params); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check for invalid flags used against the present generator.
|
||||
if err := kubectl.EnsureFlagsValid(cmd, generators, generatorName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate new object
|
||||
object, err := generator.Generate(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mapping := info.ResourceMapping()
|
||||
if err := f.CanBeExposed(mapping.GroupVersionKind.GroupKind()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if inline := cmdutil.GetFlagString(cmd, "overrides"); len(inline) > 0 {
|
||||
codec := runtime.NewCodec(f.JSONEncoder(), f.Decoder(true))
|
||||
object, err = cmdutil.Merge(codec, object, inline, mapping.GroupVersionKind.Kind)
|
||||
params := kubectl.MakeParams(cmd, names)
|
||||
name := info.Name
|
||||
if len(name) > validation.DNS952LabelMaxLength {
|
||||
name = name[:validation.DNS952LabelMaxLength]
|
||||
}
|
||||
params["default-name"] = name
|
||||
|
||||
// For objects that need a pod selector, derive it from the exposed object in case a user
|
||||
// didn't explicitly specify one via --selector
|
||||
if s, found := params["selector"]; found && kubectl.IsZero(s) {
|
||||
s, err := f.MapBasedSelectorForObject(info.Object)
|
||||
if err != nil {
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't retrieve selectors via --selector flag or introspection: %s", err))
|
||||
}
|
||||
params["selector"] = s
|
||||
}
|
||||
|
||||
// For objects that need a port, derive it from the exposed object in case a user
|
||||
// didn't explicitly specify one via --port
|
||||
if port, found := params["port"]; found && kubectl.IsZero(port) {
|
||||
ports, err := f.PortsForObject(info.Object)
|
||||
if err != nil {
|
||||
return cmdutil.UsageError(cmd, fmt.Sprintf("couldn't find port via --port flag or introspection: %s", err))
|
||||
}
|
||||
switch len(ports) {
|
||||
case 0:
|
||||
return cmdutil.UsageError(cmd, "couldn't find port via --port flag or introspection")
|
||||
case 1:
|
||||
params["port"] = ports[0]
|
||||
default:
|
||||
params["ports"] = strings.Join(ports, ",")
|
||||
}
|
||||
}
|
||||
if kubectl.IsZero(params["labels"]) {
|
||||
labels, err := f.LabelsForObject(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params["labels"] = kubectl.MakeLabels(labels)
|
||||
}
|
||||
if err = kubectl.ValidateParams(names, params); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check for invalid flags used against the present generator.
|
||||
if err := kubectl.EnsureFlagsValid(cmd, generators, generatorName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate new object
|
||||
object, err := generator.Generate(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
resourceMapper := &resource.Mapper{
|
||||
ObjectTyper: typer,
|
||||
RESTMapper: mapper,
|
||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||
Decoder: f.Decoder(true),
|
||||
}
|
||||
info, err = resourceMapper.InfoForObject(object, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, info) {
|
||||
if err := cmdutil.RecordChangeCause(object, f.Command()); err != nil {
|
||||
if inline := cmdutil.GetFlagString(cmd, "overrides"); len(inline) > 0 {
|
||||
codec := runtime.NewCodec(f.JSONEncoder(), f.Decoder(true))
|
||||
object, err = cmdutil.Merge(codec, object, inline, mapping.GroupVersionKind.Kind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
resourceMapper := &resource.Mapper{
|
||||
ObjectTyper: typer,
|
||||
RESTMapper: mapper,
|
||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||
Decoder: f.Decoder(true),
|
||||
}
|
||||
info, err = resourceMapper.InfoForObject(object, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, info) {
|
||||
if err := cmdutil.RecordChangeCause(object, f.Command()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
info.Refresh(object, true)
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
info.Refresh(object, true)
|
||||
// TODO: extract this flag to a central location, when such a location exists.
|
||||
if cmdutil.GetFlagBool(cmd, "dry-run") {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serialize the object with the annotation applied.
|
||||
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, object)
|
||||
// Serialize the object with the annotation applied.
|
||||
object, err = resource.NewHelper(info.Client, info.Mapping).Create(namespace, false, object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "exposed")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return f.PrintObject(cmd, mapper, object, out)
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, "exposed")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
@@ -197,19 +198,39 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
||||
return nil
|
||||
}
|
||||
|
||||
b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
|
||||
FilenameParam(enforceNamespace, options.Recursive, options.Filenames...).
|
||||
SelectorParam(selector).
|
||||
ExportParam(export).
|
||||
ResourceTypeOrNameArgs(true, args...).
|
||||
ContinueOnError().
|
||||
Latest()
|
||||
Latest().
|
||||
Flatten().
|
||||
Do()
|
||||
err = r.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printer, generic, err := cmdutil.PrinterForCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
infos := []*resource.Info{}
|
||||
allErrs := []error{}
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
infos = append(infos, info)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
|
||||
if generic {
|
||||
clientConfig, err := f.ClientConfig()
|
||||
if err != nil {
|
||||
@@ -217,11 +238,7 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
||||
}
|
||||
|
||||
singular := false
|
||||
r := b.Flatten().Do()
|
||||
infos, err := r.IntoSingular(&singular).Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.IntoSingular(&singular)
|
||||
|
||||
// the outermost object will be converted to the output-version, but inner
|
||||
// objects can use their mappings
|
||||
@@ -237,10 +254,6 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
||||
return printer.PrintObj(obj, out)
|
||||
}
|
||||
|
||||
infos, err := b.Flatten().Do().Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
objs := make([]runtime.Object, len(infos))
|
||||
for ix := range infos {
|
||||
objs[ix] = infos[ix].Object
|
||||
@@ -262,7 +275,8 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
||||
for ix := range infos {
|
||||
objs[ix], err = infos[ix].Mapping.ConvertToVersion(infos[ix].Object, version.String())
|
||||
if err != nil {
|
||||
return err
|
||||
allErrs = append(allErrs, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,19 +305,21 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
||||
if printer == nil || lastMapping == nil || mapping == nil || mapping.Resource != lastMapping.Resource {
|
||||
printer, err = f.PrinterForMapping(cmd, mapping, allNamespaces)
|
||||
if err != nil {
|
||||
return err
|
||||
allErrs = append(allErrs, err)
|
||||
continue
|
||||
}
|
||||
lastMapping = mapping
|
||||
}
|
||||
if _, found := printer.(*kubectl.HumanReadablePrinter); found {
|
||||
if err := printer.PrintObj(original, w); err != nil {
|
||||
return err
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := printer.PrintObj(original, w); err != nil {
|
||||
return err
|
||||
allErrs = append(allErrs, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return utilerrors.NewAggregate(allErrs)
|
||||
}
|
||||
|
||||
@@ -137,35 +137,41 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
return err
|
||||
}
|
||||
|
||||
infos, err := r.Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(infos) > 1 {
|
||||
return fmt.Errorf("multiple resources provided")
|
||||
}
|
||||
info := infos[0]
|
||||
name, namespace := info.Name, info.Namespace
|
||||
mapping := info.ResourceMapping()
|
||||
client, err := f.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
helper := resource.NewHelper(client, mapping)
|
||||
patchedObject, err := helper.Patch(namespace, name, patchType, patchBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, info) {
|
||||
if err := cmdutil.RecordChangeCause(patchedObject, f.Command()); err == nil {
|
||||
// don't return an error on failure. The patch itself succeeded, its only the hint for that change that failed
|
||||
// don't bother checking for failures of this replace, because a failure to indicate the hint doesn't fail the command
|
||||
// also, don't force the replacement. If the replacement fails on a resourceVersion conflict, then it means this
|
||||
// record hint is likely to be invalid anyway, so avoid the bad hint
|
||||
resource.NewHelper(client, mapping).Replace(namespace, name, false, patchedObject)
|
||||
count := 0
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name, namespace := info.Name, info.Namespace
|
||||
mapping := info.ResourceMapping()
|
||||
client, err := f.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
helper := resource.NewHelper(client, mapping)
|
||||
patchedObject, err := helper.Patch(namespace, name, patchType, patchBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, info) {
|
||||
if err := cmdutil.RecordChangeCause(patchedObject, f.Command()); err == nil {
|
||||
// don't return an error on failure. The patch itself succeeded, its only the hint for that change that failed
|
||||
// don't bother checking for failures of this replace, because a failure to indicate the hint doesn't fail the command
|
||||
// also, don't force the replacement. If the replacement fails on a resourceVersion conflict, then it means this
|
||||
// record hint is likely to be invalid anyway, so avoid the bad hint
|
||||
resource.NewHelper(client, mapping).Replace(namespace, name, false, patchedObject)
|
||||
}
|
||||
}
|
||||
count++
|
||||
cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
return fmt.Errorf("no objects passed to patch")
|
||||
}
|
||||
cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
)
|
||||
|
||||
// ScaleOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||
@@ -122,43 +121,47 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
return err
|
||||
}
|
||||
|
||||
infos, err := r.Infos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info := infos[0]
|
||||
mapping := info.ResourceMapping()
|
||||
scaler, err := f.Scaler(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
infos := []*resource.Info{}
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err == nil {
|
||||
infos = append(infos, info)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
resourceVersion := cmdutil.GetFlagString(cmd, "resource-version")
|
||||
if len(resourceVersion) != 0 && len(infos) > 1 {
|
||||
return fmt.Errorf("cannot use --resource-version with multiple resources")
|
||||
}
|
||||
currentSize := cmdutil.GetFlagInt(cmd, "current-replicas")
|
||||
if currentSize != -1 && len(infos) > 1 {
|
||||
return fmt.Errorf("cannot use --current-replicas with multiple resources")
|
||||
}
|
||||
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: resourceVersion}
|
||||
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
|
||||
var waitForReplicas *kubectl.RetryParams
|
||||
if timeout := cmdutil.GetFlagDuration(cmd, "timeout"); timeout != 0 {
|
||||
waitForReplicas = kubectl.NewRetryParams(kubectl.Interval, timeout)
|
||||
}
|
||||
|
||||
errs := []error{}
|
||||
for _, info := range infos {
|
||||
counter := 0
|
||||
err = r.Visit(func(info *resource.Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapping := info.ResourceMapping()
|
||||
scaler, err := f.Scaler(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currentSize := cmdutil.GetFlagInt(cmd, "current-replicas")
|
||||
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: resourceVersion}
|
||||
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
|
||||
|
||||
var waitForReplicas *kubectl.RetryParams
|
||||
if timeout := cmdutil.GetFlagDuration(cmd, "timeout"); timeout != 0 {
|
||||
waitForReplicas = kubectl.NewRetryParams(kubectl.Interval, timeout)
|
||||
}
|
||||
|
||||
if err := scaler.Scale(info.Namespace, info.Name, uint(count), precondition, retry, waitForReplicas); err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
if cmdutil.ShouldRecord(cmd, info) {
|
||||
patchBytes, err := cmdutil.ChangeResourcePatch(info, f.Command())
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
mapping := info.ResourceMapping()
|
||||
client, err := f.ClientForMapping(mapping)
|
||||
@@ -168,12 +171,18 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
|
||||
helper := resource.NewHelper(client, mapping)
|
||||
_, err = helper.Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patchBytes)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
}
|
||||
counter++
|
||||
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "scaled")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errs)
|
||||
if counter == 0 {
|
||||
return fmt.Errorf("no objects passed to scale")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user