use recordFlags

This commit is contained in:
David Eads
2018-04-19 08:32:15 -04:00
parent b1357da473
commit 484d81ab01
18 changed files with 318 additions and 237 deletions

View File

@@ -26,12 +26,14 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@@ -60,10 +62,11 @@ var (
// ResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags
type ResourcesOptions struct {
type SetResourcesOptions struct {
resource.FilenameOptions
PrintFlags *printers.PrintFlags
PrintFlags *printers.PrintFlags
RecordFlags *genericclioptions.RecordFlags
Infos []*resource.Info
Out io.Writer
@@ -72,7 +75,6 @@ type ResourcesOptions struct {
ContainerSelector string
Output string
All bool
Record bool
ChangeCause string
Local bool
Cmd *cobra.Command
@@ -80,6 +82,7 @@ type ResourcesOptions struct {
DryRun bool
PrintObj printers.ResourcePrinterFunc
Recorder genericclioptions.Recorder
Limits string
Requests string
@@ -91,9 +94,12 @@ type ResourcesOptions struct {
// NewResourcesOptions returns a ResourcesOptions indicating all containers in the selected
// pod templates are selected by default.
func NewResourcesOptions(out io.Writer, errOut io.Writer) *ResourcesOptions {
return &ResourcesOptions{
PrintFlags: printers.NewPrintFlags("resource requirements updated"),
func NewResourcesOptions(out io.Writer, errOut io.Writer) *SetResourcesOptions {
return &SetResourcesOptions{
PrintFlags: printers.NewPrintFlags("resource requirements updated"),
RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{},
Out: out,
Err: errOut,
@@ -102,7 +108,7 @@ func NewResourcesOptions(out io.Writer, errOut io.Writer) *ResourcesOptions {
}
func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := NewResourcesOptions(out, errOut)
o := NewResourcesOptions(out, errOut)
resourceTypesWithPodTemplate := []string{}
for _, resource := range f.SuggestedPodTemplateResources() {
@@ -116,34 +122,41 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
Long: fmt.Sprintf(resources_long, strings.Join(resourceTypesWithPodTemplate, ", ")),
Example: resources_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args))
cmdutil.CheckErr(options.Validate())
cmdutil.CheckErr(options.Run())
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
}
options.PrintFlags.AddFlags(cmd)
o.PrintFlags.AddFlags(cmd)
o.RecordFlags.AddFlags(cmd)
//usage := "Filename, directory, or URL to a file identifying the resource to get from the server"
//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", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "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", options.ContainerSelector, "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", options.Local, "If true, set resources will NOT contact api-server but run locally.")
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
cmd.Flags().BoolVar(&o.All, "all", o.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, not including uninitialized ones,supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().StringVarP(&o.ContainerSelector, "containers", "c", o.ContainerSelector, "The names of containers in the selected pod templates to change, all containers are selected by default - may use wildcards")
cmd.Flags().BoolVar(&o.Local, "local", o.Local, "If true, set resources will NOT contact api-server but run locally.")
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
cmd.Flags().StringVar(&options.Limits, "limits", options.Limits, "The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.")
cmd.Flags().StringVar(&options.Requests, "requests", options.Requests, "The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.")
cmd.Flags().StringVar(&o.Limits, "limits", o.Limits, "The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.")
cmd.Flags().StringVar(&o.Requests, "requests", o.Requests, "The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.")
return cmd
}
func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error
o.RecordFlags.Complete(f.Command(cmd, false))
o.Recorder, err = o.RecordFlags.ToRecorder()
if err != nil {
return err
}
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Output = cmdutil.GetFlagString(cmd, "output")
o.Record = cmdutil.GetRecordFlag(cmd)
o.ChangeCause = f.Command(cmd, false)
o.Cmd = cmd
o.DryRun = cmdutil.GetDryRunFlag(o.Cmd)
@@ -194,7 +207,7 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
return nil
}
func (o *ResourcesOptions) Validate() error {
func (o *SetResourcesOptions) Validate() error {
var err error
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
@@ -211,7 +224,7 @@ func (o *ResourcesOptions) Validate() error {
return nil
}
func (o *ResourcesOptions) Run() error {
func (o *SetResourcesOptions) Run() error {
allErrs := []error{}
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
transformed := false
@@ -240,10 +253,18 @@ func (o *ResourcesOptions) Run() error {
}
return nil
})
if transformed && err == nil {
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
if err != nil {
return nil, err
}
return nil, err
if !transformed {
return nil, nil
}
// record this change (for rollout history)
if err := o.Recorder.Record(info.Object); err != nil {
glog.V(4).Infof("error recording current command: %v", err)
}
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
})
for _, patch := range patches {
@@ -273,16 +294,6 @@ func (o *ResourcesOptions) Run() error {
}
info.Refresh(obj, true)
//record this change (for rollout history)
if o.Record || cmdutil.ContainsChangeCause(info) {
if err := cmdutil.RecordChangeCause(obj, o.ChangeCause); err == nil {
if obj, err = resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, obj); err != nil {
allErrs = append(allErrs, fmt.Errorf("changes to %s/%s can't be recorded: %v\n", info.Mapping.Resource, info.Name, err))
}
}
}
info.Refresh(obj, true)
if err := o.PrintObj(info.AsVersioned(), o.Out); err != nil {
return err
}