mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Merge pull request #62794 from deads2k/cli-27-recordflags
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. fix up and use record flags This pull starts a genericclioptions package with a dependency enforcer to ensure that we have no kube/kube links. It makes the recordflags nil-able and still behave as expected. And it also updates several commands to use the record flags. @kubernetes/sig-cli-maintainers @soltysh @juanvallejo ```release-note NONE ```
This commit is contained in:
commit
b9ed99604d
@ -17,6 +17,10 @@
|
|||||||
ignoredSubTrees:
|
ignoredSubTrees:
|
||||||
- "./pkg/apis/core/validation"
|
- "./pkg/apis/core/validation"
|
||||||
|
|
||||||
|
- baseImportPath: "./pkg/kubectl/genericclioptions/"
|
||||||
|
allowedImports:
|
||||||
|
- k8s.io/apimachinery
|
||||||
|
|
||||||
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
||||||
allowedImports:
|
allowedImports:
|
||||||
- k8s.io/apimachinery
|
- k8s.io/apimachinery
|
||||||
|
@ -206,6 +206,7 @@ filegroup(
|
|||||||
"//pkg/kubectl/categories:all-srcs",
|
"//pkg/kubectl/categories:all-srcs",
|
||||||
"//pkg/kubectl/cmd:all-srcs",
|
"//pkg/kubectl/cmd:all-srcs",
|
||||||
"//pkg/kubectl/explain:all-srcs",
|
"//pkg/kubectl/explain:all-srcs",
|
||||||
|
"//pkg/kubectl/genericclioptions:all-srcs",
|
||||||
"//pkg/kubectl/metricsutil:all-srcs",
|
"//pkg/kubectl/metricsutil:all-srcs",
|
||||||
"//pkg/kubectl/plugins:all-srcs",
|
"//pkg/kubectl/plugins:all-srcs",
|
||||||
"//pkg/kubectl/proxy:all-srcs",
|
"//pkg/kubectl/proxy:all-srcs",
|
||||||
|
@ -41,7 +41,6 @@ go_library(
|
|||||||
"plugin.go",
|
"plugin.go",
|
||||||
"portforward.go",
|
"portforward.go",
|
||||||
"proxy.go",
|
"proxy.go",
|
||||||
"record_flags.go",
|
|
||||||
"replace.go",
|
"replace.go",
|
||||||
"rollingupdate.go",
|
"rollingupdate.go",
|
||||||
"run.go",
|
"run.go",
|
||||||
@ -79,6 +78,7 @@ go_library(
|
|||||||
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||||
"//pkg/kubectl/explain:go_default_library",
|
"//pkg/kubectl/explain:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/metricsutil:go_default_library",
|
"//pkg/kubectl/metricsutil:go_default_library",
|
||||||
"//pkg/kubectl/plugins:go_default_library",
|
"//pkg/kubectl/plugins:go_default_library",
|
||||||
"//pkg/kubectl/proxy:go_default_library",
|
"//pkg/kubectl/proxy:go_default_library",
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
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/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -42,21 +43,22 @@ import (
|
|||||||
type AnnotateOptions struct {
|
type AnnotateOptions struct {
|
||||||
// Filename options
|
// Filename options
|
||||||
resource.FilenameOptions
|
resource.FilenameOptions
|
||||||
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
|
|
||||||
// Common user flags
|
// Common user flags
|
||||||
overwrite bool
|
overwrite bool
|
||||||
local bool
|
local bool
|
||||||
dryrun bool
|
dryrun bool
|
||||||
all bool
|
all bool
|
||||||
resourceVersion string
|
resourceVersion string
|
||||||
selector string
|
selector string
|
||||||
outputFormat string
|
outputFormat string
|
||||||
recordChangeCause bool
|
|
||||||
|
|
||||||
// results of arg parsing
|
// results of arg parsing
|
||||||
resources []string
|
resources []string
|
||||||
newAnnotations map[string]string
|
newAnnotations map[string]string
|
||||||
removeAnnotations []string
|
removeAnnotations []string
|
||||||
|
Recorder genericclioptions.Recorder
|
||||||
|
|
||||||
// Common share fields
|
// Common share fields
|
||||||
out io.Writer
|
out io.Writer
|
||||||
@ -97,8 +99,15 @@ var (
|
|||||||
kubectl annotate pods foo description-`))
|
kubectl annotate pods foo description-`))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewAnnotateOptions(out io.Writer) *AnnotateOptions {
|
||||||
|
return &AnnotateOptions{
|
||||||
|
out: out,
|
||||||
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
options := &AnnotateOptions{}
|
options := NewAnnotateOptions(out)
|
||||||
validArgs := cmdutil.ValidArgList(f)
|
validArgs := cmdutil.ValidArgList(f)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -108,7 +117,7 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
Long: annotateLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
|
Long: annotateLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
|
||||||
Example: annotateExample,
|
Example: annotateExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := options.Complete(out, cmd, args); err != nil {
|
if err := options.Complete(f, cmd, args); err != nil {
|
||||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
@ -119,6 +128,10 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: kubectl.ResourceAliases(validArgs),
|
ArgAliases: kubectl.ResourceAliases(validArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind flag structs
|
||||||
|
options.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
cmdutil.AddPrinterFlags(cmd)
|
||||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||||
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
|
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
|
||||||
@ -129,18 +142,23 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
usage := "identifying the resource to update the annotation"
|
usage := "identifying the resource to update the annotation"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmdutil.AddRecordFlag(cmd)
|
|
||||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete adapts from the command line args and factory to the data required.
|
// Complete adapts from the command line args and factory to the data required.
|
||||||
func (o *AnnotateOptions) Complete(out io.Writer, cmd *cobra.Command, args []string) (err error) {
|
func (o *AnnotateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
o.out = out
|
o.RecordFlags.Complete(f.Command(cmd, false))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
o.outputFormat = cmdutil.GetFlagString(cmd, "output")
|
o.outputFormat = cmdutil.GetFlagString(cmd, "output")
|
||||||
o.dryrun = cmdutil.GetDryRunFlag(cmd)
|
o.dryrun = cmdutil.GetDryRunFlag(cmd)
|
||||||
o.recordChangeCause = cmdutil.GetRecordFlag(cmd)
|
|
||||||
|
|
||||||
// retrieves resource and annotation args from args
|
// retrieves resource and annotation args from args
|
||||||
// also checks args to verify that all resources are specified before annotations
|
// also checks args to verify that all resources are specified before annotations
|
||||||
@ -174,8 +192,6 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCause := f.Command(cmd, false)
|
|
||||||
|
|
||||||
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||||
b := f.NewBuilder().
|
b := f.NewBuilder().
|
||||||
Unstructured().
|
Unstructured().
|
||||||
@ -232,9 +248,8 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If we should record change-cause, add it to new annotations
|
if err := o.Recorder.Record(info.Object); err != nil {
|
||||||
if cmdutil.ContainsChangeCause(info) || o.recordChangeCause {
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
o.newAnnotations[kubectl.ChangeCauseAnnotation] = changeCause
|
|
||||||
}
|
}
|
||||||
if err := o.updateAnnotations(obj); err != nil {
|
if err := o.updateAnnotations(obj); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -431,8 +431,8 @@ func TestAnnotateErrors(t *testing.T) {
|
|||||||
for k, v := range testCase.flags {
|
for k, v := range testCase.flags {
|
||||||
cmd.Flags().Set(k, v)
|
cmd.Flags().Set(k, v)
|
||||||
}
|
}
|
||||||
options := &AnnotateOptions{}
|
options := NewAnnotateOptions(buf)
|
||||||
err := options.Complete(buf, cmd, testCase.args)
|
err := options.Complete(tf, cmd, testCase.args)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = options.Validate()
|
err = options.Validate()
|
||||||
}
|
}
|
||||||
@ -488,9 +488,9 @@ func TestAnnotateObject(t *testing.T) {
|
|||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
cmd := NewCmdAnnotate(tf, buf)
|
cmd := NewCmdAnnotate(tf, buf)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
options := &AnnotateOptions{}
|
options := NewAnnotateOptions(buf)
|
||||||
args := []string{"pods/foo", "a=b", "c-"}
|
args := []string{"pods/foo", "a=b", "c-"}
|
||||||
if err := options.Complete(buf, cmd, args); err != nil {
|
if err := options.Complete(tf, cmd, args); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
@ -542,10 +542,10 @@ func TestAnnotateObjectFromFile(t *testing.T) {
|
|||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
cmd := NewCmdAnnotate(tf, buf)
|
cmd := NewCmdAnnotate(tf, buf)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
options := &AnnotateOptions{}
|
options := NewAnnotateOptions(buf)
|
||||||
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
|
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
|
||||||
args := []string{"a=b", "c-"}
|
args := []string{"a=b", "c-"}
|
||||||
if err := options.Complete(buf, cmd, args); err != nil {
|
if err := options.Complete(tf, cmd, args); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
@ -573,10 +573,11 @@ func TestAnnotateLocal(t *testing.T) {
|
|||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
cmd := NewCmdAnnotate(tf, buf)
|
cmd := NewCmdAnnotate(tf, buf)
|
||||||
options := &AnnotateOptions{local: true}
|
options := NewAnnotateOptions(buf)
|
||||||
|
options.local = true
|
||||||
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
|
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
|
||||||
args := []string{"a=b"}
|
args := []string{"a=b"}
|
||||||
if err := options.Complete(buf, cmd, args); err != nil {
|
if err := options.Complete(tf, cmd, args); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
@ -629,9 +630,10 @@ func TestAnnotateMultipleObjects(t *testing.T) {
|
|||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
cmd := NewCmdAnnotate(tf, buf)
|
cmd := NewCmdAnnotate(tf, buf)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
options := &AnnotateOptions{all: true}
|
options := NewAnnotateOptions(buf)
|
||||||
|
options.all = true
|
||||||
args := []string{"pods", "a=b", "c-"}
|
args := []string{"pods", "a=b", "c-"}
|
||||||
if err := options.Complete(buf, cmd, args); err != nil {
|
if err := options.Complete(tf, cmd, args); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
|
@ -45,16 +45,17 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ApplyOptions struct {
|
type ApplyOptions struct {
|
||||||
RecordFlags *RecordFlags
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
FilenameOptions resource.FilenameOptions
|
FilenameOptions resource.FilenameOptions
|
||||||
|
|
||||||
Recorder Recorder
|
Recorder genericclioptions.Recorder
|
||||||
|
|
||||||
Selector string
|
Selector string
|
||||||
Force bool
|
Force bool
|
||||||
@ -111,7 +112,7 @@ var (
|
|||||||
|
|
||||||
func NewApplyOptions(out, errout io.Writer) *ApplyOptions {
|
func NewApplyOptions(out, errout io.Writer) *ApplyOptions {
|
||||||
return &ApplyOptions{
|
return &ApplyOptions{
|
||||||
RecordFlags: NewRecordFlags(),
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
|
||||||
Overwrite: true,
|
Overwrite: true,
|
||||||
Cascade: true,
|
Cascade: true,
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -59,11 +58,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||||
options := &editor.EditOptions{
|
o := editor.NewEditOptions(editor.ApplyEditMode, out, errOut)
|
||||||
EditMode: editor.ApplyEditMode,
|
|
||||||
Output: "yaml",
|
|
||||||
WindowsLineEndings: runtime.GOOS == "windows",
|
|
||||||
}
|
|
||||||
validArgs := cmdutil.ValidArgList(f)
|
validArgs := cmdutil.ValidArgList(f)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -73,11 +69,10 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra
|
|||||||
Long: applyEditLastAppliedLong,
|
Long: applyEditLastAppliedLong,
|
||||||
Example: applyEditLastAppliedExample,
|
Example: applyEditLastAppliedExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
options.ChangeCause = f.Command(cmd, false)
|
if err := o.Complete(f, args, cmd); err != nil {
|
||||||
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Run(); err != nil {
|
if err := o.Run(); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -85,12 +80,14 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra
|
|||||||
ArgAliases: kubectl.ResourceAliases(validArgs),
|
ArgAliases: kubectl.ResourceAliases(validArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind flag structs
|
||||||
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
usage := "to use to edit the resource"
|
usage := "to use to edit the resource"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmd.Flags().StringVarP(&options.Output, "output", "o", options.Output, "Output format. One of: yaml|json.")
|
cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "Output format. One of: yaml|json.")
|
||||||
cmd.Flags().BoolVar(&options.WindowsLineEndings, "windows-line-endings", options.WindowsLineEndings,
|
cmd.Flags().BoolVar(&o.WindowsLineEndings, "windows-line-endings", o.WindowsLineEndings,
|
||||||
"Defaults to the line ending native to your platform.")
|
"Defaults to the line ending native to your platform.")
|
||||||
cmdutil.AddRecordVarFlag(cmd, &options.Record)
|
|
||||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -54,8 +54,9 @@ type SetLastAppliedOptions struct {
|
|||||||
Output string
|
Output string
|
||||||
PatchBufferList []PatchBuffer
|
PatchBufferList []PatchBuffer
|
||||||
Factory cmdutil.Factory
|
Factory cmdutil.Factory
|
||||||
Out io.Writer
|
|
||||||
ErrOut io.Writer
|
Out io.Writer
|
||||||
|
ErrOut io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
type PatchBuffer struct {
|
type PatchBuffer struct {
|
||||||
@ -81,8 +82,15 @@ var (
|
|||||||
`))
|
`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdApplySetLastApplied(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
func NewSetLastAppliedOptions(out, errout io.Writer) *SetLastAppliedOptions {
|
||||||
options := &SetLastAppliedOptions{Out: out, ErrOut: err}
|
return &SetLastAppliedOptions{
|
||||||
|
Out: out,
|
||||||
|
ErrOut: errout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdApplySetLastApplied(f cmdutil.Factory, out, errout io.Writer) *cobra.Command {
|
||||||
|
options := NewSetLastAppliedOptions(out, errout)
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "set-last-applied -f FILENAME",
|
Use: "set-last-applied -f FILENAME",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
@ -97,7 +105,6 @@ func NewCmdApplySetLastApplied(f cmdutil.Factory, out, err io.Writer) *cobra.Com
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmdutil.AddRecordFlag(cmd)
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
cmdutil.AddPrinterFlags(cmd)
|
||||||
cmd.Flags().BoolVar(&options.CreateAnnotation, "create-annotation", options.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one")
|
cmd.Flags().BoolVar(&options.CreateAnnotation, "create-annotation", options.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one")
|
||||||
usage := "that contains the last-applied-configuration annotations"
|
usage := "that contains the last-applied-configuration annotations"
|
||||||
@ -111,12 +118,9 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command)
|
|||||||
o.Output = cmdutil.GetFlagString(cmd, "output")
|
o.Output = cmdutil.GetFlagString(cmd, "output")
|
||||||
o.ShortOutput = o.Output == "name"
|
o.ShortOutput = o.Output == "name"
|
||||||
|
|
||||||
var err error
|
|
||||||
o.Mapper, o.Typer = f.Object()
|
o.Mapper, o.Typer = f.Object()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var err error
|
||||||
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,11 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
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/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,8 +47,22 @@ var (
|
|||||||
kubectl autoscale rc foo --max=5 --cpu-percent=80`))
|
kubectl autoscale rc foo --max=5 --cpu-percent=80`))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AutoscaleOptions struct {
|
||||||
|
FilenameOptions resource.FilenameOptions
|
||||||
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
|
|
||||||
|
Recorder genericclioptions.Recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAutoscaleOptions() *AutoscaleOptions {
|
||||||
|
return &AutoscaleOptions{
|
||||||
|
FilenameOptions: resource.FilenameOptions{},
|
||||||
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewCmdAutoscale(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdAutoscale(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
options := &resource.FilenameOptions{}
|
o := NewAutoscaleOptions()
|
||||||
|
|
||||||
validArgs := []string{"deployment", "replicaset", "replicationcontroller"}
|
validArgs := []string{"deployment", "replicaset", "replicationcontroller"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
@ -58,12 +74,16 @@ func NewCmdAutoscale(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
Long: autoscaleLong,
|
Long: autoscaleLong,
|
||||||
Example: autoscaleExample,
|
Example: autoscaleExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunAutoscale(f, out, cmd, args, options)
|
cmdutil.CheckErr(o.Complete(f, cmd))
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(o.RunAutoscale(f, out, cmd, args))
|
||||||
},
|
},
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: argAliases,
|
ArgAliases: argAliases,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind flag structs
|
||||||
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
cmdutil.AddPrinterFlags(cmd)
|
||||||
cmd.Flags().String("generator", cmdutil.HorizontalPodAutoscalerV1GeneratorName, i18n.T("The name of the API generator to use. Currently there is only 1 generator."))
|
cmd.Flags().String("generator", cmdutil.HorizontalPodAutoscalerV1GeneratorName, i18n.T("The name of the API generator to use. Currently there is only 1 generator."))
|
||||||
cmd.Flags().Int32("min", -1, "The lower limit for the number of pods that can be set by the autoscaler. If it's not specified or negative, the server will apply a default value.")
|
cmd.Flags().Int32("min", -1, "The lower limit for the number of pods that can be set by the autoscaler. If it's not specified or negative, the server will apply a default value.")
|
||||||
@ -73,14 +93,25 @@ func NewCmdAutoscale(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
cmd.Flags().String("name", "", i18n.T("The name for the newly created object. If not specified, the name of the input resource will be used."))
|
cmd.Flags().String("name", "", i18n.T("The name for the newly created object. If not specified, the name of the input resource will be used."))
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
usage := "identifying the resource to autoscale."
|
usage := "identifying the resource to autoscale."
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, options, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||||
cmdutil.AddRecordFlag(cmd)
|
|
||||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error {
|
func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
|
o.RecordFlags.Complete(f.Command(cmd, false))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *AutoscaleOptions) RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
||||||
namespace, enforceNamespace, err := f.DefaultNamespace()
|
namespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -95,7 +126,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
|||||||
Internal().
|
Internal().
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(namespace).DefaultNamespace().
|
NamespaceParam(namespace).DefaultNamespace().
|
||||||
FilenameParam(enforceNamespace, options).
|
FilenameParam(enforceNamespace, &o.FilenameOptions).
|
||||||
ResourceTypeOrNameArgs(false, args...).
|
ResourceTypeOrNameArgs(false, args...).
|
||||||
Flatten().
|
Flatten().
|
||||||
Do()
|
Do()
|
||||||
@ -149,11 +180,8 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cmdutil.ShouldRecord(cmd, hpa) {
|
if err := o.Recorder.Record(hpa.Object); err != nil {
|
||||||
if err := cmdutil.RecordChangeCause(hpa.Object, f.Command(cmd, false)); err != nil {
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
object = hpa.Object
|
|
||||||
}
|
}
|
||||||
if cmdutil.GetDryRunFlag(cmd) {
|
if cmdutil.GetDryRunFlag(cmd) {
|
||||||
return cmdutil.PrintObject(cmd, object, out)
|
return cmdutil.PrintObject(cmd, object, out)
|
||||||
|
@ -27,9 +27,11 @@ go_library(
|
|||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
"//pkg/kubectl/cmd/util/editor:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/resource:go_default_library",
|
"//pkg/kubectl/resource:go_default_library",
|
||||||
"//pkg/kubectl/util/i18n:go_default_library",
|
"//pkg/kubectl/util/i18n:go_default_library",
|
||||||
"//pkg/printers:go_default_library",
|
"//pkg/printers:go_default_library",
|
||||||
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
kruntime "k8s.io/apimachinery/pkg/runtime"
|
kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -34,13 +35,14 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateOptions struct {
|
type CreateOptions struct {
|
||||||
PrintFlags *PrintFlags
|
PrintFlags *PrintFlags
|
||||||
PrintObj func(obj kruntime.Object) error
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
|
|
||||||
DryRun bool
|
DryRun bool
|
||||||
|
|
||||||
@ -50,6 +52,9 @@ type CreateOptions struct {
|
|||||||
Raw string
|
Raw string
|
||||||
Out io.Writer
|
Out io.Writer
|
||||||
ErrOut io.Writer
|
ErrOut io.Writer
|
||||||
|
|
||||||
|
Recorder genericclioptions.Recorder
|
||||||
|
PrintObj func(obj kruntime.Object) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -69,13 +74,18 @@ var (
|
|||||||
kubectl create -f docker-registry.yaml --edit -o json`))
|
kubectl create -f docker-registry.yaml --edit -o json`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCreateOptions(out, errOut io.Writer) *CreateOptions {
|
||||||
options := &CreateOptions{
|
return &CreateOptions{
|
||||||
PrintFlags: NewPrintFlags("created"),
|
PrintFlags: NewPrintFlags("created"),
|
||||||
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
|
||||||
Out: out,
|
Out: out,
|
||||||
ErrOut: errOut,
|
ErrOut: errOut,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||||
|
o := NewCreateOptions(out, errOut)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "create -f FILENAME",
|
Use: "create -f FILENAME",
|
||||||
@ -84,32 +94,34 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Long: createLong,
|
Long: createLong,
|
||||||
Example: createExample,
|
Example: createExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if cmdutil.IsFilenameSliceEmpty(options.FilenameOptions.Filenames) {
|
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
||||||
defaultRunFunc := cmdutil.DefaultSubCommandRun(errOut)
|
defaultRunFunc := cmdutil.DefaultSubCommandRun(errOut)
|
||||||
defaultRunFunc(cmd, args)
|
defaultRunFunc(cmd, args)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmdutil.CheckErr(options.Complete(cmd))
|
cmdutil.CheckErr(o.Complete(f, cmd))
|
||||||
cmdutil.CheckErr(options.ValidateArgs(cmd, args))
|
cmdutil.CheckErr(o.ValidateArgs(cmd, args))
|
||||||
cmdutil.CheckErr(options.RunCreate(f, cmd))
|
cmdutil.CheckErr(o.RunCreate(f, cmd))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind flag structs
|
||||||
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
usage := "to use to create the resource"
|
usage := "to use to create the resource"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmd.MarkFlagRequired("filename")
|
cmd.MarkFlagRequired("filename")
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmd.Flags().BoolVar(&options.EditBeforeCreate, "edit", options.EditBeforeCreate, "Edit the API resource before creating")
|
cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating")
|
||||||
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
|
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
|
||||||
"Only relevant if --edit=true. Defaults to the line ending native to your platform.")
|
"Only relevant if --edit=true. Defaults to the line ending native to your platform.")
|
||||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||||
cmdutil.AddRecordFlag(cmd)
|
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||||
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||||
cmd.Flags().StringVar(&options.Raw, "raw", options.Raw, "Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.")
|
cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to POST to the server. Uses the transport specified by the kubeconfig file.")
|
||||||
|
|
||||||
options.PrintFlags.AddFlags(cmd)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
// create subcommands
|
// create subcommands
|
||||||
cmd.AddCommand(NewCmdCreateNamespace(f, out))
|
cmd.AddCommand(NewCmdCreateNamespace(f, out))
|
||||||
@ -160,7 +172,15 @@ func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *CreateOptions) Complete(cmd *cobra.Command) error {
|
func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
|
o.RecordFlags.Complete(f.Command(cmd, false))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
o.DryRun = cmdutil.GetDryRunFlag(cmd)
|
o.DryRun = cmdutil.GetDryRunFlag(cmd)
|
||||||
|
|
||||||
if o.DryRun {
|
if o.DryRun {
|
||||||
@ -186,7 +206,7 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.EditBeforeCreate {
|
if o.EditBeforeCreate {
|
||||||
return RunEditOnCreate(f, o.Out, o.ErrOut, cmd, &o.FilenameOptions)
|
return RunEditOnCreate(f, o.RecordFlags, o.Out, o.ErrOut, cmd, &o.FilenameOptions)
|
||||||
}
|
}
|
||||||
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -221,10 +241,8 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||||||
return cmdutil.AddSourceToErr("creating", info.Source, err)
|
return cmdutil.AddSourceToErr("creating", info.Source, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmdutil.ShouldRecord(cmd, info) {
|
if err := o.Recorder.Record(info.Object); err != nil {
|
||||||
if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil {
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
return cmdutil.AddSourceToErr("creating", info.Source, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !o.DryRun {
|
if !o.DryRun {
|
||||||
@ -273,21 +291,18 @@ func (o *CreateOptions) raw(f cmdutil.Factory) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunEditOnCreate(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, options *resource.FilenameOptions) error {
|
func RunEditOnCreate(f cmdutil.Factory, recordFlags *genericclioptions.RecordFlags, out, errOut io.Writer, cmd *cobra.Command, options *resource.FilenameOptions) error {
|
||||||
editOptions := &editor.EditOptions{
|
editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, out, errOut)
|
||||||
EditMode: editor.EditBeforeCreateMode,
|
editOptions.FilenameOptions = *options
|
||||||
FilenameOptions: *options,
|
editOptions.ValidateOptions = cmdutil.ValidateOptions{
|
||||||
ValidateOptions: cmdutil.ValidateOptions{
|
EnableValidation: cmdutil.GetFlagBool(cmd, "validate"),
|
||||||
EnableValidation: cmdutil.GetFlagBool(cmd, "validate"),
|
|
||||||
},
|
|
||||||
Output: cmdutil.GetFlagString(cmd, "output"),
|
|
||||||
WindowsLineEndings: cmdutil.GetFlagBool(cmd, "windows-line-endings"),
|
|
||||||
ApplyAnnotation: cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag),
|
|
||||||
Record: cmdutil.GetFlagBool(cmd, "record"),
|
|
||||||
ChangeCause: f.Command(cmd, false),
|
|
||||||
Include3rdParty: cmdutil.GetFlagBool(cmd, "include-extended-apis"),
|
|
||||||
}
|
}
|
||||||
err := editOptions.Complete(f, out, errOut, []string{}, cmd)
|
editOptions.Output = cmdutil.GetFlagString(cmd, "output")
|
||||||
|
editOptions.ApplyAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
||||||
|
editOptions.RecordFlags = recordFlags
|
||||||
|
editOptions.Include3rdParty = cmdutil.GetFlagBool(cmd, "include-extended-apis")
|
||||||
|
|
||||||
|
err := editOptions.Complete(f, []string{}, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -70,13 +69,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||||
options := &editor.EditOptions{
|
o := editor.NewEditOptions(editor.NormalEditMode, out, errOut)
|
||||||
EditMode: editor.NormalEditMode,
|
o.ValidateOptions = cmdutil.ValidateOptions{EnableValidation: true}
|
||||||
Output: "yaml",
|
o.Include3rdParty = true
|
||||||
WindowsLineEndings: runtime.GOOS == "windows",
|
|
||||||
ValidateOptions: cmdutil.ValidateOptions{EnableValidation: true},
|
|
||||||
Include3rdParty: true,
|
|
||||||
}
|
|
||||||
validArgs := cmdutil.ValidArgList(f)
|
validArgs := cmdutil.ValidArgList(f)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -86,28 +82,30 @@ func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Long: editLong,
|
Long: editLong,
|
||||||
Example: fmt.Sprintf(editExample),
|
Example: fmt.Sprintf(editExample),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
options.ChangeCause = f.Command(cmd, false)
|
if err := o.Complete(f, args, cmd); err != nil {
|
||||||
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Run(); err != nil {
|
if err := o.Run(); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: kubectl.ResourceAliases(validArgs),
|
ArgAliases: kubectl.ResourceAliases(validArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind flag structs
|
||||||
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
usage := "to use to edit the resource"
|
usage := "to use to edit the resource"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmdutil.AddValidateOptionFlags(cmd, &options.ValidateOptions)
|
cmdutil.AddValidateOptionFlags(cmd, &o.ValidateOptions)
|
||||||
cmd.Flags().StringVarP(&options.Output, "output", "o", options.Output, "Output format. One of: yaml|json.")
|
cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "Output format. One of: yaml|json.")
|
||||||
cmd.Flags().BoolVarP(&options.OutputPatch, "output-patch", "", options.OutputPatch, "Output the patch if the resource is edited.")
|
cmd.Flags().BoolVarP(&o.OutputPatch, "output-patch", "", o.OutputPatch, "Output the patch if the resource is edited.")
|
||||||
cmd.Flags().BoolVar(&options.WindowsLineEndings, "windows-line-endings", options.WindowsLineEndings,
|
cmd.Flags().BoolVar(&o.WindowsLineEndings, "windows-line-endings", o.WindowsLineEndings,
|
||||||
"Defaults to the line ending native to your platform.")
|
"Defaults to the line ending native to your platform.")
|
||||||
|
|
||||||
cmdutil.AddApplyAnnotationVarFlags(cmd, &options.ApplyAnnotation)
|
cmdutil.AddApplyAnnotationVarFlags(cmd, &o.ApplyAnnotation)
|
||||||
cmdutil.AddRecordVarFlag(cmd, &options.Record)
|
cmdutil.AddInclude3rdPartyVarFlags(cmd, &o.Include3rdParty)
|
||||||
cmdutil.AddInclude3rdPartyVarFlags(cmd, &options.Include3rdParty)
|
|
||||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"new-data3": "newivalue"
|
"new-data3": "newivalue"
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"annotations": {
|
|
||||||
"kubernetes.io/change-cause": "edit test cmd invocation"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,5 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"annotations": {
|
|
||||||
"kubernetes.io/change-cause": "edit test cmd invocation"
|
|
||||||
},
|
|
||||||
"labels": {
|
"labels": {
|
||||||
"new-label2": "foo2"
|
"new-label2": "foo2"
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ go_library(
|
|||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/kubectl:go_default_library",
|
"//pkg/kubectl:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/resource:go_default_library",
|
"//pkg/kubectl/resource:go_default_library",
|
||||||
"//pkg/kubectl/scheme:go_default_library",
|
"//pkg/kubectl/scheme:go_default_library",
|
||||||
"//pkg/kubectl/util/crlf:go_default_library",
|
"//pkg/kubectl/util/crlf:go_default_library",
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
goruntime "runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/evanphx/json-patch"
|
"github.com/evanphx/json-patch"
|
||||||
@ -44,6 +45,7 @@ import (
|
|||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
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/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/crlf"
|
"k8s.io/kubernetes/pkg/kubectl/util/crlf"
|
||||||
@ -53,6 +55,7 @@ import (
|
|||||||
// EditOptions contains all the options for running edit cli command.
|
// EditOptions contains all the options for running edit cli command.
|
||||||
type EditOptions struct {
|
type EditOptions struct {
|
||||||
resource.FilenameOptions
|
resource.FilenameOptions
|
||||||
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
|
|
||||||
Output string
|
Output string
|
||||||
OutputPatch bool
|
OutputPatch bool
|
||||||
@ -67,18 +70,32 @@ type EditOptions struct {
|
|||||||
|
|
||||||
CmdNamespace string
|
CmdNamespace string
|
||||||
ApplyAnnotation bool
|
ApplyAnnotation bool
|
||||||
Record bool
|
|
||||||
ChangeCause string
|
ChangeCause string
|
||||||
Include3rdParty bool
|
Include3rdParty bool
|
||||||
|
|
||||||
Out io.Writer
|
Out io.Writer
|
||||||
ErrOut io.Writer
|
ErrOut io.Writer
|
||||||
|
|
||||||
|
Recorder genericclioptions.Recorder
|
||||||
f cmdutil.Factory
|
f cmdutil.Factory
|
||||||
editPrinterOptions *editPrinterOptions
|
editPrinterOptions *editPrinterOptions
|
||||||
updatedResultGetter func(data []byte) *resource.Result
|
updatedResultGetter func(data []byte) *resource.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEditOptions(editMode EditMode, out, errOut io.Writer) *EditOptions {
|
||||||
|
return &EditOptions{
|
||||||
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
|
||||||
|
EditMode: editMode,
|
||||||
|
|
||||||
|
Output: "yaml",
|
||||||
|
WindowsLineEndings: goruntime.GOOS == "windows",
|
||||||
|
|
||||||
|
Out: out,
|
||||||
|
ErrOut: errOut,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type editPrinterOptions struct {
|
type editPrinterOptions struct {
|
||||||
printer printers.ResourcePrinter
|
printer printers.ResourcePrinter
|
||||||
ext string
|
ext string
|
||||||
@ -86,7 +103,15 @@ type editPrinterOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Complete completes all the required options
|
// Complete completes all the required options
|
||||||
func (o *EditOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string, cmd *cobra.Command) error {
|
func (o *EditOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Command) error {
|
||||||
|
o.RecordFlags.Complete(f.Command(cmd, false))
|
||||||
|
|
||||||
|
var err error
|
||||||
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if o.EditMode != NormalEditMode && o.EditMode != EditBeforeCreateMode && o.EditMode != ApplyEditMode {
|
if o.EditMode != NormalEditMode && o.EditMode != EditBeforeCreateMode && o.EditMode != ApplyEditMode {
|
||||||
return fmt.Errorf("unsupported edit mode %q", o.EditMode)
|
return fmt.Errorf("unsupported edit mode %q", o.EditMode)
|
||||||
}
|
}
|
||||||
@ -138,10 +163,6 @@ func (o *EditOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []
|
|||||||
o.CmdNamespace = cmdNamespace
|
o.CmdNamespace = cmdNamespace
|
||||||
o.f = f
|
o.f = f
|
||||||
|
|
||||||
// Set up writer
|
|
||||||
o.Out = out
|
|
||||||
o.ErrOut = errOut
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,10 +630,8 @@ func (o *EditOptions) visitAnnotation(annotationVisitor resource.Visitor) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if o.Record || cmdutil.ContainsChangeCause(info) {
|
if err := o.Recorder.Record(info.Object); err != nil {
|
||||||
if err := cmdutil.RecordChangeCause(info.Object, o.ChangeCause); err != nil {
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
30
pkg/kubectl/genericclioptions/BUILD
Normal file
30
pkg/kubectl/genericclioptions/BUILD
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"doc.go",
|
||||||
|
"record_flags.go",
|
||||||
|
],
|
||||||
|
importpath = "k8s.io/kubernetes/pkg/kubectl/genericclioptions",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime: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"],
|
||||||
|
)
|
19
pkg/kubectl/genericclioptions/doc.go
Normal file
19
pkg/kubectl/genericclioptions/doc.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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 genericclioptions contains flags which can be added to you command, bound, completed, and produce
|
||||||
|
// useful helper functions. Nothing in this package can depend on kube/kube
|
||||||
|
package genericclioptions
|
@ -14,18 +14,21 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package cmd
|
package genericclioptions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ChangeCauseAnnotation is the annotation indicating a guess at "why" something was changed
|
||||||
|
const ChangeCauseAnnotation = "kubernetes.io/change-cause"
|
||||||
|
|
||||||
// RecordFlags contains all flags associated with the "--record" operation
|
// RecordFlags contains all flags associated with the "--record" operation
|
||||||
type RecordFlags struct {
|
type RecordFlags struct {
|
||||||
|
// Record indicates the state of the recording flag. It is a pointer so a caller can opt out or rebind
|
||||||
Record *bool
|
Record *bool
|
||||||
|
|
||||||
changeCause string
|
changeCause string
|
||||||
@ -34,6 +37,10 @@ type RecordFlags struct {
|
|||||||
// ToRecorder returns a ChangeCause recorder if --record=false was not
|
// ToRecorder returns a ChangeCause recorder if --record=false was not
|
||||||
// explicitly given by the user
|
// explicitly given by the user
|
||||||
func (f *RecordFlags) ToRecorder() (Recorder, error) {
|
func (f *RecordFlags) ToRecorder() (Recorder, error) {
|
||||||
|
if f == nil {
|
||||||
|
return &NoopRecorder{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
shouldRecord := false
|
shouldRecord := false
|
||||||
if f.Record != nil {
|
if f.Record != nil {
|
||||||
shouldRecord = *f.Record
|
shouldRecord = *f.Record
|
||||||
@ -50,17 +57,29 @@ func (f *RecordFlags) ToRecorder() (Recorder, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Complete is called before the command is run, but after it is invoked to finish the state of the struct before use.
|
||||||
func (f *RecordFlags) Complete(changeCause string) error {
|
func (f *RecordFlags) Complete(changeCause string) error {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
f.changeCause = changeCause
|
f.changeCause = changeCause
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddFlags binds the requested flags to the provided flagset
|
||||||
|
// TODO have this only take a flagset
|
||||||
func (f *RecordFlags) AddFlags(cmd *cobra.Command) {
|
func (f *RecordFlags) AddFlags(cmd *cobra.Command) {
|
||||||
|
if f == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if f.Record != nil {
|
if f.Record != nil {
|
||||||
cmd.Flags().BoolVar(f.Record, "record", *f.Record, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
|
cmd.Flags().BoolVar(f.Record, "record", *f.Record, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRecordFlags provides a RecordFlags with reasonable default values set for use
|
||||||
func NewRecordFlags() *RecordFlags {
|
func NewRecordFlags() *RecordFlags {
|
||||||
record := false
|
record := false
|
||||||
|
|
||||||
@ -69,12 +88,16 @@ func NewRecordFlags() *RecordFlags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recorder is used to record why a runtime.Object was changed in an annotation.
|
||||||
type Recorder interface {
|
type Recorder interface {
|
||||||
|
// Record records why a runtime.Object was changed in an annotation.
|
||||||
Record(runtime.Object) error
|
Record(runtime.Object) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NoopRecorder does nothing. It is a "do nothing" that can be returned so code doesn't switch on it.
|
||||||
type NoopRecorder struct{}
|
type NoopRecorder struct{}
|
||||||
|
|
||||||
|
// Record implements Recorder
|
||||||
func (r *NoopRecorder) Record(obj runtime.Object) error {
|
func (r *NoopRecorder) Record(obj runtime.Object) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -95,7 +118,7 @@ func (r *ChangeCauseRecorder) Record(obj runtime.Object) error {
|
|||||||
if annotations == nil {
|
if annotations == nil {
|
||||||
annotations = make(map[string]string)
|
annotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
annotations[kubectl.ChangeCauseAnnotation] = r.changeCause
|
annotations[ChangeCauseAnnotation] = r.changeCause
|
||||||
accessor.SetAnnotations(annotations)
|
accessor.SetAnnotations(annotations)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user