move filename flags to genericclioptions

This commit is contained in:
juanvallejo 2018-05-24 15:05:16 -04:00 committed by Maciej Szulik
parent d463bbddb1
commit b4af3a4ffb
No known key found for this signature in database
GPG Key ID: F15E55D276FA84C4
9 changed files with 119 additions and 120 deletions

View File

@ -82,7 +82,6 @@ go_library(
srcs = [ srcs = [
"apply.go", "apply.go",
"autoscale.go", "autoscale.go",
"bash_comp_utils.go",
"clusterrolebinding.go", "clusterrolebinding.go",
"conditions.go", "conditions.go",
"configmap.go", "configmap.go",
@ -125,7 +124,6 @@ go_library(
"//pkg/controller/deployment/util:go_default_library", "//pkg/controller/deployment/util:go_default_library",
"//pkg/credentialprovider:go_default_library", "//pkg/credentialprovider:go_default_library",
"//pkg/kubectl/apps:go_default_library", "//pkg/kubectl/apps:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/util:go_default_library", "//pkg/kubectl/util:go_default_library",
"//pkg/kubectl/util/hash:go_default_library", "//pkg/kubectl/util/hash:go_default_library",
"//pkg/kubectl/util/slice:go_default_library", "//pkg/kubectl/util/slice:go_default_library",

View File

@ -1,36 +0,0 @@
/*
Copyright 2015 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.
*/
// A set of common functions needed by cmd/kubectl and pkg/kubectl packages.
package kubectl
import (
"strings"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
)
func AddJsonFilenameFlag(cmd *cobra.Command, value *[]string, usage string) {
cmd.Flags().StringSliceVarP(value, "filename", "f", *value, usage)
annotations := make([]string, 0, len(resource.FileExtensions))
for _, ext := range resource.FileExtensions {
annotations = append(annotations, strings.TrimLeft(ext, "."))
}
cmd.Flags().SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
}

View File

@ -107,7 +107,7 @@ func NewCmdApplySetLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IO
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
cmd.Flags().BoolVar(&o.CreateAnnotation, "create-annotation", o.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one") cmd.Flags().BoolVar(&o.CreateAnnotation, "create-annotation", o.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one")
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, "Filename, directory, or URL to files that contains the last-applied-configuration annotations") cmdutil.AddJsonFilenameFlag(cmd.Flags(), &o.FilenameOptions.Filenames, "Filename, directory, or URL to files that contains the last-applied-configuration annotations")
return cmd return cmd
} }

View File

@ -22,44 +22,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
) )
type FileNameFlags struct {
Usage string
Filenames *[]string
Recursive *bool
}
func (o *FileNameFlags) ToOptions() resource.FilenameOptions {
options := resource.FilenameOptions{}
if o.Recursive != nil {
options.Recursive = *o.Recursive
}
if o.Filenames != nil {
options.Filenames = *o.Filenames
}
return options
}
func (o *FileNameFlags) AddFlags(cmd *cobra.Command) {
if o.Recursive != nil {
cmd.Flags().BoolVarP(o.Recursive, "recursive", "R", *o.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
}
if o.Filenames != nil {
kubectl.AddJsonFilenameFlag(cmd, o.Filenames, "Filename, directory, or URL to files "+o.Usage)
}
}
// PrintFlags composes common printer flag structs // PrintFlags composes common printer flag structs
// used for commands requiring deletion logic. // used for commands requiring deletion logic.
type DeleteFlags struct { type DeleteFlags struct {
FileNameFlags *FileNameFlags FileNameFlags *genericclioptions.FileNameFlags
LabelSelector *string LabelSelector *string
FieldSelector *string FieldSelector *string
@ -121,7 +90,7 @@ func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams generic
} }
func (f *DeleteFlags) AddFlags(cmd *cobra.Command) { func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
f.FileNameFlags.AddFlags(cmd) f.FileNameFlags.AddFlags(cmd.Flags())
if f.LabelSelector != nil { if f.LabelSelector != nil {
cmd.Flags().StringVarP(f.LabelSelector, "selector", "l", *f.LabelSelector, "Selector (label query) to filter on, not including uninitialized ones.") cmd.Flags().StringVarP(f.LabelSelector, "selector", "l", *f.LabelSelector, "Selector (label query) to filter on, not including uninitialized ones.")
} }
@ -175,7 +144,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
recursive := false recursive := false
return &DeleteFlags{ return &DeleteFlags{
FileNameFlags: &FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive}, FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive},
LabelSelector: &labelSelector, LabelSelector: &labelSelector,
FieldSelector: &fieldSelector, FieldSelector: &fieldSelector,
@ -203,7 +172,7 @@ func NewDeleteFlags(usage string) *DeleteFlags {
recursive := false recursive := false
return &DeleteFlags{ return &DeleteFlags{
FileNameFlags: &FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive}, FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive},
Cascade: &cascade, Cascade: &cascade,
GracePeriod: &gracePeriod, GracePeriod: &gracePeriod,

View File

@ -150,7 +150,7 @@ func NewCmdRollingUpdate(f cmdutil.Factory, ioStreams genericclioptions.IOStream
cmd.Flags().DurationVar(&o.Interval, "poll-interval", o.Interval, `Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`) cmd.Flags().DurationVar(&o.Interval, "poll-interval", o.Interval, `Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, `Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`) cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, `Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
usage := "Filename or URL to file to use to create the new replication controller." usage := "Filename or URL to file to use to create the new replication controller."
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, usage) cmdutil.AddJsonFilenameFlag(cmd.Flags(), &o.FilenameOptions.Filenames, usage)
cmd.Flags().StringVar(&o.Image, "image", o.Image, i18n.T("Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f")) cmd.Flags().StringVar(&o.Image, "image", o.Image, i18n.T("Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f"))
cmd.Flags().StringVar(&o.DeploymentKey, "deployment-label-key", o.DeploymentKey, i18n.T("The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise")) cmd.Flags().StringVar(&o.DeploymentKey, "deployment-label-key", o.DeploymentKey, i18n.T("The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise"))
cmd.Flags().StringVar(&o.Container, "container", o.Container, i18n.T("Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod")) cmd.Flags().StringVar(&o.Container, "container", o.Container, i18n.T("Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod"))

View File

@ -29,6 +29,7 @@ import (
"github.com/evanphx/json-patch" "github.com/evanphx/json-patch"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
kerrors "k8s.io/apimachinery/pkg/api/errors" kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
@ -42,7 +43,6 @@ import (
"k8s.io/client-go/scale" "k8s.io/client-go/scale"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/printers" "k8s.io/kubernetes/pkg/printers"
@ -405,10 +405,19 @@ func AddValidateOptionFlags(cmd *cobra.Command, options *ValidateOptions) {
} }
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) { func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, "Filename, directory, or URL to files "+usage) AddJsonFilenameFlag(cmd.Flags(), &options.Filenames, "Filename, directory, or URL to files "+usage)
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.") cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
} }
func AddJsonFilenameFlag(flags *pflag.FlagSet, value *[]string, usage string) {
flags.StringSliceVarP(value, "filename", "f", *value, usage)
annotations := make([]string, 0, len(resource.FileExtensions))
for _, ext := range resource.FileExtensions {
annotations = append(annotations, strings.TrimLeft(ext, "."))
}
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
}
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations. // AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
func AddDryRunFlag(cmd *cobra.Command) { func AddDryRunFlag(cmd *cobra.Command) {
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.") cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")

View File

@ -8,6 +8,7 @@ go_library(
"config_flags.go", "config_flags.go",
"config_flags_fake.go", "config_flags_fake.go",
"doc.go", "doc.go",
"filename_flags.go",
"io_options.go", "io_options.go",
"json_yaml_flags.go", "json_yaml_flags.go",
"name_flags.go", "name_flags.go",

View File

@ -17,53 +17,46 @@ limitations under the License.
package genericclioptions package genericclioptions
import ( import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
) )
// ResourceBuilderFlags are flags for finding resources // ResourceBuilderFlags are flags for finding resources
// TODO(juanvallejo): wire --local flag from commands through
type ResourceBuilderFlags struct { type ResourceBuilderFlags struct {
FilenameOptions resource.FilenameOptions FileNameFlags *FileNameFlags
Namespace string
ExplicitNamespace bool
LabelSelector *string LabelSelector *string
FieldSelector *string FieldSelector *string
AllNamespaces *bool AllNamespaces *bool
All *bool All bool
Local *bool
} }
// NewResourceBuilderFlags returns a default ResourceBuilderFlags // NewResourceBuilderFlags returns a default ResourceBuilderFlags
func NewResourceBuilderFlags() *ResourceBuilderFlags { func NewResourceBuilderFlags() *ResourceBuilderFlags {
filenames := []string{}
return &ResourceBuilderFlags{ return &ResourceBuilderFlags{
FilenameOptions: resource.FilenameOptions{ FileNameFlags: &FileNameFlags{
Recursive: true, Usage: "identifying the resource.",
Filenames: &filenames,
Recursive: boolPtr(true),
}, },
LabelSelector: str_ptr(""), LabelSelector: strPtr(""),
FieldSelector: str_ptr(""), AllNamespaces: boolPtr(false),
AllNamespaces: bool_ptr(false),
All: bool_ptr(false),
Local: bool_ptr(false),
} }
} }
func (o *ResourceBuilderFlags) WithFieldSelector(selector string) *ResourceBuilderFlags {
o.FieldSelector = &selector
return o
}
// AddFlags registers flags for finding resources // AddFlags registers flags for finding resources
func (o *ResourceBuilderFlags) AddFlags(flagset *pflag.FlagSet) { func (o *ResourceBuilderFlags) AddFlags(flagset *pflag.FlagSet) {
flagset.StringSliceVarP(&o.FilenameOptions.Filenames, "filename", "f", o.FilenameOptions.Filenames, "Filename, directory, or URL to files identifying the resource.") o.FileNameFlags.AddFlags(flagset)
annotations := make([]string, 0, len(resource.FileExtensions))
for _, ext := range resource.FileExtensions {
annotations = append(annotations, strings.TrimLeft(ext, "."))
}
flagset.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
flagset.BoolVar(&o.FilenameOptions.Recursive, "recursive", o.FilenameOptions.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
if o.LabelSelector != nil { if o.LabelSelector != nil {
flagset.StringVarP(o.LabelSelector, "selector", "l", *o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)") flagset.StringVarP(o.LabelSelector, "selector", "l", *o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
@ -80,29 +73,23 @@ func (o *ResourceBuilderFlags) AddFlags(flagset *pflag.FlagSet) {
func (o *ResourceBuilderFlags) ToBuilder(restClientGetter RESTClientGetter, resources []string) ResourceFinder { func (o *ResourceBuilderFlags) ToBuilder(restClientGetter RESTClientGetter, resources []string) ResourceFinder {
namespace, enforceNamespace, namespaceErr := restClientGetter.ToRawKubeConfigLoader().Namespace() namespace, enforceNamespace, namespaceErr := restClientGetter.ToRawKubeConfigLoader().Namespace()
labelSelector := "" builder := resource.NewBuilder(restClientGetter).
Unstructured().
NamespaceParam(namespace).DefaultNamespace().
ResourceTypeOrNameArgs(o.All, resources...)
if o.FileNameFlags != nil {
opts := o.FileNameFlags.ToOptions()
builder = builder.FilenameParam(enforceNamespace, &opts)
}
if o.LabelSelector != nil { if o.LabelSelector != nil {
labelSelector = *o.LabelSelector builder = builder.LabelSelectorParam(*o.LabelSelector)
} }
fieldSelector := ""
if o.FieldSelector != nil { if o.FieldSelector != nil {
fieldSelector = *o.FieldSelector builder = builder.FieldSelectorParam(*o.FieldSelector)
}
allResources := false
if o.All != nil {
allResources = *o.All
} }
return &ResourceFindBuilderWrapper{ return &ResourceFindBuilderWrapper{
builder: resource.NewBuilder(restClientGetter). builder: builder.
Unstructured().
NamespaceParam(namespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(labelSelector).
FieldSelectorParam(fieldSelector).
ResourceTypeOrNameArgs(allResources, resources...).
Latest(). Latest().
Flatten(). Flatten().
AddError(namespaceErr), AddError(namespaceErr),
@ -140,10 +127,10 @@ func ResourceFinderForResult(result resource.Visitor) ResourceFinder {
}) })
} }
func str_ptr(val string) *string { func strPtr(val string) *string {
return &val return &val
} }
func bool_ptr(val bool) *bool { func boolPtr(val bool) *bool {
return &val return &val
} }

View File

@ -0,0 +1,71 @@
/*
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
import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
)
// Usage of this struct by itself is discouraged.
// These flags are composed by ResourceBuilderFlags
// which should be used instead.
type FileNameFlags struct {
Usage string
Filenames *[]string
Recursive *bool
}
func (o *FileNameFlags) ToOptions() resource.FilenameOptions {
options := resource.FilenameOptions{}
if o == nil {
return options
}
if o.Recursive != nil {
options.Recursive = *o.Recursive
}
if o.Filenames != nil {
options.Filenames = *o.Filenames
}
return options
}
func (o *FileNameFlags) AddFlags(flags *pflag.FlagSet) {
if o == nil {
return
}
if o.Recursive != nil {
flags.BoolVarP(o.Recursive, "recursive", "R", *o.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
}
if o.Filenames != nil {
flags.StringSliceVarP(o.Filenames, "filename", "f", *o.Filenames, o.Usage)
annotations := make([]string, 0, len(resource.FileExtensions))
for _, ext := range resource.FileExtensions {
annotations = append(annotations, strings.TrimLeft(ext, "."))
}
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
}
}