Merge pull request #70682 from idealhack/fix-golint-pkg-kubectl-cmd

Fix some golint errors for packages in `pkg/kubectl/cmd`
This commit is contained in:
Kubernetes Prow Robot
2018-12-04 00:49:09 -08:00
committed by GitHub
83 changed files with 641 additions and 424 deletions

View File

@@ -1,4 +1,3 @@
cluster/images/etcd-version-monitor cluster/images/etcd-version-monitor
cmd/cloud-controller-manager/app/apis/config/v1alpha1 cmd/cloud-controller-manager/app/apis/config/v1alpha1
cmd/hyperkube cmd/hyperkube
@@ -137,15 +136,12 @@ pkg/kubeapiserver/options
pkg/kubectl pkg/kubectl
pkg/kubectl/apps pkg/kubectl/apps
pkg/kubectl/cmd/annotate pkg/kubectl/cmd/annotate
pkg/kubectl/cmd/apiresources
pkg/kubectl/cmd/apply pkg/kubectl/cmd/apply
pkg/kubectl/cmd/attach pkg/kubectl/cmd/attach
pkg/kubectl/cmd/auth
pkg/kubectl/cmd/autoscale pkg/kubectl/cmd/autoscale
pkg/kubectl/cmd/certificates pkg/kubectl/cmd/certificates
pkg/kubectl/cmd/clusterinfo pkg/kubectl/cmd/clusterinfo
pkg/kubectl/cmd/completion pkg/kubectl/cmd/completion
pkg/kubectl/cmd/config
pkg/kubectl/cmd/convert pkg/kubectl/cmd/convert
pkg/kubectl/cmd/cp pkg/kubectl/cmd/cp
pkg/kubectl/cmd/create pkg/kubectl/cmd/create
@@ -175,9 +171,7 @@ pkg/kubectl/cmd/taint
pkg/kubectl/cmd/testing pkg/kubectl/cmd/testing
pkg/kubectl/cmd/top pkg/kubectl/cmd/top
pkg/kubectl/cmd/util pkg/kubectl/cmd/util
pkg/kubectl/cmd/util/editor
pkg/kubectl/cmd/util/openapi pkg/kubectl/cmd/util/openapi
pkg/kubectl/cmd/util/sanity
pkg/kubectl/cmd/version pkg/kubectl/cmd/version
pkg/kubectl/cmd/wait pkg/kubectl/cmd/wait
pkg/kubectl/describe/versioned pkg/kubectl/describe/versioned

View File

@@ -109,6 +109,7 @@ var (
kubectl annotate pods foo description-`)) kubectl annotate pods foo description-`))
) )
// NewAnnotateOptions creates the options for annotate
func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions { func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions {
return &AnnotateOptions{ return &AnnotateOptions{
PrintFlags: genericclioptions.NewPrintFlags("annotated").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("annotated").WithTypeSetter(scheme.Scheme),
@@ -119,6 +120,7 @@ func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions
} }
} }
// NewCmdAnnotate creates the `annotate` command
func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAnnotateOptions(ioStreams) o := NewAnnotateOptions(ioStreams)
@@ -126,7 +128,7 @@ func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioption
Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]", Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Update the annotations on a resource"), Short: i18n.T("Update the annotations on a resource"),
Long: annotateLong + "\n\n" + cmdutil.SuggestApiResources(parent), Long: annotateLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
Example: annotateExample, Example: annotateExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))

View File

@@ -51,9 +51,9 @@ var (
kubectl api-resources --api-group=extensions`) kubectl api-resources --api-group=extensions`)
) )
// ApiResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of // APIResourceOptions is the start of the data required to perform the operation.
// referencing the cmd.Flags() // As new fields are added, add them here instead of referencing the cmd.Flags()
type ApiResourcesOptions struct { type APIResourceOptions struct {
Output string Output string
APIGroup string APIGroup string
Namespaced bool Namespaced bool
@@ -70,8 +70,9 @@ type groupResource struct {
APIResource metav1.APIResource APIResource metav1.APIResource
} }
func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *ApiResourcesOptions { // NewAPIResourceOptions creates the options for APIResource
return &ApiResourcesOptions{ func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *APIResourceOptions {
return &APIResourceOptions{
IOStreams: ioStreams, IOStreams: ioStreams,
Namespaced: true, Namespaced: true,
} }
@@ -89,7 +90,7 @@ func NewCmdAPIResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(cmd, args)) cmdutil.CheckErr(o.Complete(cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunApiResources(cmd, f)) cmdutil.CheckErr(o.RunAPIResources(cmd, f))
}, },
} }
@@ -103,7 +104,8 @@ func NewCmdAPIResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams
return cmd return cmd
} }
func (o *ApiResourcesOptions) Validate() error { // Validate checks to the APIResourceOptions to see if there is sufficient information run the command
func (o *APIResourceOptions) Validate() error {
supportedOutputTypes := sets.NewString("", "wide", "name") supportedOutputTypes := sets.NewString("", "wide", "name")
if !supportedOutputTypes.Has(o.Output) { if !supportedOutputTypes.Has(o.Output) {
return fmt.Errorf("--output %v is not available", o.Output) return fmt.Errorf("--output %v is not available", o.Output)
@@ -111,14 +113,16 @@ func (o *ApiResourcesOptions) Validate() error {
return nil return nil
} }
func (o *ApiResourcesOptions) Complete(cmd *cobra.Command, args []string) error { // Complete adapts from the command line args and validates them
func (o *APIResourceOptions) Complete(cmd *cobra.Command, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args) return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args)
} }
return nil return nil
} }
func (o *ApiResourcesOptions) RunApiResources(cmd *cobra.Command, f cmdutil.Factory) error { // RunAPIResources does the work
func (o *APIResourceOptions) RunAPIResources(cmd *cobra.Command, f cmdutil.Factory) error {
w := printers.GetNewTabWriter(o.Out) w := printers.GetNewTabWriter(o.Out)
defer w.Flush() defer w.Flush()

View File

@@ -36,21 +36,23 @@ var (
kubectl api-versions`)) kubectl api-versions`))
) )
type ApiVersionsOptions struct { // APIVersionsOptions have the data required for API versions
type APIVersionsOptions struct {
discoveryClient discovery.CachedDiscoveryInterface discoveryClient discovery.CachedDiscoveryInterface
genericclioptions.IOStreams genericclioptions.IOStreams
} }
func NewApiVersionsOptions(ioStreams genericclioptions.IOStreams) *ApiVersionsOptions { // NewAPIVersionsOptions creates the options for APIVersions
return &ApiVersionsOptions{ func NewAPIVersionsOptions(ioStreams genericclioptions.IOStreams) *APIVersionsOptions {
return &APIVersionsOptions{
IOStreams: ioStreams, IOStreams: ioStreams,
} }
} }
// NewCmdAPIVersions creates the `api-versions` command // NewCmdAPIVersions creates the `api-versions` command
func NewCmdAPIVersions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdAPIVersions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewApiVersionsOptions(ioStreams) o := NewAPIVersionsOptions(ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "api-versions", Use: "api-versions",
Short: "Print the supported API versions on the server, in the form of \"group/version\"", Short: "Print the supported API versions on the server, in the form of \"group/version\"",
@@ -58,13 +60,14 @@ func NewCmdAPIVersions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
Example: apiversionsExample, Example: apiversionsExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.RunApiVersions()) cmdutil.CheckErr(o.RunAPIVersions())
}, },
} }
return cmd return cmd
} }
func (o *ApiVersionsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { // Complete adapts from the command line args and factory to the data required
func (o *APIVersionsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args) return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args)
} }
@@ -76,13 +79,14 @@ func (o *ApiVersionsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
return nil return nil
} }
func (o *ApiVersionsOptions) RunApiVersions() error { // RunAPIVersions does the work
func (o *APIVersionsOptions) RunAPIVersions() error {
// Always request fresh data from the server // Always request fresh data from the server
o.discoveryClient.Invalidate() o.discoveryClient.Invalidate()
groupList, err := o.discoveryClient.ServerGroups() groupList, err := o.discoveryClient.ServerGroups()
if err != nil { if err != nil {
return fmt.Errorf("Couldn't get available api versions from server: %v\n", err) return fmt.Errorf("couldn't get available api versions from server: %v", err)
} }
apiVersions := metav1.ExtractGroupVersions(groupList) apiVersions := metav1.ExtractGroupVersions(groupList)
sort.Strings(apiVersions) sort.Strings(apiVersions)

View File

@@ -73,7 +73,7 @@ type ApplyOptions struct {
cmdBaseName string cmdBaseName string
All bool All bool
Overwrite bool Overwrite bool
OpenApiPatch bool OpenAPIPatch bool
PruneWhitelist []string PruneWhitelist []string
ShouldIncludeUninitialized bool ShouldIncludeUninitialized bool
@@ -133,7 +133,7 @@ func NewApplyOptions(ioStreams genericclioptions.IOStreams) *ApplyOptions {
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
Overwrite: true, Overwrite: true,
OpenApiPatch: true, OpenAPIPatch: true,
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
@@ -141,6 +141,7 @@ func NewApplyOptions(ioStreams genericclioptions.IOStreams) *ApplyOptions {
} }
} }
// NewCmdApply creates the `apply` command
func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewApplyOptions(ioStreams) o := NewApplyOptions(ioStreams)
@@ -174,7 +175,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions
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().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&o.All, "all", o.All, "Select all resources in the namespace of the specified resource types.") cmd.Flags().BoolVar(&o.All, "all", o.All, "Select all resources in the namespace of the specified resource types.")
cmd.Flags().StringArrayVar(&o.PruneWhitelist, "prune-whitelist", o.PruneWhitelist, "Overwrite the default whitelist with <group/version/kind> for --prune") cmd.Flags().StringArrayVar(&o.PruneWhitelist, "prune-whitelist", o.PruneWhitelist, "Overwrite the default whitelist with <group/version/kind> for --prune")
cmd.Flags().BoolVar(&o.OpenApiPatch, "openapi-patch", o.OpenApiPatch, "If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.") cmd.Flags().BoolVar(&o.OpenAPIPatch, "openapi-patch", o.OpenAPIPatch, "If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.")
cmd.Flags().BoolVar(&o.ServerDryRun, "server-dry-run", o.ServerDryRun, "If true, request will be sent to server with dry-run flag, which means the modifications won't be persisted. This is an alpha feature and flag.") cmd.Flags().BoolVar(&o.ServerDryRun, "server-dry-run", o.ServerDryRun, "If true, request will be sent to server with dry-run flag, which means the modifications won't be persisted. This is an alpha feature and flag.")
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd) cmdutil.AddIncludeUninitializedFlag(cmd)
@@ -258,7 +259,7 @@ func validatePruneAll(prune, all bool, selector string) error {
return fmt.Errorf("cannot set --all and --selector at the same time") return fmt.Errorf("cannot set --all and --selector at the same time")
} }
if prune && !all && selector == "" { if prune && !all && selector == "" {
return fmt.Errorf("all resources selected for prune without explicitly passing --all. To prune all resources, pass the --all flag. If you did not mean to prune all resources, specify a label selector.") return fmt.Errorf("all resources selected for prune without explicitly passing --all. To prune all resources, pass the --all flag. If you did not mean to prune all resources, specify a label selector")
} }
return nil return nil
} }
@@ -296,7 +297,7 @@ func parsePruneResources(mapper meta.RESTMapper, gvks []string) ([]pruneResource
func (o *ApplyOptions) Run() error { func (o *ApplyOptions) Run() error {
var openapiSchema openapi.Resources var openapiSchema openapi.Resources
if o.OpenApiPatch { if o.OpenAPIPatch {
openapiSchema = o.OpenAPISchema openapiSchema = o.OpenAPISchema
} }
@@ -901,7 +902,7 @@ func (p *Patcher) deleteAndCreate(original runtime.Object, modified []byte, name
// but still propagate and advertise error to user // but still propagate and advertise error to user
recreated, recreateErr := p.Helper.Create(namespace, true, original, &options) recreated, recreateErr := p.Helper.Create(namespace, true, original, &options)
if recreateErr != nil { if recreateErr != nil {
err = fmt.Errorf("An error occurred force-replacing the existing object with the newly provided one:\n\n%v.\n\nAdditionally, an error occurred attempting to restore the original object:\n\n%v\n", err, recreateErr) err = fmt.Errorf("An error occurred force-replacing the existing object with the newly provided one:\n\n%v.\n\nAdditionally, an error occurred attempting to restore the original object:\n\n%v", err, recreateErr)
} else { } else {
createdObject = recreated createdObject = recreated
} }

View File

@@ -162,9 +162,8 @@ func (o *SetLastAppliedOptions) Validate() error {
if err := info.Get(); err != nil { if err := info.Get(); err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
return err return err
} else {
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
} }
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
} }
originalBuf, err := kubectl.GetOriginalConfiguration(info.Object) originalBuf, err := kubectl.GetOriginalConfiguration(info.Object)
if err != nil { if err != nil {

View File

@@ -377,7 +377,7 @@ func TestRunApplyViewLastApplied(t *testing.T) {
name: "view resource/name invalid format", name: "view resource/name invalid format",
filePath: "", filePath: "",
outputFormat: "wide", outputFormat: "wide",
expectedErr: "error: Unexpected -o output mode: wide, the flag 'output' must be one of yaml|json\nSee 'view-last-applied -h' for help and examples.", expectedErr: "error: Unexpected -o output mode: wide, the flag 'output' must be one of yaml|json\nSee 'view-last-applied -h' for help and examples",
expectedOut: "", expectedOut: "",
selector: "", selector: "",
args: []string{"replicationcontroller", "test-rc"}, args: []string{"replicationcontroller", "test-rc"},
@@ -648,7 +648,7 @@ func TestApplyRetry(t *testing.T) {
case p == pathRC && m == "PATCH": case p == pathRC && m == "PATCH":
if firstPatch { if firstPatch {
firstPatch = false firstPatch = false
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first.")) statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first"))
bodyBytes, _ := json.Marshal(statusErr) bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes)) bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: cmdtesting.DefaultHeader(), Body: bodyErr}, nil return &http.Response{StatusCode: http.StatusConflict, Header: cmdtesting.DefaultHeader(), Body: bodyErr}, nil
@@ -1280,7 +1280,7 @@ func TestForceApply(t *testing.T) {
case strings.HasSuffix(p, pathRC) && m == "PATCH": case strings.HasSuffix(p, pathRC) && m == "PATCH":
counts["patch"]++ counts["patch"]++
if counts["patch"] <= 6 { if counts["patch"] <= 6 {
statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first.")) statusErr := kubeerr.NewConflict(schema.GroupResource{Group: "", Resource: "rc"}, "test-rc", fmt.Errorf("the object has been modified. Please apply at first"))
bodyBytes, _ := json.Marshal(statusErr) bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes)) bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusConflict, Header: cmdtesting.DefaultHeader(), Body: bodyErr}, nil return &http.Response{StatusCode: http.StatusConflict, Header: cmdtesting.DefaultHeader(), Body: bodyErr}, nil

View File

@@ -23,6 +23,7 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
// NewCmdAuth returns an initialized Command instance for 'auth' sub command
func NewCmdAuth(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdAuth(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
// Parent command to which all subcommands are added. // Parent command to which all subcommands are added.
cmds := &cobra.Command{ cmds := &cobra.Command{

View File

@@ -80,6 +80,7 @@ var (
kubectl auth can-i get /logs/`) kubectl auth can-i get /logs/`)
) )
// NewCmdCanI returns an initialized Command for 'auth can-i' sub command
func NewCmdCanI(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdCanI(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &CanIOptions{ o := &CanIOptions{
IOStreams: streams, IOStreams: streams,
@@ -112,6 +113,7 @@ func NewCmdCanI(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
return cmd return cmd
} }
// Complete completes all the required options
func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error { func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error {
if o.Quiet { if o.Quiet {
o.Out = ioutil.Discard o.Out = ioutil.Discard
@@ -155,6 +157,7 @@ func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error {
return nil return nil
} }
// Validate makes sure provided values for CanIOptions are valid
func (o *CanIOptions) Validate() error { func (o *CanIOptions) Validate() error {
if o.NonResourceURL != "" { if o.NonResourceURL != "" {
if o.Subresource != "" { if o.Subresource != "" {
@@ -167,6 +170,7 @@ func (o *CanIOptions) Validate() error {
return nil return nil
} }
// RunAccessCheck checks if user has access to a certain resource or non resource URL
func (o *CanIOptions) RunAccessCheck() (bool, error) { func (o *CanIOptions) RunAccessCheck() (bool, error) {
var sar *authorizationv1.SelfSubjectAccessReview var sar *authorizationv1.SelfSubjectAccessReview
if o.NonResourceURL == "" { if o.NonResourceURL == "" {

View File

@@ -66,6 +66,7 @@ var (
kubectl auth reconcile -f my-rbac-rules.yaml`) kubectl auth reconcile -f my-rbac-rules.yaml`)
) )
// NewReconcileOptions returns a new ReconcileOptions instance
func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOptions { func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOptions {
return &ReconcileOptions{ return &ReconcileOptions{
FilenameOptions: &resource.FilenameOptions{}, FilenameOptions: &resource.FilenameOptions{},
@@ -74,6 +75,7 @@ func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOption
} }
} }
// NewCmdReconcile holds the options for 'auth reconcile' sub command
func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewReconcileOptions(streams) o := NewReconcileOptions(streams)
@@ -101,6 +103,7 @@ func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *co
return cmd return cmd
} }
// Complete completes all the required options
func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error { func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error {
if len(args) > 0 { if len(args) > 0 {
return errors.New("no arguments are allowed") return errors.New("no arguments are allowed")
@@ -149,6 +152,7 @@ func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args
return nil return nil
} }
// Validate makes sure provided values for ReconcileOptions are valid
func (o *ReconcileOptions) Validate() error { func (o *ReconcileOptions) Validate() error {
if o.Visitor == nil { if o.Visitor == nil {
return errors.New("ReconcileOptions.Visitor must be set") return errors.New("ReconcileOptions.Visitor must be set")
@@ -171,6 +175,7 @@ func (o *ReconcileOptions) Validate() error {
return nil return nil
} }
// RunReconcile performs the execution
func (o *ReconcileOptions) RunReconcile() error { func (o *ReconcileOptions) RunReconcile() error {
return o.Visitor.Visit(func(info *resource.Info, err error) error { return o.Visitor.Visit(func(info *resource.Info, err error) error {
if err != nil { if err != nil {

View File

@@ -66,7 +66,7 @@ type AutoscaleOptions struct {
Generator string Generator string
Min int32 Min int32
Max int32 Max int32
CpuPercent int32 CPUPercent int32
createAnnotation bool createAnnotation bool
args []string args []string
@@ -120,7 +120,7 @@ func NewCmdAutoscale(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *
cmd.Flags().Int32Var(&o.Min, "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().Int32Var(&o.Min, "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().Int32Var(&o.Max, "max", -1, "The upper limit for the number of pods that can be set by the autoscaler. Required.") cmd.Flags().Int32Var(&o.Max, "max", -1, "The upper limit for the number of pods that can be set by the autoscaler. Required.")
cmd.MarkFlagRequired("max") cmd.MarkFlagRequired("max")
cmd.Flags().Int32Var(&o.CpuPercent, "cpu-percent", -1, fmt.Sprintf("The target average CPU utilization (represented as a percent of requested CPU) over all the pods. If it's not specified or negative, a default autoscaling policy will be used.")) cmd.Flags().Int32Var(&o.CPUPercent, "cpu-percent", -1, fmt.Sprintf("The target average CPU utilization (represented as a percent of requested CPU) over all the pods. If it's not specified or negative, a default autoscaling policy will be used."))
cmd.Flags().StringVar(&o.Name, "name", "", i18n.T("The name for the newly created object. If not specified, the name of the input resource will be used.")) cmd.Flags().StringVar(&o.Name, "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)
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, "identifying the resource to autoscale.") cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, "identifying the resource to autoscale.")
@@ -156,7 +156,7 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
Name: name, Name: name,
MinReplicas: o.Min, MinReplicas: o.Min,
MaxReplicas: o.Max, MaxReplicas: o.Max,
CPUPercent: o.CpuPercent, CPUPercent: o.CPUPercent,
ScaleRefName: name, ScaleRefName: name,
ScaleRefKind: mapping.GroupVersionKind.Kind, ScaleRefKind: mapping.GroupVersionKind.Kind,
ScaleRefAPIVersion: mapping.GroupVersionKind.GroupVersion().String(), ScaleRefAPIVersion: mapping.GroupVersionKind.GroupVersion().String(),

View File

@@ -68,6 +68,14 @@ type CertificateOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewCertificateOptions creates the options for certificate
func NewCertificateOptions(ioStreams genericclioptions.IOStreams) *CertificateOptions {
return &CertificateOptions{
PrintFlags: genericclioptions.NewPrintFlags("approved").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
}
func (o *CertificateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *CertificateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.csrNames = args o.csrNames = args
o.outputStyle = cmdutil.GetFlagString(cmd, "output") o.outputStyle = cmdutil.GetFlagString(cmd, "output")
@@ -103,10 +111,8 @@ func (o *CertificateOptions) Validate() error {
} }
func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := CertificateOptions{ o := NewCertificateOptions(ioStreams)
PrintFlags: genericclioptions.NewPrintFlags("approved").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "approve (-f FILENAME | NAME)", Use: "approve (-f FILENAME | NAME)",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
@@ -124,16 +130,16 @@ func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOS
signed certificate can do. signed certificate can do.
`), `),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.Validate()) cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(options.RunCertificateApprove(cmdutil.GetFlagBool(cmd, "force"))) cmdutil.CheckErr(o.RunCertificateApprove(cmdutil.GetFlagBool(cmd, "force")))
}, },
} }
options.PrintFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd)
cmd.Flags().Bool("force", false, "Update the CSR even if it is already approved.") cmd.Flags().Bool("force", false, "Update the CSR even if it is already approved.")
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update") cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to update")
return cmd return cmd
} }
@@ -160,10 +166,8 @@ func (o *CertificateOptions) RunCertificateApprove(force bool) error {
} }
func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := CertificateOptions{ o := NewCertificateOptions(ioStreams)
PrintFlags: genericclioptions.NewPrintFlags("denied").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "deny (-f FILENAME | NAME)", Use: "deny (-f FILENAME | NAME)",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
@@ -176,16 +180,16 @@ func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStre
not to issue a certificate to the requestor. not to issue a certificate to the requestor.
`), `),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.Validate()) cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(options.RunCertificateDeny(cmdutil.GetFlagBool(cmd, "force"))) cmdutil.CheckErr(o.RunCertificateDeny(cmdutil.GetFlagBool(cmd, "force")))
}, },
} }
options.PrintFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd)
cmd.Flags().Bool("force", false, "Update the CSR even if it is already denied.") cmd.Flags().Bool("force", false, "Update the CSR even if it is already denied.")
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update") cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to update")
return cmd return cmd
} }
@@ -211,13 +215,13 @@ func (o *CertificateOptions) RunCertificateDeny(force bool) error {
}) })
} }
func (options *CertificateOptions) modifyCertificateCondition(builder *resource.Builder, clientSet certificatesv1beta1client.CertificatesV1beta1Interface, force bool, modify func(csr *certificatesv1beta1.CertificateSigningRequest) (*certificatesv1beta1.CertificateSigningRequest, bool)) error { func (o *CertificateOptions) modifyCertificateCondition(builder *resource.Builder, clientSet certificatesv1beta1client.CertificatesV1beta1Interface, force bool, modify func(csr *certificatesv1beta1.CertificateSigningRequest) (*certificatesv1beta1.CertificateSigningRequest, bool)) error {
var found int var found int
r := builder. r := builder.
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
ContinueOnError(). ContinueOnError().
FilenameParam(false, &options.FilenameOptions). FilenameParam(false, &o.FilenameOptions).
ResourceNames("certificatesigningrequest", options.csrNames...). ResourceNames("certificatesigningrequest", o.csrNames...).
RequireObject(true). RequireObject(true).
Flatten(). Flatten().
Latest(). Latest().
@@ -245,10 +249,10 @@ func (options *CertificateOptions) modifyCertificateCondition(builder *resource.
} }
found++ found++
return options.PrintObj(info.Object, options.Out) return o.PrintObj(info.Object, o.Out)
}) })
if found == 0 { if found == 0 {
fmt.Fprintf(options.Out, "No resources found\n") fmt.Fprintf(o.Out, "No resources found\n")
} }
return err return err
} }

View File

@@ -61,7 +61,6 @@ type ClusterInfoDumpOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewCmdCreateSecret groups subcommands to create various types of secrets
func NewCmdClusterInfoDump(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdClusterInfoDump(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := &ClusterInfoDumpOptions{ o := &ClusterInfoDumpOptions{
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme).WithDefaultOutput("json"), PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme).WithDefaultOutput("json"),

View File

@@ -44,7 +44,7 @@ const defaultBoilerPlate = `
` `
var ( var (
completion_long = templates.LongDesc(i18n.T(` completionLong = templates.LongDesc(i18n.T(`
Output shell completion code for the specified shell (bash or zsh). Output shell completion code for the specified shell (bash or zsh).
The shell code must be evaluated to provide interactive The shell code must be evaluated to provide interactive
completion of kubectl commands. This can be done by sourcing it from completion of kubectl commands. This can be done by sourcing it from
@@ -55,7 +55,7 @@ var (
Note for zsh users: [1] zsh completions are only supported in versions of zsh >= 5.2`)) Note for zsh users: [1] zsh completions are only supported in versions of zsh >= 5.2`))
completion_example = templates.Examples(i18n.T(` completionExample = templates.Examples(i18n.T(`
# Installing bash completion on macOS using homebrew # Installing bash completion on macOS using homebrew
## If running Bash 3.2 included with macOS ## If running Bash 3.2 included with macOS
brew install bash-completion brew install bash-completion
@@ -86,7 +86,7 @@ var (
) )
var ( var (
completion_shells = map[string]func(out io.Writer, boilerPlate string, cmd *cobra.Command) error{ completionShells = map[string]func(out io.Writer, boilerPlate string, cmd *cobra.Command) error{
"bash": runCompletionBash, "bash": runCompletionBash,
"zsh": runCompletionZsh, "zsh": runCompletionZsh,
} }
@@ -94,7 +94,7 @@ var (
func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command { func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
shells := []string{} shells := []string{}
for s := range completion_shells { for s := range completionShells {
shells = append(shells, s) shells = append(shells, s)
} }
@@ -102,8 +102,8 @@ func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
Use: "completion SHELL", Use: "completion SHELL",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)"), Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)"),
Long: completion_long, Long: completionLong,
Example: completion_example, Example: completionExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := RunCompletion(out, boilerPlate, cmd, args) err := RunCompletion(out, boilerPlate, cmd, args)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)
@@ -121,7 +121,7 @@ func RunCompletion(out io.Writer, boilerPlate string, cmd *cobra.Command, args [
if len(args) > 1 { if len(args) > 1 {
return cmdutil.UsageErrorf(cmd, "Too many arguments. Expected only the shell type.") return cmdutil.UsageErrorf(cmd, "Too many arguments. Expected only the shell type.")
} }
run, found := completion_shells[args[0]] run, found := completionShells[args[0]]
if !found { if !found {
return cmdutil.UsageErrorf(cmd, "Unsupported shell type %q.", args[0]) return cmdutil.UsageErrorf(cmd, "Unsupported shell type %q.", args[0])
} }
@@ -141,9 +141,9 @@ func runCompletionBash(out io.Writer, boilerPlate string, kubectl *cobra.Command
} }
func runCompletionZsh(out io.Writer, boilerPlate string, kubectl *cobra.Command) error { func runCompletionZsh(out io.Writer, boilerPlate string, kubectl *cobra.Command) error {
zsh_head := "#compdef kubectl\n" zshHead := "#compdef kubectl\n"
out.Write([]byte(zsh_head)) out.Write([]byte(zshHead))
if len(boilerPlate) == 0 { if len(boilerPlate) == 0 {
boilerPlate = defaultBoilerPlate boilerPlate = defaultBoilerPlate
@@ -152,7 +152,7 @@ func runCompletionZsh(out io.Writer, boilerPlate string, kubectl *cobra.Command)
return err return err
} }
zsh_initialization := ` zshInitialization := `
__kubectl_bash_source() { __kubectl_bash_source() {
alias shopt=':' alias shopt=':'
alias _expand=_bash_expand alias _expand=_bash_expand
@@ -294,19 +294,19 @@ __kubectl_convert_bash_to_zsh() {
-e "s/\\\$(type${RWORD}/\$(__kubectl_type/g" \ -e "s/\\\$(type${RWORD}/\$(__kubectl_type/g" \
<<'BASH_COMPLETION_EOF' <<'BASH_COMPLETION_EOF'
` `
out.Write([]byte(zsh_initialization)) out.Write([]byte(zshInitialization))
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
kubectl.GenBashCompletion(buf) kubectl.GenBashCompletion(buf)
out.Write(buf.Bytes()) out.Write(buf.Bytes())
zsh_tail := ` zshTail := `
BASH_COMPLETION_EOF BASH_COMPLETION_EOF
} }
__kubectl_bash_source <(__kubectl_convert_bash_to_zsh) __kubectl_bash_source <(__kubectl_convert_bash_to_zsh)
_complete kubectl 2>/dev/null _complete kubectl 2>/dev/null
` `
out.Write([]byte(zsh_tail)) out.Write([]byte(zshTail))
return nil return nil
} }

View File

@@ -88,5 +88,5 @@ func toBool(propertyValue string) (bool, error) {
func helpErrorf(cmd *cobra.Command, format string, args ...interface{}) error { func helpErrorf(cmd *cobra.Command, format string, args ...interface{}) error {
cmd.Help() cmd.Help()
msg := fmt.Sprintf(format, args...) msg := fmt.Sprintf(format, args...)
return fmt.Errorf("%s\n", msg) return fmt.Errorf("%s", msg)
} }

View File

@@ -56,7 +56,7 @@ const (
) )
var ( var (
create_authinfo_long = fmt.Sprintf(templates.LongDesc(` createAuthInfoLong = fmt.Sprintf(templates.LongDesc(`
Sets a user entry in kubeconfig Sets a user entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values. Specifying a name that already exists will merge new fields on top of existing values.
@@ -72,7 +72,7 @@ var (
Bearer token and basic auth are mutually exclusive.`), clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword) Bearer token and basic auth are mutually exclusive.`), clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword)
create_authinfo_example = templates.Examples(` createAuthInfoExample = templates.Examples(`
# Set only the "client-key" field on the "cluster-admin" # Set only the "client-key" field on the "cluster-admin"
# entry, without touching other values: # entry, without touching other values:
kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key
@@ -93,6 +93,7 @@ var (
kubectl config set-credentials cluster-admin --auth-provider=oidc --auth-provider-arg=client-secret-`) kubectl config set-credentials cluster-admin --auth-provider=oidc --auth-provider-arg=client-secret-`)
) )
// NewCmdConfigSetAuthInfo returns an Command option instance for 'config set-credentials' sub command
func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &createAuthInfoOptions{configAccess: configAccess} options := &createAuthInfoOptions{configAccess: configAccess}
return newCmdConfigSetAuthInfo(out, options) return newCmdConfigSetAuthInfo(out, options)
@@ -103,8 +104,8 @@ func newCmdConfigSetAuthInfo(out io.Writer, options *createAuthInfoOptions) *cob
Use: fmt.Sprintf("set-credentials NAME [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password] [--%v=provider_name] [--%v=key=value]", clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword, flagAuthProvider, flagAuthProviderArg), Use: fmt.Sprintf("set-credentials NAME [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password] [--%v=provider_name] [--%v=key=value]", clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword, flagAuthProvider, flagAuthProviderArg),
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Sets a user entry in kubeconfig"), Short: i18n.T("Sets a user entry in kubeconfig"),
Long: create_authinfo_long, Long: createAuthInfoLong,
Example: create_authinfo_example, Example: createAuthInfoExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := options.complete(cmd, out) err := options.complete(cmd, out)
if err != nil { if err != nil {
@@ -247,13 +248,13 @@ func (o *createAuthInfoOptions) complete(cmd *cobra.Command, out io.Writer) erro
authProviderArgs, err := cmd.Flags().GetStringSlice(flagAuthProviderArg) authProviderArgs, err := cmd.Flags().GetStringSlice(flagAuthProviderArg)
if err != nil { if err != nil {
return fmt.Errorf("Error: %s\n", err) return fmt.Errorf("Error: %s", err)
} }
if len(authProviderArgs) > 0 { if len(authProviderArgs) > 0 {
newPairs, removePairs, err := cmdutil.ParsePairs(authProviderArgs, flagAuthProviderArg, true) newPairs, removePairs, err := cmdutil.ParsePairs(authProviderArgs, flagAuthProviderArg, true)
if err != nil { if err != nil {
return fmt.Errorf("Error: %s\n", err) return fmt.Errorf("Error: %s", err)
} }
o.authProviderArgs = newPairs o.authProviderArgs = newPairs
o.authProviderArgsToRemove = removePairs o.authProviderArgsToRemove = removePairs

View File

@@ -43,12 +43,12 @@ type createClusterOptions struct {
} }
var ( var (
create_cluster_long = templates.LongDesc(` createClusterLong = templates.LongDesc(`
Sets a cluster entry in kubeconfig. Sets a cluster entry in kubeconfig.
Specifying a name that already exists will merge new fields on top of existing values for those fields.`) Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
create_cluster_example = templates.Examples(` createClusterExample = templates.Examples(`
# Set only the server field on the e2e cluster entry without touching other values. # Set only the server field on the e2e cluster entry without touching other values.
kubectl config set-cluster e2e --server=https://1.2.3.4 kubectl config set-cluster e2e --server=https://1.2.3.4
@@ -59,6 +59,7 @@ var (
kubectl config set-cluster e2e --insecure-skip-tls-verify=true`) kubectl config set-cluster e2e --insecure-skip-tls-verify=true`)
) )
// NewCmdConfigSetCluster returns a Command instance for 'config set-cluster' sub command
func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &createClusterOptions{configAccess: configAccess} options := &createClusterOptions{configAccess: configAccess}
@@ -66,8 +67,8 @@ func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess)
Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certificate/authority] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagInsecure), Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certificate/authority] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagInsecure),
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Sets a cluster entry in kubeconfig"), Short: i18n.T("Sets a cluster entry in kubeconfig"),
Long: create_cluster_long, Long: createClusterLong,
Example: create_cluster_example, Example: createClusterExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.complete(cmd)) cmdutil.CheckErr(options.complete(cmd))
cmdutil.CheckErr(options.run()) cmdutil.CheckErr(options.run())

View File

@@ -41,16 +41,17 @@ type createContextOptions struct {
} }
var ( var (
create_context_long = templates.LongDesc(` createContextLong = templates.LongDesc(`
Sets a context entry in kubeconfig Sets a context entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values for those fields.`) Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
create_context_example = templates.Examples(` createContextExample = templates.Examples(`
# Set the user field on the gce context entry without touching other values # Set the user field on the gce context entry without touching other values
kubectl config set-context gce --user=cluster-admin`) kubectl config set-context gce --user=cluster-admin`)
) )
// NewCmdConfigSetContext returns a Command instance for 'config set-context' sub command
func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &createContextOptions{configAccess: configAccess} options := &createContextOptions{configAccess: configAccess}
@@ -58,8 +59,8 @@ func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess)
Use: fmt.Sprintf("set-context [NAME | --current] [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace), Use: fmt.Sprintf("set-context [NAME | --current] [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace),
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Sets a context entry in kubeconfig"), Short: i18n.T("Sets a context entry in kubeconfig"),
Long: create_context_long, Long: createContextLong,
Example: create_context_example, Example: createContextExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.complete(cmd)) cmdutil.CheckErr(options.complete(cmd))
name, exists, err := options.run() name, exists, err := options.run()

View File

@@ -28,27 +28,29 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// CurrentContextOptions holds the command-line options for 'config current-context' sub command
type CurrentContextOptions struct { type CurrentContextOptions struct {
ConfigAccess clientcmd.ConfigAccess ConfigAccess clientcmd.ConfigAccess
} }
var ( var (
current_context_long = templates.LongDesc(` currentContextLong = templates.LongDesc(`
Displays the current-context`) Displays the current-context`)
current_context_example = templates.Examples(` currentContextExample = templates.Examples(`
# Display the current-context # Display the current-context
kubectl config current-context`) kubectl config current-context`)
) )
// NewCmdConfigCurrentContext returns a Command instance for 'config current-context' sub command
func NewCmdConfigCurrentContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigCurrentContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &CurrentContextOptions{ConfigAccess: configAccess} options := &CurrentContextOptions{ConfigAccess: configAccess}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "current-context", Use: "current-context",
Short: i18n.T("Displays the current-context"), Short: i18n.T("Displays the current-context"),
Long: current_context_long, Long: currentContextLong,
Example: current_context_example, Example: currentContextExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := RunCurrentContext(out, options) err := RunCurrentContext(out, options)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)
@@ -58,6 +60,7 @@ func NewCmdConfigCurrentContext(out io.Writer, configAccess clientcmd.ConfigAcce
return cmd return cmd
} }
// RunCurrentContext performs the execution of 'config current-context' sub command
func RunCurrentContext(out io.Writer, options *CurrentContextOptions) error { func RunCurrentContext(out io.Writer, options *CurrentContextOptions) error {
config, err := options.ConfigAccess.GetStartingConfig() config, err := options.ConfigAccess.GetStartingConfig()
if err != nil { if err != nil {
@@ -65,7 +68,7 @@ func RunCurrentContext(out io.Writer, options *CurrentContextOptions) error {
} }
if config.CurrentContext == "" { if config.CurrentContext == "" {
err = fmt.Errorf("current-context is not set\n") err = fmt.Errorf("current-context is not set")
return err return err
} }

View File

@@ -28,18 +28,19 @@ import (
) )
var ( var (
delete_cluster_example = templates.Examples(` deleteClusterExample = templates.Examples(`
# Delete the minikube cluster # Delete the minikube cluster
kubectl config delete-cluster minikube`) kubectl config delete-cluster minikube`)
) )
// NewCmdConfigDeleteCluster returns a Command instance for 'config delete-cluster' sub command
func NewCmdConfigDeleteCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigDeleteCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "delete-cluster NAME", Use: "delete-cluster NAME",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Delete the specified cluster from the kubeconfig"), Short: i18n.T("Delete the specified cluster from the kubeconfig"),
Long: "Delete the specified cluster from the kubeconfig", Long: "Delete the specified cluster from the kubeconfig",
Example: delete_cluster_example, Example: deleteClusterExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := runDeleteCluster(out, configAccess, cmd) err := runDeleteCluster(out, configAccess, cmd)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)

View File

@@ -28,18 +28,19 @@ import (
) )
var ( var (
delete_context_example = templates.Examples(` deleteContextExample = templates.Examples(`
# Delete the context for the minikube cluster # Delete the context for the minikube cluster
kubectl config delete-context minikube`) kubectl config delete-context minikube`)
) )
// NewCmdConfigDeleteContext returns a Command instance for 'config delete-context' sub command
func NewCmdConfigDeleteContext(out, errOut io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigDeleteContext(out, errOut io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "delete-context NAME", Use: "delete-context NAME",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Delete the specified context from the kubeconfig"), Short: i18n.T("Delete the specified context from the kubeconfig"),
Long: "Delete the specified context from the kubeconfig", Long: "Delete the specified context from the kubeconfig",
Example: delete_context_example, Example: deleteContextExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := runDeleteContext(out, errOut, configAccess, cmd) err := runDeleteContext(out, errOut, configAccess, cmd)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)

View File

@@ -28,7 +28,7 @@ import (
) )
var ( var (
get_clusters_example = templates.Examples(` getClustersExample = templates.Examples(`
# List the clusters kubectl knows about # List the clusters kubectl knows about
kubectl config get-clusters`) kubectl config get-clusters`)
) )
@@ -40,7 +40,7 @@ func NewCmdConfigGetClusters(out io.Writer, configAccess clientcmd.ConfigAccess)
Use: "get-clusters", Use: "get-clusters",
Short: i18n.T("Display clusters defined in the kubeconfig"), Short: i18n.T("Display clusters defined in the kubeconfig"),
Long: "Display clusters defined in the kubeconfig.", Long: "Display clusters defined in the kubeconfig.",
Example: get_clusters_example, Example: getClustersExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := runGetClusters(out, configAccess) err := runGetClusters(out, configAccess)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)

View File

@@ -92,6 +92,7 @@ func (o *RenameContextOptions) Complete(cmd *cobra.Command, args []string, out i
return nil return nil
} }
// Validate makes sure that provided values for command-line options are valid
func (o RenameContextOptions) Validate() error { func (o RenameContextOptions) Validate() error {
if len(o.newName) == 0 { if len(o.newName) == 0 {
return errors.New("You must specify a new non-empty context name") return errors.New("You must specify a new non-empty context name")
@@ -99,6 +100,7 @@ func (o RenameContextOptions) Validate() error {
return nil return nil
} }
// RunRenameContext performs the execution for 'config rename-context' sub command
func (o RenameContextOptions) RunRenameContext(out io.Writer) error { func (o RenameContextOptions) RunRenameContext(out io.Writer) error {
config, err := o.configAccess.GetStartingConfig() config, err := o.configAccess.GetStartingConfig()
if err != nil { if err != nil {

View File

@@ -36,7 +36,7 @@ const (
) )
var ( var (
contextData *clientcmdapi.Context = clientcmdapi.NewContext() contextData = clientcmdapi.NewContext()
) )
type renameContextTest struct { type renameContextTest struct {

View File

@@ -40,13 +40,14 @@ type setOptions struct {
setRawBytes flag.Tristate setRawBytes flag.Tristate
} }
var set_long = templates.LongDesc(` var setLong = templates.LongDesc(`
Sets an individual value in a kubeconfig file Sets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots. PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots.
PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.`) PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.`)
// NewCmdConfigSet returns a Command instance for 'config set' sub command
func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &setOptions{configAccess: configAccess} options := &setOptions{configAccess: configAccess}
@@ -54,7 +55,7 @@ func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.
Use: "set PROPERTY_NAME PROPERTY_VALUE", Use: "set PROPERTY_NAME PROPERTY_VALUE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Sets an individual value in a kubeconfig file"), Short: i18n.T("Sets an individual value in a kubeconfig file"),
Long: set_long, Long: setLong,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.complete(cmd)) cmdutil.CheckErr(options.complete(cmd))
cmdutil.CheckErr(options.run()) cmdutil.CheckErr(options.run())

View File

@@ -49,6 +49,7 @@ var (
kubectl config unset contexts.foo.namespace`) kubectl config unset contexts.foo.namespace`)
) )
// NewCmdConfigUnset returns a Command instance for 'config unset' sub command
func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &unsetOptions{configAccess: configAccess} options := &unsetOptions{configAccess: configAccess}

View File

@@ -31,7 +31,7 @@ import (
) )
var ( var (
use_context_example = templates.Examples(` useContextExample = templates.Examples(`
# Use the context for the minikube cluster # Use the context for the minikube cluster
kubectl config use-context minikube`) kubectl config use-context minikube`)
) )
@@ -41,6 +41,7 @@ type useContextOptions struct {
contextName string contextName string
} }
// NewCmdConfigUseContext returns a Command instance for 'config use-context' sub command
func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &useContextOptions{configAccess: configAccess} options := &useContextOptions{configAccess: configAccess}
@@ -50,7 +51,7 @@ func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess)
Short: i18n.T("Sets the current-context in a kubeconfig file"), Short: i18n.T("Sets the current-context in a kubeconfig file"),
Aliases: []string{"use"}, Aliases: []string{"use"},
Long: `Sets the current-context in a kubeconfig file`, Long: `Sets the current-context in a kubeconfig file`,
Example: use_context_example, Example: useContextExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.complete(cmd)) cmdutil.CheckErr(options.complete(cmd))
cmdutil.CheckErr(options.run()) cmdutil.CheckErr(options.run())
@@ -98,5 +99,5 @@ func (o useContextOptions) validate(config *clientcmdapi.Config) error {
} }
} }
return fmt.Errorf("no context exists with the name: %q.", o.contextName) return fmt.Errorf("no context exists with the name: %q", o.contextName)
} }

View File

@@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// ViewOptions holds the command-line options for 'config view' sub command
type ViewOptions struct { type ViewOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
PrintObject printers.ResourcePrinterFunc PrintObject printers.ResourcePrinterFunc
@@ -50,12 +51,12 @@ type ViewOptions struct {
} }
var ( var (
view_long = templates.LongDesc(` viewLong = templates.LongDesc(`
Display merged kubeconfig settings or a specified kubeconfig file. Display merged kubeconfig settings or a specified kubeconfig file.
You can use --output jsonpath={...} to extract specific values using a jsonpath expression.`) You can use --output jsonpath={...} to extract specific values using a jsonpath expression.`)
view_example = templates.Examples(` viewExample = templates.Examples(`
# Show merged kubeconfig settings. # Show merged kubeconfig settings.
kubectl config view kubectl config view
@@ -68,6 +69,7 @@ var (
defaultOutputFormat = "yaml" defaultOutputFormat = "yaml"
) )
// NewCmdConfigView returns a Command instance for 'config view' sub command
func NewCmdConfigView(f cmdutil.Factory, streams genericclioptions.IOStreams, ConfigAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigView(f cmdutil.Factory, streams genericclioptions.IOStreams, ConfigAccess clientcmd.ConfigAccess) *cobra.Command {
o := &ViewOptions{ o := &ViewOptions{
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme).WithDefaultOutput("yaml"), PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme).WithDefaultOutput("yaml"),
@@ -79,8 +81,8 @@ func NewCmdConfigView(f cmdutil.Factory, streams genericclioptions.IOStreams, Co
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "view", Use: "view",
Short: i18n.T("Display merged kubeconfig settings or a specified kubeconfig file"), Short: i18n.T("Display merged kubeconfig settings or a specified kubeconfig file"),
Long: view_long, Long: viewLong,
Example: view_example, Example: viewExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(cmd, args)) cmdutil.CheckErr(o.Complete(cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -99,6 +101,7 @@ func NewCmdConfigView(f cmdutil.Factory, streams genericclioptions.IOStreams, Co
return cmd return cmd
} }
// Complete completes the required command-line options
func (o *ViewOptions) Complete(cmd *cobra.Command, args []string) error { func (o *ViewOptions) Complete(cmd *cobra.Command, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args) return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args)
@@ -119,6 +122,7 @@ func (o *ViewOptions) Complete(cmd *cobra.Command, args []string) error {
return nil return nil
} }
// Validate makes sure that provided values for command-line options are valid
func (o ViewOptions) Validate() error { func (o ViewOptions) Validate() error {
if !o.Merge.Value() && !o.ConfigAccess.IsExplicitFile() { if !o.Merge.Value() && !o.ConfigAccess.IsExplicitFile() {
return errors.New("if merge==false a precise file must to specified") return errors.New("if merge==false a precise file must to specified")
@@ -127,6 +131,7 @@ func (o ViewOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of 'config view' sub command
func (o ViewOptions) Run() error { func (o ViewOptions) Run() error {
config, err := o.loadConfig() config, err := o.loadConfig()
if err != nil { if err != nil {

View File

@@ -37,7 +37,7 @@ import (
) )
var ( var (
convert_long = templates.LongDesc(i18n.T(` convertLong = templates.LongDesc(i18n.T(`
Convert config files between different API versions. Both YAML Convert config files between different API versions. Both YAML
and JSON formats are accepted. and JSON formats are accepted.
@@ -48,7 +48,7 @@ var (
The default output will be printed to stdout in YAML format. One can use -o option The default output will be printed to stdout in YAML format. One can use -o option
to change to output destination.`)) to change to output destination.`))
convert_example = templates.Examples(i18n.T(` convertExample = templates.Examples(i18n.T(`
# Convert 'pod.yaml' to latest version and print to stdout. # Convert 'pod.yaml' to latest version and print to stdout.
kubectl convert -f pod.yaml kubectl convert -f pod.yaml
@@ -93,8 +93,8 @@ func NewCmdConvert(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co
Use: "convert -f FILENAME", Use: "convert -f FILENAME",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Convert config files between different API versions"), Short: i18n.T("Convert config files between different API versions"),
Long: convert_long, Long: convertLong,
Example: convert_example, Example: convertExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd)) cmdutil.CheckErr(o.Complete(f, cmd))
cmdutil.CheckErr(o.RunConvert()) cmdutil.CheckErr(o.RunConvert())

View File

@@ -45,6 +45,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// CreateOptions is the commandline options for 'create' sub command
type CreateOptions struct { type CreateOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags RecordFlags *genericclioptions.RecordFlags
@@ -79,6 +80,7 @@ var (
kubectl create -f docker-registry.yaml --edit -o json`)) kubectl create -f docker-registry.yaml --edit -o json`))
) )
// NewCreateOptions returns an initialized CreateOptions instance
func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions { func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
return &CreateOptions{ return &CreateOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
@@ -90,6 +92,7 @@ func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
} }
} }
// NewCmdCreate returns new initialized instance of create sub command
func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateOptions(ioStreams) o := NewCreateOptions(ioStreams)
@@ -146,6 +149,7 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob
return cmd return cmd
} }
// ValidateArgs makes sure there is no discrepency in command options
func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error { func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args) return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
@@ -177,6 +181,7 @@ func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error {
return nil return nil
} }
// Complete completes all the required options
func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
var err error var err error
@@ -203,6 +208,7 @@ func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
return nil return nil
} }
// RunCreate performs the creation
func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error { func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
// raw only makes sense for a single file resource multiple objects aren't likely to do what you want. // raw only makes sense for a single file resource multiple objects aren't likely to do what you want.
// the validator enforces this, so // the validator enforces this, so
@@ -300,6 +306,7 @@ func (o *CreateOptions) raw(f cmdutil.Factory) error {
return nil return nil
} }
// RunEditOnCreate performs edit on creation
func RunEditOnCreate(f cmdutil.Factory, printFlags *genericclioptions.PrintFlags, recordFlags *genericclioptions.RecordFlags, ioStreams genericclioptions.IOStreams, cmd *cobra.Command, options *resource.FilenameOptions) error { func RunEditOnCreate(f cmdutil.Factory, printFlags *genericclioptions.PrintFlags, recordFlags *genericclioptions.RecordFlags, ioStreams genericclioptions.IOStreams, cmd *cobra.Command, options *resource.FilenameOptions) error {
editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, ioStreams) editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, ioStreams)
editOptions.FilenameOptions = *options editOptions.FilenameOptions = *options
@@ -363,6 +370,7 @@ type CreateSubcommandOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewCreateSubcommandOptions returns initialized CreateSubcommandOptions
func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSubcommandOptions { func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSubcommandOptions {
return &CreateSubcommandOptions{ return &CreateSubcommandOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
@@ -370,6 +378,7 @@ func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSu
} }
} }
// Complete completes all the required options
func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, generator generate.StructuredGenerator) error { func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, generator generate.StructuredGenerator) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -411,7 +420,7 @@ func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command
return nil return nil
} }
// RunCreateSubcommand executes a create subcommand using the specified options // Run executes a create subcommand using the specified options
func (o *CreateSubcommandOptions) Run() error { func (o *CreateSubcommandOptions) Run() error {
obj, err := o.StructuredGenerator.StructuredGenerate() obj, err := o.StructuredGenerator.StructuredGenerate()
if err != nil { if err != nil {

View File

@@ -58,13 +58,14 @@ var (
validNonResourceVerbs = []string{"*", "get", "post", "put", "delete", "patch", "head", "options"} validNonResourceVerbs = []string{"*", "get", "post", "put", "delete", "patch", "head", "options"}
) )
// CreateClusterRoleOptions is returned by NewCmdCreateClusterRole
type CreateClusterRoleOptions struct { type CreateClusterRoleOptions struct {
*CreateRoleOptions *CreateRoleOptions
NonResourceURLs []string NonResourceURLs []string
AggregationRule map[string]string AggregationRule map[string]string
} }
// ClusterRole is a command to ease creating ClusterRoles. // NewCmdCreateClusterRole initializes and returns new ClusterRoles command
func NewCmdCreateClusterRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreateClusterRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
c := &CreateClusterRoleOptions{ c := &CreateClusterRoleOptions{
CreateRoleOptions: NewCreateRoleOptions(ioStreams), CreateRoleOptions: NewCreateRoleOptions(ioStreams),
@@ -97,6 +98,7 @@ func NewCmdCreateClusterRole(f cmdutil.Factory, ioStreams genericclioptions.IOSt
return cmd return cmd
} }
// Complete completes all the required options
func (c *CreateClusterRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (c *CreateClusterRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
// Remove duplicate nonResourceURLs // Remove duplicate nonResourceURLs
nonResourceURLs := []string{} nonResourceURLs := []string{}
@@ -110,6 +112,7 @@ func (c *CreateClusterRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
return c.CreateRoleOptions.Complete(f, cmd, args) return c.CreateRoleOptions.Complete(f, cmd, args)
} }
// Validate makes sure there is no discrepency in CreateClusterRoleOptions
func (c *CreateClusterRoleOptions) Validate() error { func (c *CreateClusterRoleOptions) Validate() error {
if c.Name == "" { if c.Name == "" {
return fmt.Errorf("name must be specified") return fmt.Errorf("name must be specified")
@@ -170,6 +173,7 @@ func (c *CreateClusterRoleOptions) Validate() error {
} }
// RunCreateRole creates a new clusterRole
func (c *CreateClusterRoleOptions) RunCreateRole() error { func (c *CreateClusterRoleOptions) RunCreateRole() error {
clusterRole := &rbacv1.ClusterRole{ clusterRole := &rbacv1.ClusterRole{
// this is ok because we know exactly how we want to be serialized // this is ok because we know exactly how we want to be serialized

View File

@@ -36,13 +36,14 @@ var (
kubectl create clusterrolebinding cluster-admin --clusterrole=cluster-admin --user=user1 --user=user2 --group=group1`)) kubectl create clusterrolebinding cluster-admin --clusterrole=cluster-admin --user=user1 --user=user2 --group=group1`))
) )
// ClusterRoleBindingOpts is returned by NewCmdCreateClusterRoleBinding
type ClusterRoleBindingOpts struct { type ClusterRoleBindingOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
// ClusterRoleBinding is a command to ease creating ClusterRoleBindings. // NewCmdCreateClusterRoleBinding returns an initialized command instance of ClusterRoleBinding
func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ClusterRoleBindingOpts{ o := &ClusterRoleBindingOpts{
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams), CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
} }
@@ -53,12 +54,12 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptio
Long: clusterRoleBindingLong, Long: clusterRoleBindingLong,
Example: clusterRoleBindingExample, Example: clusterRoleBindingExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.Run()) cmdutil.CheckErr(o.Run())
}, },
} }
options.CreateSubcommandOptions.PrintFlags.AddFlags(cmd) o.CreateSubcommandOptions.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd) cmdutil.AddValidateFlags(cmd)
@@ -71,6 +72,7 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptio
return cmd return cmd
} }
// Complete completes all the required options
func (o *ClusterRoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ClusterRoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -94,7 +96,7 @@ func (o *ClusterRoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command,
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateClusterRoleBinding is the implementation of the create clusterrolebinding command. // Run calls the CreateSubcommandOptions.Run in ClusterRoleBindingOpts instance
func (o *ClusterRoleBindingOpts) Run() error { func (o *ClusterRoleBindingOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -57,11 +57,12 @@ var (
kubectl create configmap my-config --from-env-file=path/to/bar.env`)) kubectl create configmap my-config --from-env-file=path/to/bar.env`))
) )
// ConfigMapOpts holds properties for create configmap sub-command
type ConfigMapOpts struct { type ConfigMapOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
// ConfigMap is a command to ease creating ConfigMaps. // NewCmdCreateConfigMap initializes and returns ConfigMapOpts
func NewCmdCreateConfigMap(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreateConfigMap(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ConfigMapOpts{ options := &ConfigMapOpts{
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams), CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
@@ -92,6 +93,7 @@ func NewCmdCreateConfigMap(f cmdutil.Factory, ioStreams genericclioptions.IOStre
return cmd return cmd
} }
// Complete completes all the required options
func (o *ConfigMapOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ConfigMapOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -115,7 +117,7 @@ func (o *ConfigMapOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateConfigMap is the implementation of the create configmap command. // Run performs the execution of 'create' sub command options
func (o *ConfigMapOpts) Run() error { func (o *ConfigMapOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -36,6 +36,7 @@ var (
kubectl create deployment my-dep --image=busybox`)) kubectl create deployment my-dep --image=busybox`))
) )
// DeploymentOpts is returned by NewCmdCreateDeployment
type DeploymentOpts struct { type DeploymentOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -112,6 +113,7 @@ func generatorFromName(
return nil, false return nil, false
} }
// Complete completes all the options
func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -147,10 +149,7 @@ func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// createDeployment // Run performs the execution of 'create deployment' sub command
// 1. Reads user config values from Cobra.
// 2. Sets up the correct Generator object.
// 3. Calls RunCreateSubcommand.
func (o *DeploymentOpts) Run() error { func (o *DeploymentOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -50,6 +50,7 @@ var (
kubectl create job test-job --from=cronjob/a-cronjob`)) kubectl create job test-job --from=cronjob/a-cronjob`))
) )
// CreateJobOptions is the command line options for 'create job'
type CreateJobOptions struct { type CreateJobOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
@@ -69,6 +70,7 @@ type CreateJobOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewCreateJobOptions initializes and returns new CreateJobOptions instance
func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOptions { func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOptions {
return &CreateJobOptions{ return &CreateJobOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
@@ -102,6 +104,7 @@ func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *
return cmd return cmd
} }
// Complete completes all the required options
func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -143,6 +146,7 @@ func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
return nil return nil
} }
// Validate makes sure provided values and valid Job options
func (o *CreateJobOptions) Validate() error { func (o *CreateJobOptions) Validate() error {
if (len(o.Image) == 0 && len(o.From) == 0) || (len(o.Image) != 0 && len(o.From) != 0) { if (len(o.Image) == 0 && len(o.From) == 0) || (len(o.Image) != 0 && len(o.From) != 0) {
return fmt.Errorf("either --image or --from must be specified") return fmt.Errorf("either --image or --from must be specified")
@@ -153,6 +157,7 @@ func (o *CreateJobOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of 'create job' sub command
func (o *CreateJobOptions) Run() error { func (o *CreateJobOptions) Run() error {
var job *batchv1.Job var job *batchv1.Job
if len(o.Image) > 0 { if len(o.Image) > 0 {

View File

@@ -36,6 +36,7 @@ var (
kubectl create namespace my-namespace`)) kubectl create namespace my-namespace`))
) )
// NamespaceOpts is the options for 'create namespare' sub command
type NamespaceOpts struct { type NamespaceOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -68,6 +69,7 @@ func NewCmdCreateNamespace(f cmdutil.Factory, ioStreams genericclioptions.IOStre
return cmd return cmd
} }
// Complete completes all the required options
func (o *NamespaceOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *NamespaceOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -85,7 +87,7 @@ func (o *NamespaceOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateNamespace implements the behavior to run the create namespace command // Run calls the CreateSubcommandOptions.Run in NamespaceOpts instance
func (o *NamespaceOpts) Run() error { func (o *NamespaceOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -41,6 +41,7 @@ var (
kubectl create pdb my-pdb --selector=app=nginx --min-available=50%`)) kubectl create pdb my-pdb --selector=app=nginx --min-available=50%`))
) )
// PodDisruptionBudgetOpts holds the command-line options for poddisruptionbudget sub command
type PodDisruptionBudgetOpts struct { type PodDisruptionBudgetOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -76,6 +77,7 @@ func NewCmdCreatePodDisruptionBudget(f cmdutil.Factory, ioStreams genericcliopti
return cmd return cmd
} }
// Complete completes all the required options
func (o *PodDisruptionBudgetOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *PodDisruptionBudgetOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -104,7 +106,7 @@ func (o *PodDisruptionBudgetOpts) Complete(f cmdutil.Factory, cmd *cobra.Command
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreatePodDisruptionBudget implements the behavior to run the create pdb command. // Run calls the CreateSubcommandOptions.Run in PodDisruptionBudgetOpts instance
func (o *PodDisruptionBudgetOpts) Run() error { func (o *PodDisruptionBudgetOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -39,6 +39,7 @@ var (
kubectl create priorityclass default-priority --value=1000 --global-default=true --description="default priority"`)) kubectl create priorityclass default-priority --value=1000 --global-default=true --description="default priority"`))
) )
// PriorityClassOpts holds the options for 'create priorityclass' sub command
type PriorityClassOpts struct { type PriorityClassOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -74,6 +75,7 @@ func NewCmdCreatePriorityClass(f cmdutil.Factory, ioStreams genericclioptions.IO
return cmd return cmd
} }
// Complete completes all the required options
func (o *PriorityClassOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *PriorityClassOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -96,7 +98,7 @@ func (o *PriorityClassOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreatePriorityClass implements the behavior to run the create priorityClass command. // Run calls the CreateSubcommandOptions.Run in the PriorityClassOpts instance
func (o *PriorityClassOpts) Run() error { func (o *PriorityClassOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -39,6 +39,7 @@ var (
kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`)) kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`))
) )
// QuotaOpts holds the command-line options for 'create quota' sub command
type QuotaOpts struct { type QuotaOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -72,6 +73,7 @@ func NewCmdCreateQuota(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
return cmd return cmd
} }
// Complete completes all the required options
func (o *QuotaOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *QuotaOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -93,7 +95,7 @@ func (o *QuotaOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []strin
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateQuota implements the behavior to run the create quota command // Run calls the CreateSubcommandOptions.Run in QuotaOpts instance
func (o *QuotaOpts) Run() error { func (o *QuotaOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -105,12 +105,14 @@ var (
} }
) )
// ResourceOptions holds the related options for '--resource' option
type ResourceOptions struct { type ResourceOptions struct {
Group string Group string
Resource string Resource string
SubResource string SubResource string
} }
// CreateRoleOptions holds the options for 'create role' sub command
type CreateRoleOptions struct { type CreateRoleOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
@@ -129,6 +131,7 @@ type CreateRoleOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewCreateRoleOptions returns an initialized CreateRoleOptions instance
func NewCreateRoleOptions(ioStreams genericclioptions.IOStreams) *CreateRoleOptions { func NewCreateRoleOptions(ioStreams genericclioptions.IOStreams) *CreateRoleOptions {
return &CreateRoleOptions{ return &CreateRoleOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
@@ -137,7 +140,7 @@ func NewCreateRoleOptions(ioStreams genericclioptions.IOStreams) *CreateRoleOpti
} }
} }
// Role is a command to ease creating Roles. // NewCmdCreateRole returnns an initialized Command instance for 'create role' sub command
func NewCmdCreateRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreateRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateRoleOptions(ioStreams) o := NewCreateRoleOptions(ioStreams)
@@ -166,6 +169,7 @@ func NewCmdCreateRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
return cmd return cmd
} }
// Complete completes all the required options
func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -255,6 +259,7 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
return nil return nil
} }
// Validate makes sure there is no discrepency in provided option values
func (o *CreateRoleOptions) Validate() error { func (o *CreateRoleOptions) Validate() error {
if o.Name == "" { if o.Name == "" {
return fmt.Errorf("name must be specified") return fmt.Errorf("name must be specified")
@@ -317,6 +322,7 @@ func (o *CreateRoleOptions) validateResource() error {
return nil return nil
} }
// RunCreateRole performs the execution of 'create role' sub command
func (o *CreateRoleOptions) RunCreateRole() error { func (o *CreateRoleOptions) RunCreateRole() error {
role := &rbacv1.Role{ role := &rbacv1.Role{
// this is ok because we know exactly how we want to be serialized // this is ok because we know exactly how we want to be serialized

View File

@@ -36,13 +36,14 @@ var (
kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1`)) kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1`))
) )
// RoleBindingOpts holds the options for 'create rolebinding' sub command
type RoleBindingOpts struct { type RoleBindingOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
// RoleBinding is a command to ease creating RoleBindings. // NewCmdCreateRoleBinding returns an initialized Command instance for 'create rolebinding' sub command
func NewCmdCreateRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCreateRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &RoleBindingOpts{ o := &RoleBindingOpts{
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams), CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
} }
@@ -53,12 +54,12 @@ func NewCmdCreateRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOSt
Long: roleBindingLong, Long: roleBindingLong,
Example: roleBindingExample, Example: roleBindingExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.Run()) cmdutil.CheckErr(o.Run())
}, },
} }
options.CreateSubcommandOptions.PrintFlags.AddFlags(cmd) o.CreateSubcommandOptions.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd) cmdutil.AddValidateFlags(cmd)
@@ -71,6 +72,7 @@ func NewCmdCreateRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOSt
return cmd return cmd
} }
// Complete completes all the required options
func (o *RoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *RoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -95,6 +97,7 @@ func (o *RoleBindingOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// Run calls the CreateSubcommandOptions.Run in RoleBindingOpts instance
func (o *RoleBindingOpts) Run() error { func (o *RoleBindingOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -73,6 +73,7 @@ var (
kubectl create secret generic my-secret --from-env-file=path/to/bar.env`)) kubectl create secret generic my-secret --from-env-file=path/to/bar.env`))
) )
// SecretGenericOpts holds the options for 'create secret' sub command
type SecretGenericOpts struct { type SecretGenericOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -108,6 +109,7 @@ func NewCmdCreateSecretGeneric(f cmdutil.Factory, ioStreams genericclioptions.IO
return cmd return cmd
} }
// Complete completes all the required options
func (o *SecretGenericOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *SecretGenericOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -132,7 +134,7 @@ func (o *SecretGenericOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateSecretGeneric is the implementation of the create secret generic command // Run calls the CreateSubcommandOptions.Run in SecretGenericOpts instance
func (o *SecretGenericOpts) Run() error { func (o *SecretGenericOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }
@@ -158,6 +160,7 @@ var (
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`)) kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`))
) )
// SecretDockerRegistryOpts holds the options for 'create secret docker-registry' sub command
type SecretDockerRegistryOpts struct { type SecretDockerRegistryOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -197,6 +200,7 @@ func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, ioStreams genericcliopt
return cmd return cmd
} }
// Complete completes all the required options
func (o *SecretDockerRegistryOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *SecretDockerRegistryOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -232,7 +236,7 @@ func (o *SecretDockerRegistryOpts) Complete(f cmdutil.Factory, cmd *cobra.Comman
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateSecretDockerRegistry is the implementation of the create secret docker-registry command // Run calls CreateSubcommandOptions.Run in SecretDockerRegistryOpts instance
func (o *SecretDockerRegistryOpts) Run() error { func (o *SecretDockerRegistryOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }
@@ -249,6 +253,7 @@ var (
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`)) kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`))
) )
// SecretTLSOpts holds the options for 'create secret tls' sub command
type SecretTLSOpts struct { type SecretTLSOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -282,6 +287,7 @@ func NewCmdCreateSecretTLS(f cmdutil.Factory, ioStreams genericclioptions.IOStre
return cmd return cmd
} }
// Complete completes all the required options
func (o *SecretTLSOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *SecretTLSOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -310,7 +316,7 @@ func (o *SecretTLSOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateSecretTLS is the implementation of the create secret tls command // Run calls CreateSubcommandOptions.Run in the SecretTLSOpts instance
func (o *SecretTLSOpts) Run() error { func (o *SecretTLSOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -61,6 +61,7 @@ func addPortFlags(cmd *cobra.Command) {
cmd.Flags().StringSlice("tcp", []string{}, "Port pairs can be specified as '<port>:<targetPort>'.") cmd.Flags().StringSlice("tcp", []string{}, "Port pairs can be specified as '<port>:<targetPort>'.")
} }
// ServiceClusterIPOpts holds the options for 'create service clusterip' sub command
type ServiceClusterIPOpts struct { type ServiceClusterIPOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -97,6 +98,7 @@ func errUnsupportedGenerator(cmd *cobra.Command, generatorName string) error {
return cmdutil.UsageErrorf(cmd, "Generator %s not supported. ", generatorName) return cmdutil.UsageErrorf(cmd, "Generator %s not supported. ", generatorName)
} }
// Complete completes all the required options
func (o *ServiceClusterIPOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ServiceClusterIPOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -119,7 +121,7 @@ func (o *ServiceClusterIPOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, a
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateServiceClusterIP is the implementation of the create service clusterip command // Run calls the CreateSubcommandOptions.Run in ServiceClusterIPOpts instance
func (o *ServiceClusterIPOpts) Run() error { func (o *ServiceClusterIPOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }
@@ -133,6 +135,7 @@ var (
kubectl create service nodeport my-ns --tcp=5678:8080`)) kubectl create service nodeport my-ns --tcp=5678:8080`))
) )
// ServiceNodePortOpts holds the options for 'create service nodeport' sub command
type ServiceNodePortOpts struct { type ServiceNodePortOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -165,6 +168,7 @@ func NewCmdCreateServiceNodePort(f cmdutil.Factory, ioStreams genericclioptions.
return cmd return cmd
} }
// Complete completes all the required options
func (o *ServiceNodePortOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ServiceNodePortOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -188,7 +192,7 @@ func (o *ServiceNodePortOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, ar
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateServiceNodePort is the implementation of the create service nodeport command // Run calls the CreateSubcommandOptions.Run in ServiceNodePortOpts instance
func (o *ServiceNodePortOpts) Run() error { func (o *ServiceNodePortOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }
@@ -202,6 +206,7 @@ var (
kubectl create service loadbalancer my-lbs --tcp=5678:8080`)) kubectl create service loadbalancer my-lbs --tcp=5678:8080`))
) )
// ServiceLoadBalancerOpts holds the options for 'create service loadbalancer' sub command
type ServiceLoadBalancerOpts struct { type ServiceLoadBalancerOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -233,6 +238,7 @@ func NewCmdCreateServiceLoadBalancer(f cmdutil.Factory, ioStreams genericcliopti
return cmd return cmd
} }
// Complete completes all the required options
func (o *ServiceLoadBalancerOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ServiceLoadBalancerOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -255,7 +261,7 @@ func (o *ServiceLoadBalancerOpts) Complete(f cmdutil.Factory, cmd *cobra.Command
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateServiceLoadBalancer is the implementation of the create service loadbalancer command // Run calls the CreateSubcommandOptions.Run in ServiceLoadBalancerOpts instance
func (o *ServiceLoadBalancerOpts) Run() error { func (o *ServiceLoadBalancerOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }
@@ -273,6 +279,7 @@ var (
kubectl create service externalname my-ns --external-name bar.com`)) kubectl create service externalname my-ns --external-name bar.com`))
) )
// ServiceExternalNameOpts holds the options for 'create service externalname' sub command
type ServiceExternalNameOpts struct { type ServiceExternalNameOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -306,6 +313,7 @@ func NewCmdCreateServiceExternalName(f cmdutil.Factory, ioStreams genericcliopti
return cmd return cmd
} }
// Complete completes all the required options
func (o *ServiceExternalNameOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ServiceExternalNameOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -328,7 +336,7 @@ func (o *ServiceExternalNameOpts) Complete(f cmdutil.Factory, cmd *cobra.Command
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateExternalNameService is the implementation of the create service externalname command // Run calls the CreateSubcommandOptions.Run in ServiceExternalNameOpts instance
func (o *ServiceExternalNameOpts) Run() error { func (o *ServiceExternalNameOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -36,6 +36,7 @@ var (
kubectl create serviceaccount my-service-account`)) kubectl create serviceaccount my-service-account`))
) )
// ServiceAccountOpts holds the options for 'create serviceaccount' sub command
type ServiceAccountOpts struct { type ServiceAccountOpts struct {
CreateSubcommandOptions *CreateSubcommandOptions CreateSubcommandOptions *CreateSubcommandOptions
} }
@@ -67,6 +68,7 @@ func NewCmdCreateServiceAccount(f cmdutil.Factory, ioStreams genericclioptions.I
return cmd return cmd
} }
// Complete completes all the required options
func (o *ServiceAccountOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ServiceAccountOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
@@ -84,7 +86,7 @@ func (o *ServiceAccountOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
return o.CreateSubcommandOptions.Complete(f, cmd, args, generator) return o.CreateSubcommandOptions.Complete(f, cmd, args, generator)
} }
// CreateServiceAccount implements the behavior to run the create service account command // Run calls the CreateSubcommandOptions.Run in ServiceAccountOpts instance
func (o *ServiceAccountOpts) Run() error { func (o *ServiceAccountOpts) Run() error {
return o.CreateSubcommandOptions.Run() return o.CreateSubcommandOptions.Run()
} }

View File

@@ -33,13 +33,13 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
kubectlwait "k8s.io/kubernetes/pkg/kubectl/cmd/wait" cmdwait "k8s.io/kubernetes/pkg/kubectl/cmd/wait"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
var ( var (
delete_long = templates.LongDesc(i18n.T(` deleteLong = templates.LongDesc(i18n.T(`
Delete resources by filenames, stdin, resources and names, or by resources and label selector. Delete resources by filenames, stdin, resources and names, or by resources and label selector.
JSON and YAML formats are accepted. Only one type of the arguments may be specified: filenames, JSON and YAML formats are accepted. Only one type of the arguments may be specified: filenames,
@@ -67,7 +67,7 @@ var (
update to a resource right when you submit a delete, their update will be lost along with the update to a resource right when you submit a delete, their update will be lost along with the
rest of the resource.`)) rest of the resource.`))
delete_example = templates.Examples(i18n.T(` deleteExample = templates.Examples(i18n.T(`
# Delete a pod using the type and name specified in pod.json. # Delete a pod using the type and name specified in pod.json.
kubectl delete -f ./pod.json kubectl delete -f ./pod.json
@@ -121,8 +121,8 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])", Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"), Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"),
Long: delete_long, Long: deleteLong,
Example: delete_example, Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
o := deleteFlags.ToOptions(nil, streams) o := deleteFlags.ToOptions(nil, streams)
cmdutil.CheckErr(o.Complete(f, args, cmd)) cmdutil.CheckErr(o.Complete(f, args, cmd))
@@ -196,7 +196,7 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Co
func (o *DeleteOptions) Validate() error { func (o *DeleteOptions) Validate() error {
if o.Output != "" && o.Output != "name" { if o.Output != "" && o.Output != "name" {
return fmt.Errorf("unexpected -o output mode: %v. We only support '-o name'.", o.Output) return fmt.Errorf("unexpected -o output mode: %v. We only support '-o name'", o.Output)
} }
if o.DeleteAll && len(o.LabelSelector) > 0 { if o.DeleteAll && len(o.LabelSelector) > 0 {
@@ -225,7 +225,7 @@ func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
r = r.IgnoreErrors(errors.IsNotFound) r = r.IgnoreErrors(errors.IsNotFound)
} }
deletedInfos := []*resource.Info{} deletedInfos := []*resource.Info{}
uidMap := kubectlwait.UIDMap{} uidMap := cmdwait.UIDMap{}
err := r.Visit(func(info *resource.Info, err error) error { err := r.Visit(func(info *resource.Info, err error) error {
if err != nil { if err != nil {
return err return err
@@ -247,7 +247,7 @@ func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
if err != nil { if err != nil {
return err return err
} }
resourceLocation := kubectlwait.ResourceLocation{ resourceLocation := cmdwait.ResourceLocation{
GroupResource: info.Mapping.Resource.GroupResource(), GroupResource: info.Mapping.Resource.GroupResource(),
Namespace: info.Namespace, Namespace: info.Namespace,
Name: info.Name, Name: info.Name,
@@ -287,14 +287,14 @@ func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
// if we requested to wait forever, set it to a week. // if we requested to wait forever, set it to a week.
effectiveTimeout = 168 * time.Hour effectiveTimeout = 168 * time.Hour
} }
waitOptions := kubectlwait.WaitOptions{ waitOptions := cmdwait.WaitOptions{
ResourceFinder: genericclioptions.ResourceFinderForResult(resource.InfoListVisitor(deletedInfos)), ResourceFinder: genericclioptions.ResourceFinderForResult(resource.InfoListVisitor(deletedInfos)),
UIDMap: uidMap, UIDMap: uidMap,
DynamicClient: o.DynamicClient, DynamicClient: o.DynamicClient,
Timeout: effectiveTimeout, Timeout: effectiveTimeout,
Printer: printers.NewDiscardingPrinter(), Printer: printers.NewDiscardingPrinter(),
ConditionFn: kubectlwait.IsDeleted, ConditionFn: cmdwait.IsDeleted,
IOStreams: o.IOStreams, IOStreams: o.IOStreams,
} }
err = waitOptions.RunWait() err = waitOptions.RunWait()
@@ -317,7 +317,7 @@ func (o *DeleteOptions) deleteResource(info *resource.Info, deleteOptions *metav
return deleteResponse, nil return deleteResponse, nil
} }
// deletion printing is special because we do not have an object to print. // PrintObj for deleted objects is special because we do not have an object to print.
// This mirrors name printer behavior // This mirrors name printer behavior
func (o *DeleteOptions) PrintObj(info *resource.Info) { func (o *DeleteOptions) PrintObj(info *resource.Info) {
operation := "deleted" operation := "deleted"

View File

@@ -25,7 +25,7 @@ import (
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
) )
// PrintFlags composes common printer flag structs // DeleteFlags composes common printer flag structs
// used for commands requiring deletion logic. // used for commands requiring deletion logic.
type DeleteFlags struct { type DeleteFlags struct {
FileNameFlags *genericclioptions.FileNameFlags FileNameFlags *genericclioptions.FileNameFlags

View File

@@ -105,7 +105,7 @@ func NewCmdDescribe(parent string, f cmdutil.Factory, streams genericclioptions.
Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)", Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Show details of a specific resource or group of resources"), Short: i18n.T("Show details of a specific resource or group of resources"),
Long: describeLong + "\n\n" + cmdutil.SuggestApiResources(parent), Long: describeLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
Example: describeExample, Example: describeExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
@@ -133,7 +133,7 @@ func (o *DescribeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
} }
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
return fmt.Errorf("You must specify the type of resource to describe. %s\n", cmdutil.SuggestApiResources(o.CmdParent)) return fmt.Errorf("You must specify the type of resource to describe. %s\n", cmdutil.SuggestAPIResources(o.CmdParent))
} }
o.BuilderArgs = args o.BuilderArgs = args

View File

@@ -84,79 +84,72 @@ const (
EvictionKind = "Eviction" EvictionKind = "Eviction"
EvictionSubresource = "pods/eviction" EvictionSubresource = "pods/eviction"
kDaemonsetFatal = "DaemonSet-managed pods (use --ignore-daemonsets to ignore)" daemonsetFatal = "DaemonSet-managed Pods (use --ignore-daemonsets to ignore)"
kDaemonsetWarning = "Ignoring DaemonSet-managed pods" daemonsetWarning = "ignoring DaemonSet-managed Pods"
kLocalStorageFatal = "pods with local storage (use --delete-local-data to override)" localStorageFatal = "Pods with local storage (use --delete-local-data to override)"
kLocalStorageWarning = "Deleting pods with local storage" localStorageWarning = "deleting Pods with local storage"
kUnmanagedFatal = "pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override)" unmanagedFatal = "Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override)"
kUnmanagedWarning = "Deleting pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet" unmanagedWarning = "deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet"
) )
var ( var (
cordon_long = templates.LongDesc(i18n.T(` cordonLong = templates.LongDesc(i18n.T(`
Mark node as unschedulable.`)) Mark node as unschedulable.`))
cordon_example = templates.Examples(i18n.T(` cordonExample = templates.Examples(i18n.T(`
# Mark node "foo" as unschedulable. # Mark node "foo" as unschedulable.
kubectl cordon foo`)) kubectl cordon foo`))
) )
func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdCordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &DrainOptions{ o := NewDrainOptions(f, ioStreams)
PrintFlags: genericclioptions.NewPrintFlags("cordoned").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "cordon NODE", Use: "cordon NODE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Mark node as unschedulable"), Short: i18n.T("Mark node as unschedulable"),
Long: cordon_long, Long: cordonLong,
Example: cordon_example, Example: cordonExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.RunCordonOrUncordon(true)) cmdutil.CheckErr(o.RunCordonOrUncordon(true))
}, },
} }
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on") cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on")
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
return cmd return cmd
} }
var ( var (
uncordon_long = templates.LongDesc(i18n.T(` uncordonLong = templates.LongDesc(i18n.T(`
Mark node as schedulable.`)) Mark node as schedulable.`))
uncordon_example = templates.Examples(i18n.T(` uncordonExample = templates.Examples(i18n.T(`
# Mark node "foo" as schedulable. # Mark node "foo" as schedulable.
$ kubectl uncordon foo`)) $ kubectl uncordon foo`))
) )
func NewCmdUncordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdUncordon(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &DrainOptions{ o := NewDrainOptions(f, ioStreams)
PrintFlags: genericclioptions.NewPrintFlags("uncordoned").WithTypeSetter(scheme.Scheme),
IOStreams: ioStreams,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "uncordon NODE", Use: "uncordon NODE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Mark node as schedulable"), Short: i18n.T("Mark node as schedulable"),
Long: uncordon_long, Long: uncordonLong,
Example: uncordon_example, Example: uncordonExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.RunCordonOrUncordon(false)) cmdutil.CheckErr(o.RunCordonOrUncordon(false))
}, },
} }
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on") cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on")
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
return cmd return cmd
} }
var ( var (
drain_long = templates.LongDesc(i18n.T(` drainLong = templates.LongDesc(i18n.T(`
Drain node in preparation for maintenance. Drain node in preparation for maintenance.
The given node will be marked unschedulable to prevent new pods from arriving. The given node will be marked unschedulable to prevent new pods from arriving.
@@ -181,7 +174,7 @@ var (
![Workflow](http://kubernetes.io/images/docs/kubectl_drain.svg)`)) ![Workflow](http://kubernetes.io/images/docs/kubectl_drain.svg)`))
drain_example = templates.Examples(i18n.T(` drainExample = templates.Examples(i18n.T(`
# Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet on it. # Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet on it.
$ kubectl drain foo --force $ kubectl drain foo --force
@@ -199,26 +192,26 @@ func NewDrainOptions(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *
} }
func NewCmdDrain(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command { func NewCmdDrain(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := NewDrainOptions(f, ioStreams) o := NewDrainOptions(f, ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "drain NODE", Use: "drain NODE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Drain node in preparation for maintenance"), Short: i18n.T("Drain node in preparation for maintenance"),
Long: drain_long, Long: drainLong,
Example: drain_example, Example: drainExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(options.RunDrain()) cmdutil.CheckErr(o.RunDrain())
}, },
} }
cmd.Flags().BoolVar(&options.Force, "force", options.Force, "Continue even if there are pods not managed by a ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet.") cmd.Flags().BoolVar(&o.Force, "force", o.Force, "Continue even if there are pods not managed by a ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet.")
cmd.Flags().BoolVar(&options.IgnoreDaemonsets, "ignore-daemonsets", options.IgnoreDaemonsets, "Ignore DaemonSet-managed pods.") cmd.Flags().BoolVar(&o.IgnoreDaemonsets, "ignore-daemonsets", o.IgnoreDaemonsets, "Ignore DaemonSet-managed pods.")
cmd.Flags().BoolVar(&options.DeleteLocalData, "delete-local-data", options.DeleteLocalData, "Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained).") cmd.Flags().BoolVar(&o.DeleteLocalData, "delete-local-data", o.DeleteLocalData, "Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained).")
cmd.Flags().IntVar(&options.GracePeriodSeconds, "grace-period", options.GracePeriodSeconds, "Period of time in seconds given to each pod to terminate gracefully. If negative, the default value specified in the pod will be used.") cmd.Flags().IntVar(&o.GracePeriodSeconds, "grace-period", o.GracePeriodSeconds, "Period of time in seconds given to each pod to terminate gracefully. If negative, the default value specified in the pod will be used.")
cmd.Flags().DurationVar(&options.Timeout, "timeout", options.Timeout, "The length of time to wait before giving up, zero means infinite") cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, "The length of time to wait before giving up, zero means infinite")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on") cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on")
cmd.Flags().StringVarP(&options.PodSelector, "pod-selector", "", options.PodSelector, "Label selector to filter pods on the node") cmd.Flags().StringVarP(&o.PodSelector, "pod-selector", "", o.PodSelector, "Label selector to filter pods on the node")
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
return cmd return cmd
@@ -386,10 +379,10 @@ func (o *DrainOptions) unreplicatedFilter(pod corev1.Pod) (bool, *warning, *fata
return true, nil, nil return true, nil, nil
} }
if o.Force { if o.Force {
return true, &warning{kUnmanagedWarning}, nil return true, &warning{unmanagedWarning}, nil
} }
return false, nil, &fatal{kUnmanagedFatal} return false, nil, &fatal{unmanagedFatal}
} }
func (o *DrainOptions) daemonsetFilter(pod corev1.Pod) (bool, *warning, *fatal) { func (o *DrainOptions) daemonsetFilter(pod corev1.Pod) (bool, *warning, *fatal) {
@@ -418,10 +411,10 @@ func (o *DrainOptions) daemonsetFilter(pod corev1.Pod) (bool, *warning, *fatal)
} }
if !o.IgnoreDaemonsets { if !o.IgnoreDaemonsets {
return false, nil, &fatal{kDaemonsetFatal} return false, nil, &fatal{daemonsetFatal}
} }
return false, &warning{kDaemonsetWarning}, nil return false, &warning{daemonsetWarning}, nil
} }
func mirrorPodFilter(pod corev1.Pod) (bool, *warning, *fatal) { func mirrorPodFilter(pod corev1.Pod) (bool, *warning, *fatal) {
@@ -450,10 +443,10 @@ func (o *DrainOptions) localStorageFilter(pod corev1.Pod) (bool, *warning, *fata
return true, nil, nil return true, nil, nil
} }
if !o.DeleteLocalData { if !o.DeleteLocalData {
return false, nil, &fatal{kLocalStorageFatal} return false, nil, &fatal{localStorageFatal}
} }
return true, &warning{kLocalStorageWarning}, nil return true, &warning{localStorageWarning}, nil
} }
// Map of status message to a list of pod names having that status. // Map of status message to a list of pod names having that status.

View File

@@ -57,7 +57,7 @@ const (
) )
var node *corev1.Node var node *corev1.Node
var cordoned_node *corev1.Node var cordonedNode *corev1.Node
func boolptr(b bool) *bool { return &b } func boolptr(b bool) *bool { return &b }
@@ -72,8 +72,8 @@ func TestMain(m *testing.M) {
} }
// A copy of the same node, but cordoned. // A copy of the same node, but cordoned.
cordoned_node = node.DeepCopy() cordonedNode = node.DeepCopy()
cordoned_node.Spec.Unschedulable = true cordonedNode.Spec.Unschedulable = true
os.Exit(m.Run()) os.Exit(m.Run())
} }
@@ -88,7 +88,7 @@ func TestCordon(t *testing.T) {
}{ }{
{ {
description: "node/node syntax", description: "node/node syntax",
node: cordoned_node, node: cordonedNode,
expected: node, expected: node,
cmd: NewCmdUncordon, cmd: NewCmdUncordon,
arg: "node/node", arg: "node/node",
@@ -96,7 +96,7 @@ func TestCordon(t *testing.T) {
}, },
{ {
description: "uncordon for real", description: "uncordon for real",
node: cordoned_node, node: cordonedNode,
expected: node, expected: node,
cmd: NewCmdUncordon, cmd: NewCmdUncordon,
arg: "node", arg: "node",
@@ -112,8 +112,8 @@ func TestCordon(t *testing.T) {
}, },
{ {
description: "cordon does nothing", description: "cordon does nothing",
node: cordoned_node, node: cordonedNode,
expected: cordoned_node, expected: cordonedNode,
cmd: NewCmdCordon, cmd: NewCmdCordon,
arg: "node", arg: "node",
expectFatal: false, expectFatal: false,
@@ -121,7 +121,7 @@ func TestCordon(t *testing.T) {
{ {
description: "cordon for real", description: "cordon for real",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
cmd: NewCmdCordon, cmd: NewCmdCordon,
arg: "node", arg: "node",
expectFatal: false, expectFatal: false,
@@ -145,14 +145,14 @@ func TestCordon(t *testing.T) {
{ {
description: "cordon for multiple nodes", description: "cordon for multiple nodes",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
cmd: NewCmdCordon, cmd: NewCmdCordon,
arg: "node node1 node2", arg: "node node1 node2",
expectFatal: false, expectFatal: false,
}, },
{ {
description: "uncordon for multiple nodes", description: "uncordon for multiple nodes",
node: cordoned_node, node: cordonedNode,
expected: node, expected: node,
cmd: NewCmdUncordon, cmd: NewCmdUncordon,
arg: "node node1 node2", arg: "node node1 node2",
@@ -168,7 +168,7 @@ func TestCordon(t *testing.T) {
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...) codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
ns := scheme.Codecs ns := scheme.Codecs
new_node := &corev1.Node{} newNode := &corev1.Node{}
updated := false updated := false
tf.Client = &fake.RESTClient{ tf.Client = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"}, GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
@@ -202,14 +202,14 @@ func TestCordon(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil { if err := runtime.DecodeInto(codec, appliedPatch, newNode); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) { if !reflect.DeepEqual(test.expected.Spec, newNode.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, new_node.Spec.Unschedulable) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec.Unschedulable, newNode.Spec.Unschedulable)
} }
updated = true updated = true
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, newNode)}, nil
default: default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req) t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil return nil, nil
@@ -221,7 +221,7 @@ func TestCordon(t *testing.T) {
ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() ioStreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := test.cmd(tf, ioStreams) cmd := test.cmd(tf, ioStreams)
saw_fatal := false sawFatal := false
func() { func() {
defer func() { defer func() {
// Recover from the panic below. // Recover from the panic below.
@@ -230,7 +230,7 @@ func TestCordon(t *testing.T) {
cmdutil.DefaultBehaviorOnFatal() cmdutil.DefaultBehaviorOnFatal()
}() }()
cmdutil.BehaviorOnFatal(func(e string, code int) { cmdutil.BehaviorOnFatal(func(e string, code int) {
saw_fatal = true sawFatal = true
panic(e) panic(e)
}) })
cmd.SetArgs(strings.Split(test.arg, " ")) cmd.SetArgs(strings.Split(test.arg, " "))
@@ -238,7 +238,7 @@ func TestCordon(t *testing.T) {
}() }()
if test.expectFatal { if test.expectFatal {
if !saw_fatal { if !sawFatal {
t.Fatalf("%s: unexpected non-error", test.description) t.Fatalf("%s: unexpected non-error", test.description)
} }
if updated { if updated {
@@ -246,7 +246,7 @@ func TestCordon(t *testing.T) {
} }
} }
if !test.expectFatal && saw_fatal { if !test.expectFatal && sawFatal {
t.Fatalf("%s: unexpected error", test.description) t.Fatalf("%s: unexpected error", test.description)
} }
if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated { if !reflect.DeepEqual(test.expected.Spec, test.node.Spec) && !updated {
@@ -272,7 +272,7 @@ func TestDrain(t *testing.T) {
}, },
} }
rc_pod := corev1.Pod{ rcPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -305,7 +305,7 @@ func TestDrain(t *testing.T) {
}, },
} }
ds_pod := corev1.Pod{ dsPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -326,7 +326,7 @@ func TestDrain(t *testing.T) {
}, },
} }
ds_terminated_pod := corev1.Pod{ dsTerminatedPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -350,7 +350,7 @@ func TestDrain(t *testing.T) {
}, },
} }
ds_pod_with_emptyDir := corev1.Pod{ dsPodWithEmptyDir := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -377,7 +377,7 @@ func TestDrain(t *testing.T) {
}, },
} }
orphaned_ds_pod := corev1.Pod{ orphanedDsPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -400,7 +400,7 @@ func TestDrain(t *testing.T) {
}, },
} }
job_pod := corev1.Pod{ jobPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -427,7 +427,7 @@ func TestDrain(t *testing.T) {
}, },
} }
terminated_job_pod_with_local_storage := corev1.Pod{ terminatedJobPodWithLocalStorage := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -469,7 +469,7 @@ func TestDrain(t *testing.T) {
}, },
} }
rs_pod := corev1.Pod{ rsPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -490,7 +490,7 @@ func TestDrain(t *testing.T) {
}, },
} }
naked_pod := corev1.Pod{ nakedPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -502,7 +502,7 @@ func TestDrain(t *testing.T) {
}, },
} }
emptydir_pod := corev1.Pod{ emptydirPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -519,7 +519,7 @@ func TestDrain(t *testing.T) {
}, },
}, },
} }
emptydir_terminated_pod := corev1.Pod{ emptydirTerminatedPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "bar", Name: "bar",
Namespace: "default", Namespace: "default",
@@ -555,8 +555,8 @@ func TestDrain(t *testing.T) {
{ {
description: "RC-managed pod", description: "RC-managed pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{rc_pod}, pods: []corev1.Pod{rcPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
expectFatal: false, expectFatal: false,
@@ -565,8 +565,8 @@ func TestDrain(t *testing.T) {
{ {
description: "DS-managed pod", description: "DS-managed pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{ds_pod}, pods: []corev1.Pod{dsPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
expectFatal: true, expectFatal: true,
@@ -575,8 +575,8 @@ func TestDrain(t *testing.T) {
{ {
description: "DS-managed terminated pod", description: "DS-managed terminated pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{ds_terminated_pod}, pods: []corev1.Pod{dsTerminatedPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
expectFatal: false, expectFatal: false,
@@ -585,8 +585,8 @@ func TestDrain(t *testing.T) {
{ {
description: "orphaned DS-managed pod", description: "orphaned DS-managed pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{orphaned_ds_pod}, pods: []corev1.Pod{orphanedDsPod},
rcs: []corev1.ReplicationController{}, rcs: []corev1.ReplicationController{},
args: []string{"node"}, args: []string{"node"},
expectFatal: true, expectFatal: true,
@@ -595,8 +595,8 @@ func TestDrain(t *testing.T) {
{ {
description: "orphaned DS-managed pod with --force", description: "orphaned DS-managed pod with --force",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{orphaned_ds_pod}, pods: []corev1.Pod{orphanedDsPod},
rcs: []corev1.ReplicationController{}, rcs: []corev1.ReplicationController{},
args: []string{"node", "--force"}, args: []string{"node", "--force"},
expectFatal: false, expectFatal: false,
@@ -605,8 +605,8 @@ func TestDrain(t *testing.T) {
{ {
description: "DS-managed pod with --ignore-daemonsets", description: "DS-managed pod with --ignore-daemonsets",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{ds_pod}, pods: []corev1.Pod{dsPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node", "--ignore-daemonsets"}, args: []string{"node", "--ignore-daemonsets"},
expectFatal: false, expectFatal: false,
@@ -615,19 +615,19 @@ func TestDrain(t *testing.T) {
{ {
description: "DS-managed pod with emptyDir with --ignore-daemonsets", description: "DS-managed pod with emptyDir with --ignore-daemonsets",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{ds_pod_with_emptyDir}, pods: []corev1.Pod{dsPodWithEmptyDir},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node", "--ignore-daemonsets"}, args: []string{"node", "--ignore-daemonsets"},
expectWarning: "WARNING: Ignoring DaemonSet-managed pods: bar", expectWarning: "WARNING: ignoring DaemonSet-managed Pods: bar",
expectFatal: false, expectFatal: false,
expectDelete: false, expectDelete: false,
}, },
{ {
description: "Job-managed pod with local storage", description: "Job-managed pod with local storage",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{job_pod}, pods: []corev1.Pod{jobPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node", "--force", "--delete-local-data=true"}, args: []string{"node", "--force", "--delete-local-data=true"},
expectFatal: false, expectFatal: false,
@@ -636,8 +636,8 @@ func TestDrain(t *testing.T) {
{ {
description: "Job-managed terminated pod", description: "Job-managed terminated pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{terminated_job_pod_with_local_storage}, pods: []corev1.Pod{terminatedJobPodWithLocalStorage},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
expectFatal: false, expectFatal: false,
@@ -646,8 +646,8 @@ func TestDrain(t *testing.T) {
{ {
description: "RS-managed pod", description: "RS-managed pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{rs_pod}, pods: []corev1.Pod{rsPod},
replicaSets: []extensionsv1beta1.ReplicaSet{rs}, replicaSets: []extensionsv1beta1.ReplicaSet{rs},
args: []string{"node"}, args: []string{"node"},
expectFatal: false, expectFatal: false,
@@ -656,8 +656,8 @@ func TestDrain(t *testing.T) {
{ {
description: "naked pod", description: "naked pod",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{naked_pod}, pods: []corev1.Pod{nakedPod},
rcs: []corev1.ReplicationController{}, rcs: []corev1.ReplicationController{},
args: []string{"node"}, args: []string{"node"},
expectFatal: true, expectFatal: true,
@@ -666,8 +666,8 @@ func TestDrain(t *testing.T) {
{ {
description: "naked pod with --force", description: "naked pod with --force",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{naked_pod}, pods: []corev1.Pod{nakedPod},
rcs: []corev1.ReplicationController{}, rcs: []corev1.ReplicationController{},
args: []string{"node", "--force"}, args: []string{"node", "--force"},
expectFatal: false, expectFatal: false,
@@ -676,8 +676,8 @@ func TestDrain(t *testing.T) {
{ {
description: "pod with EmptyDir", description: "pod with EmptyDir",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{emptydir_pod}, pods: []corev1.Pod{emptydirPod},
args: []string{"node", "--force"}, args: []string{"node", "--force"},
expectFatal: true, expectFatal: true,
expectDelete: false, expectDelete: false,
@@ -685,8 +685,8 @@ func TestDrain(t *testing.T) {
{ {
description: "terminated pod with emptyDir", description: "terminated pod with emptyDir",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{emptydir_terminated_pod}, pods: []corev1.Pod{emptydirTerminatedPod},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
expectFatal: false, expectFatal: false,
@@ -695,8 +695,8 @@ func TestDrain(t *testing.T) {
{ {
description: "pod with EmptyDir and --delete-local-data", description: "pod with EmptyDir and --delete-local-data",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{emptydir_pod}, pods: []corev1.Pod{emptydirPod},
args: []string{"node", "--force", "--delete-local-data=true"}, args: []string{"node", "--force", "--delete-local-data=true"},
expectFatal: false, expectFatal: false,
expectDelete: true, expectDelete: true,
@@ -704,7 +704,7 @@ func TestDrain(t *testing.T) {
{ {
description: "empty node", description: "empty node",
node: node, node: node,
expected: cordoned_node, expected: cordonedNode,
pods: []corev1.Pod{}, pods: []corev1.Pod{},
rcs: []corev1.ReplicationController{rc}, rcs: []corev1.ReplicationController{rc},
args: []string{"node"}, args: []string{"node"},
@@ -724,7 +724,7 @@ func TestDrain(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
new_node := &corev1.Node{} newNode := &corev1.Node{}
deleted := false deleted := false
evicted := false evicted := false
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
@@ -788,10 +788,10 @@ func TestDrain(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
get_params := make(url.Values) getParams := make(url.Values)
get_params["fieldSelector"] = []string{"spec.nodeName=node"} getParams["fieldSelector"] = []string{"spec.nodeName=node"}
if !reflect.DeepEqual(get_params, values) { if !reflect.DeepEqual(getParams, values) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, get_params, values) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, getParams, values)
} }
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &corev1.PodList{Items: test.pods})}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &corev1.PodList{Items: test.pods})}, nil
case m.isFor("GET", "/replicationcontrollers"): case m.isFor("GET", "/replicationcontrollers"):
@@ -810,13 +810,13 @@ func TestDrain(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil { if err := runtime.DecodeInto(codec, appliedPatch, newNode); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if !reflect.DeepEqual(test.expected.Spec, new_node.Spec) { if !reflect.DeepEqual(test.expected.Spec, newNode.Spec) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, new_node.Spec) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, test.expected.Spec, newNode.Spec)
} }
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, newNode)}, nil
case m.isFor("DELETE", "/namespaces/default/pods/bar"): case m.isFor("DELETE", "/namespaces/default/pods/bar"):
deleted = true deleted = true
return &http.Response{StatusCode: 204, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &test.pods[0])}, nil return &http.Response{StatusCode: 204, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, &test.pods[0])}, nil
@@ -834,8 +834,8 @@ func TestDrain(t *testing.T) {
ioStreams, _, _, errBuf := genericclioptions.NewTestIOStreams() ioStreams, _, _, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdDrain(tf, ioStreams) cmd := NewCmdDrain(tf, ioStreams)
saw_fatal := false sawFatal := false
fatal_msg := "" fatalMsg := ""
func() { func() {
defer func() { defer func() {
// Recover from the panic below. // Recover from the panic below.
@@ -843,17 +843,17 @@ func TestDrain(t *testing.T) {
// Restore cmdutil behavior // Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal() cmdutil.DefaultBehaviorOnFatal()
}() }()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; fatal_msg = e; panic(e) }) cmdutil.BehaviorOnFatal(func(e string, code int) { sawFatal = true; fatalMsg = e; panic(e) })
cmd.SetArgs(test.args) cmd.SetArgs(test.args)
cmd.Execute() cmd.Execute()
}() }()
if test.expectFatal { if test.expectFatal {
if !saw_fatal { if !sawFatal {
t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod) t.Fatalf("%s: unexpected non-error when using %s", test.description, currMethod)
} }
} else { } else {
if saw_fatal { if sawFatal {
t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatal_msg) t.Fatalf("%s: unexpected error when using %s: %s", test.description, currMethod, fatalMsg)
} }
} }

View File

@@ -4,7 +4,7 @@ args:
- configmap - configmap
namespace: "edit-test" namespace: "edit-test"
expectedStderr: expectedStderr:
- edit cancelled, no objects found. - edit cancelled, no objects found
expectedExitCode: 1 expectedExitCode: 1
steps: steps:
- type: request - type: request

View File

@@ -39,7 +39,7 @@ import (
) )
var ( var (
exec_example = templates.Examples(i18n.T(` execExample = templates.Examples(i18n.T(`
# Get output from running 'date' from pod 123456-7890, using the first container by default # Get output from running 'date' from pod 123456-7890, using the first container by default
kubectl exec 123456-7890 date kubectl exec 123456-7890 date
@@ -76,7 +76,7 @@ func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Execute a command in a container"), Short: i18n.T("Execute a command in a container"),
Long: "Execute a command in a container.", Long: "Execute a command in a container.",
Example: exec_example, Example: execExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
argsLenAtDash := cmd.ArgsLenAtDash() argsLenAtDash := cmd.ArgsLenAtDash()
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash)) cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))

View File

@@ -55,7 +55,7 @@ type ExplainOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
CmdParent string CmdParent string
ApiVersion string APIVersion string
Recursive bool Recursive bool
Mapper meta.RESTMapper Mapper meta.RESTMapper
@@ -77,7 +77,7 @@ func NewCmdExplain(parent string, f cmdutil.Factory, streams genericclioptions.I
Use: "explain RESOURCE", Use: "explain RESOURCE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Documentation of resources"), Short: i18n.T("Documentation of resources"),
Long: explainLong + "\n\n" + cmdutil.SuggestApiResources(parent), Long: explainLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
Example: explainExamples, Example: explainExamples,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd)) cmdutil.CheckErr(o.Complete(f, cmd))
@@ -86,7 +86,7 @@ func NewCmdExplain(parent string, f cmdutil.Factory, streams genericclioptions.I
}, },
} }
cmd.Flags().BoolVar(&o.Recursive, "recursive", o.Recursive, "Print the fields of fields (Currently only 1 level deep)") cmd.Flags().BoolVar(&o.Recursive, "recursive", o.Recursive, "Print the fields of fields (Currently only 1 level deep)")
cmd.Flags().StringVar(&o.ApiVersion, "api-version", o.ApiVersion, "Get different explanations for particular API version") cmd.Flags().StringVar(&o.APIVersion, "api-version", o.APIVersion, "Get different explanations for particular API version")
return cmd return cmd
} }
@@ -106,7 +106,7 @@ func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
func (o *ExplainOptions) Validate(args []string) error { func (o *ExplainOptions) Validate(args []string) error {
if len(args) == 0 { if len(args) == 0 {
return fmt.Errorf("You must specify the type of resource to explain. %s\n", cmdutil.SuggestApiResources(o.CmdParent)) return fmt.Errorf("You must specify the type of resource to explain. %s\n", cmdutil.SuggestAPIResources(o.CmdParent))
} }
if len(args) > 1 { if len(args) > 1 {
return fmt.Errorf("We accept only this format: explain RESOURCE\n") return fmt.Errorf("We accept only this format: explain RESOURCE\n")
@@ -118,7 +118,7 @@ func (o *ExplainOptions) Validate(args []string) error {
// Run executes the appropriate steps to print a model's documentation // Run executes the appropriate steps to print a model's documentation
func (o *ExplainOptions) Run(args []string) error { func (o *ExplainOptions) Run(args []string) error {
recursive := o.Recursive recursive := o.Recursive
apiVersionString := o.ApiVersion apiVersionString := o.APIVersion
// TODO: After we figured out the new syntax to separate group and resource, allow // TODO: After we figured out the new syntax to separate group and resource, allow
// the users to use it in explain (kubectl explain <group><syntax><resource>). // the users to use it in explain (kubectl explain <group><syntax><resource>).

View File

@@ -153,7 +153,7 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStr
Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags]", Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Display one or many resources"), Short: i18n.T("Display one or many resources"),
Long: getLong + "\n\n" + cmdutil.SuggestApiResources(parent), Long: getLong + "\n\n" + cmdutil.SuggestAPIResources(parent),
Example: getExample, Example: getExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
@@ -261,7 +261,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, len(args) == 2) o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, len(args) == 2)
default: default:
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.SuggestApiResources(o.CmdParent)) fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.SuggestAPIResources(o.CmdParent))
fullCmdName := cmd.Parent().CommandPath() fullCmdName := cmd.Parent().CommandPath()
usageString := "Required resource not specified." usageString := "Required resource not specified."
if len(fullCmdName) > 0 && cmdutil.IsSiblingCommandExists(cmd, "explain") { if len(fullCmdName) > 0 && cmdutil.IsSiblingCommandExists(cmd, "explain") {
@@ -296,16 +296,20 @@ func (o *GetOptions) Validate(cmd *cobra.Command) error {
return nil return nil
} }
// OriginalPositioner and NopPositioner is required for swap/sort operations of data in table format
type OriginalPositioner interface { type OriginalPositioner interface {
OriginalPosition(int) int OriginalPosition(int) int
} }
// NopPositioner and OriginalPositioner is required for swap/sort operations of data in table format
type NopPositioner struct{} type NopPositioner struct{}
// OriginalPosition returns the original position from NopPositioner object
func (t *NopPositioner) OriginalPosition(ix int) int { func (t *NopPositioner) OriginalPosition(ix int) int {
return ix return ix
} }
// RuntimeSorter holds the required objects to perform sorting of runtime objects
type RuntimeSorter struct { type RuntimeSorter struct {
field string field string
decoder runtime.Decoder decoder runtime.Decoder
@@ -313,6 +317,7 @@ type RuntimeSorter struct {
positioner OriginalPositioner positioner OriginalPositioner
} }
// Sort performs the sorting of runtime objects
func (r *RuntimeSorter) Sort() error { func (r *RuntimeSorter) Sort() error {
// a list is only considered "sorted" if there are 0 or 1 items in it // a list is only considered "sorted" if there are 0 or 1 items in it
// AND (if 1 item) the item is not a Table object // AND (if 1 item) the item is not a Table object
@@ -363,6 +368,7 @@ func (r *RuntimeSorter) Sort() error {
return nil return nil
} }
// OriginalPosition returns the original position of a runtime object
func (r *RuntimeSorter) OriginalPosition(ix int) int { func (r *RuntimeSorter) OriginalPosition(ix int) int {
if r.positioner == nil { if r.positioner == nil {
return 0 return 0
@@ -370,12 +376,13 @@ func (r *RuntimeSorter) OriginalPosition(ix int) int {
return r.positioner.OriginalPosition(ix) return r.positioner.OriginalPosition(ix)
} }
// allows custom decoder to be set for testing // WithDecoder allows custom decoder to be set for testing
func (r *RuntimeSorter) WithDecoder(decoder runtime.Decoder) *RuntimeSorter { func (r *RuntimeSorter) WithDecoder(decoder runtime.Decoder) *RuntimeSorter {
r.decoder = decoder r.decoder = decoder
return r return r
} }
// NewRuntimeSorter returns a new instance of RuntimeSorter
func NewRuntimeSorter(objects []runtime.Object, sortBy string) *RuntimeSorter { func NewRuntimeSorter(objects []runtime.Object, sortBy string) *RuntimeSorter {
parsedField, err := RelaxedJSONPathExpression(sortBy) parsedField, err := RelaxedJSONPathExpression(sortBy)
if err != nil { if err != nil {

View File

@@ -64,6 +64,7 @@ func (f *PrintFlags) Copy() PrintFlags {
return printFlags return printFlags
} }
// AllowedFormats is the list of formats in which data can be displayed
func (f *PrintFlags) AllowedFormats() []string { func (f *PrintFlags) AllowedFormats() []string {
formats := f.JSONYamlPrintFlags.AllowedFormats() formats := f.JSONYamlPrintFlags.AllowedFormats()
formats = append(formats, f.NamePrintFlags.AllowedFormats()...) formats = append(formats, f.NamePrintFlags.AllowedFormats()...)

View File

@@ -61,6 +61,7 @@ func (f *HumanPrintFlags) EnsureWithNamespace() error {
return nil return nil
} }
// AllowedFormats returns more customized formating options
func (f *HumanPrintFlags) AllowedFormats() []string { func (f *HumanPrintFlags) AllowedFormats() []string {
return []string{"wide"} return []string{"wide"}
} }

View File

@@ -344,8 +344,7 @@ func (o *LabelOptions) RunLabel() error {
if err != nil { if err != nil {
return err return err
} }
printer.PrintObj(info.Object, o.Out) return printer.PrintObj(info.Object, o.Out)
return nil
}) })
} }

View File

@@ -34,13 +34,13 @@ import (
) )
var ( var (
plugin_long = templates.LongDesc(` pluginLong = templates.LongDesc(`
Provides utilities for interacting with plugins. Provides utilities for interacting with plugins.
Plugins provide extended functionality that is not part of the major command-line distribution. Plugins provide extended functionality that is not part of the major command-line distribution.
Please refer to the documentation and examples for more information about how write your own plugins.`) Please refer to the documentation and examples for more information about how write your own plugins.`)
plugin_list_long = templates.LongDesc(` pluginListLong = templates.LongDesc(`
List all available plugin files on a user's PATH. List all available plugin files on a user's PATH.
Available plugin files are those that are: Available plugin files are those that are:
@@ -55,7 +55,7 @@ func NewCmdPlugin(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
Use: "plugin [flags]", Use: "plugin [flags]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Provides utilities for interacting with plugins."), Short: i18n.T("Provides utilities for interacting with plugins."),
Long: plugin_long, Long: pluginLong,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args) cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args)
}, },
@@ -81,7 +81,7 @@ func NewCmdPluginList(f cmdutil.Factory, streams genericclioptions.IOStreams) *c
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "list", Use: "list",
Short: "list all visible plugin executables on a user's PATH", Short: "list all visible plugin executables on a user's PATH",
Long: plugin_list_long, Long: pluginListLong,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(cmd)) cmdutil.CheckErr(o.Complete(cmd))
cmdutil.CheckErr(o.Run()) cmdutil.CheckErr(o.Run())

View File

@@ -27,17 +27,17 @@ import (
) )
var ( var (
rollout_long = templates.LongDesc(` rolloutLong = templates.LongDesc(`
Manage the rollout of a resource.` + rollout_valid_resources) Manage the rollout of a resource.` + rolloutValidResources)
rollout_example = templates.Examples(` rolloutExample = templates.Examples(`
# Rollback to the previous deployment # Rollback to the previous deployment
kubectl rollout undo deployment/abc kubectl rollout undo deployment/abc
# Check the rollout status of a daemonset # Check the rollout status of a daemonset
kubectl rollout status daemonset/foo`) kubectl rollout status daemonset/foo`)
rollout_valid_resources = dedent.Dedent(` rolloutValidResources = dedent.Dedent(`
Valid resource types include: Valid resource types include:
* deployments * deployments
@@ -46,13 +46,14 @@ var (
`) `)
) )
// NewCmdRollout returns a Command instance for 'rollout' sub command
func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "rollout SUBCOMMAND", Use: "rollout SUBCOMMAND",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Manage the rollout of a resource"), Short: i18n.T("Manage the rollout of a resource"),
Long: rollout_long, Long: rolloutLong,
Example: rollout_example, Example: rolloutExample,
Run: cmdutil.DefaultSubCommandRun(streams.Out), Run: cmdutil.DefaultSubCommandRun(streams.Out),
} }
// subcommands // subcommands

View File

@@ -32,10 +32,10 @@ import (
) )
var ( var (
history_long = templates.LongDesc(` historyLong = templates.LongDesc(`
View previous rollout revisions and configurations.`) View previous rollout revisions and configurations.`)
history_example = templates.Examples(` historyExample = templates.Examples(`
# View the rollout history of a deployment # View the rollout history of a deployment
kubectl rollout history deployment/abc kubectl rollout history deployment/abc
@@ -43,6 +43,7 @@ var (
kubectl rollout history daemonset/abc --revision=3`) kubectl rollout history daemonset/abc --revision=3`)
) )
// RolloutHistoryOptions holds the options for 'rollout history' sub command
type RolloutHistoryOptions struct { type RolloutHistoryOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error) ToPrinter func(string) (printers.ResourcePrinter, error)
@@ -61,6 +62,7 @@ type RolloutHistoryOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewRolloutHistoryOptions returns an initialized RolloutHistoryOptions instance
func NewRolloutHistoryOptions(streams genericclioptions.IOStreams) *RolloutHistoryOptions { func NewRolloutHistoryOptions(streams genericclioptions.IOStreams) *RolloutHistoryOptions {
return &RolloutHistoryOptions{ return &RolloutHistoryOptions{
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
@@ -68,6 +70,7 @@ func NewRolloutHistoryOptions(streams genericclioptions.IOStreams) *RolloutHisto
} }
} }
// NewCmdRolloutHistory returns a Command instance for RolloutHistory sub command
func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutHistoryOptions(streams) o := NewRolloutHistoryOptions(streams)
@@ -77,8 +80,8 @@ func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams
Use: "history (TYPE NAME | TYPE/NAME) [flags]", Use: "history (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("View rollout history"), Short: i18n.T("View rollout history"),
Long: history_long, Long: historyLong,
Example: history_example, Example: historyExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -97,6 +100,7 @@ func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams
return cmd return cmd
} }
// Complete completes al the required options
func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args o.Resources = args
@@ -117,6 +121,7 @@ func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command,
return nil return nil
} }
// Validate makes sure all the provided values for command-line options are valid
func (o *RolloutHistoryOptions) Validate() error { func (o *RolloutHistoryOptions) Validate() error {
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return fmt.Errorf("required resource not specified") return fmt.Errorf("required resource not specified")
@@ -128,6 +133,7 @@ func (o *RolloutHistoryOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of 'rollout history' sub command
func (o *RolloutHistoryOptions) Run() error { func (o *RolloutHistoryOptions) Run() error {
r := o.Builder(). r := o.Builder().

View File

@@ -51,20 +51,21 @@ type PauseOptions struct {
} }
var ( var (
pause_long = templates.LongDesc(` pauseLong = templates.LongDesc(`
Mark the provided resource as paused Mark the provided resource as paused
Paused resources will not be reconciled by a controller. Paused resources will not be reconciled by a controller.
Use "kubectl rollout resume" to resume a paused resource. Use "kubectl rollout resume" to resume a paused resource.
Currently only deployments support being paused.`) Currently only deployments support being paused.`)
pause_example = templates.Examples(` pauseExample = templates.Examples(`
# Mark the nginx deployment as paused. Any current state of # Mark the nginx deployment as paused. Any current state of
# the deployment will continue its function, new updates to the deployment will not # the deployment will continue its function, new updates to the deployment will not
# have an effect as long as the deployment is paused. # have an effect as long as the deployment is paused.
kubectl rollout pause deployment/nginx`) kubectl rollout pause deployment/nginx`)
) )
// NewCmdRolloutPause returns a Command instance for 'rollout pause' sub command
func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &PauseOptions{ o := &PauseOptions{
PrintFlags: genericclioptions.NewPrintFlags("paused").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("paused").WithTypeSetter(scheme.Scheme),
@@ -77,8 +78,8 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
Use: "pause RESOURCE", Use: "pause RESOURCE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Mark the provided resource as paused"), Short: i18n.T("Mark the provided resource as paused"),
Long: pause_long, Long: pauseLong,
Example: pause_example, Example: pauseExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -94,6 +95,7 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
return cmd return cmd
} }
// Complete completes all the required options
func (o *PauseOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *PauseOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Pauser = polymorphichelpers.ObjectPauserFn o.Pauser = polymorphichelpers.ObjectPauserFn
@@ -121,7 +123,8 @@ func (o *PauseOptions) Validate() error {
return nil return nil
} }
func (o PauseOptions) RunPause() error { // RunPause performs the execution of 'rollout pause' sub command
func (o *PauseOptions) RunPause() error {
r := o.Builder(). r := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace(). NamespaceParam(o.Namespace).DefaultNamespace().

View File

@@ -52,18 +52,19 @@ type ResumeOptions struct {
} }
var ( var (
resume_long = templates.LongDesc(` resumeLong = templates.LongDesc(`
Resume a paused resource Resume a paused resource
Paused resources will not be reconciled by a controller. By resuming a Paused resources will not be reconciled by a controller. By resuming a
resource, we allow it to be reconciled again. resource, we allow it to be reconciled again.
Currently only deployments support being resumed.`) Currently only deployments support being resumed.`)
resume_example = templates.Examples(` resumeExample = templates.Examples(`
# Resume an already paused deployment # Resume an already paused deployment
kubectl rollout resume deployment/nginx`) kubectl rollout resume deployment/nginx`)
) )
// NewRolloutResumeOptions returns an initialized ResumeOptions instance
func NewRolloutResumeOptions(streams genericclioptions.IOStreams) *ResumeOptions { func NewRolloutResumeOptions(streams genericclioptions.IOStreams) *ResumeOptions {
return &ResumeOptions{ return &ResumeOptions{
PrintFlags: genericclioptions.NewPrintFlags("resumed").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("resumed").WithTypeSetter(scheme.Scheme),
@@ -71,6 +72,7 @@ func NewRolloutResumeOptions(streams genericclioptions.IOStreams) *ResumeOptions
} }
} }
// NewCmdRolloutResume returns a Command instance for 'rollout resume' sub command
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutResumeOptions(streams) o := NewRolloutResumeOptions(streams)
@@ -80,8 +82,8 @@ func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams)
Use: "resume RESOURCE", Use: "resume RESOURCE",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Resume a paused resource"), Short: i18n.T("Resume a paused resource"),
Long: resume_long, Long: resumeLong,
Example: resume_example, Example: resumeExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -96,6 +98,7 @@ func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams)
return cmd return cmd
} }
// Complete completes all the required options
func (o *ResumeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *ResumeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args o.Resources = args
@@ -124,6 +127,7 @@ func (o *ResumeOptions) Validate() error {
return nil return nil
} }
// RunResume performs the execution of 'rollout resume' sub command
func (o ResumeOptions) RunResume() error { func (o ResumeOptions) RunResume() error {
r := o.Builder(). r := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).

View File

@@ -45,7 +45,7 @@ import (
) )
var ( var (
status_long = templates.LongDesc(` statusLong = templates.LongDesc(`
Show the status of the rollout. Show the status of the rollout.
By default 'rollout status' will watch the status of the latest rollout By default 'rollout status' will watch the status of the latest rollout
@@ -55,11 +55,12 @@ var (
pin to a specific revision and abort if it is rolled over by another revision, pin to a specific revision and abort if it is rolled over by another revision,
use --revision=N where N is the revision you need to watch for.`) use --revision=N where N is the revision you need to watch for.`)
status_example = templates.Examples(` statusExample = templates.Examples(`
# Watch the rollout status of a deployment # Watch the rollout status of a deployment
kubectl rollout status deployment/nginx`) kubectl rollout status deployment/nginx`)
) )
// RolloutStatusOptions holds the command-line options for 'rollout status' sub command
type RolloutStatusOptions struct { type RolloutStatusOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
@@ -79,6 +80,7 @@ type RolloutStatusOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewRolloutStatusOptions returns an initialized RolloutStatusOptions instance
func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatusOptions { func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatusOptions {
return &RolloutStatusOptions{ return &RolloutStatusOptions{
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
@@ -89,6 +91,7 @@ func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatus
} }
} }
// NewCmdRolloutStatus returns a Command instance for the 'rollout status' sub command
func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutStatusOptions(streams) o := NewRolloutStatusOptions(streams)
@@ -98,8 +101,8 @@ func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams)
Use: "status (TYPE NAME | TYPE/NAME) [flags]", Use: "status (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Show the status of the rollout"), Short: i18n.T("Show the status of the rollout"),
Long: status_long, Long: statusLong,
Example: status_example, Example: statusExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, args)) cmdutil.CheckErr(o.Complete(f, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -117,6 +120,7 @@ func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams)
return cmd return cmd
} }
// Complete completes all the required options
func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error { func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
o.Builder = f.NewBuilder o.Builder = f.NewBuilder
@@ -142,6 +146,7 @@ func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error
return nil return nil
} }
// Validate makes sure all the provided values for command-line options are valid
func (o *RolloutStatusOptions) Validate() error { func (o *RolloutStatusOptions) Validate() error {
if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
return fmt.Errorf("required resource not specified") return fmt.Errorf("required resource not specified")
@@ -154,6 +159,7 @@ func (o *RolloutStatusOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of 'rollout status' sub command
func (o *RolloutStatusOptions) Run() error { func (o *RolloutStatusOptions) Run() error {
r := o.Builder(). r := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).

View File

@@ -50,10 +50,10 @@ type UndoOptions struct {
} }
var ( var (
undo_long = templates.LongDesc(` undoLong = templates.LongDesc(`
Rollback to a previous rollout.`) Rollback to a previous rollout.`)
undo_example = templates.Examples(` undoExample = templates.Examples(`
# Rollback to the previous deployment # Rollback to the previous deployment
kubectl rollout undo deployment/abc kubectl rollout undo deployment/abc
@@ -64,6 +64,7 @@ var (
kubectl rollout undo --dry-run=true deployment/abc`) kubectl rollout undo --dry-run=true deployment/abc`)
) )
// NewRolloutUndoOptions returns an initialized UndoOptions instance
func NewRolloutUndoOptions(streams genericclioptions.IOStreams) *UndoOptions { func NewRolloutUndoOptions(streams genericclioptions.IOStreams) *UndoOptions {
return &UndoOptions{ return &UndoOptions{
PrintFlags: genericclioptions.NewPrintFlags("rolled back").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("rolled back").WithTypeSetter(scheme.Scheme),
@@ -72,6 +73,7 @@ func NewRolloutUndoOptions(streams genericclioptions.IOStreams) *UndoOptions {
} }
} }
// NewCmdRolloutUndo returns a Command instance for the 'rollout undo' sub command
func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutUndoOptions(streams) o := NewRolloutUndoOptions(streams)
@@ -81,8 +83,8 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *
Use: "undo (TYPE NAME | TYPE/NAME) [flags]", Use: "undo (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Undo a previous rollout"), Short: i18n.T("Undo a previous rollout"),
Long: undo_long, Long: undoLong,
Example: undo_example, Example: undoExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -99,6 +101,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) *
return cmd return cmd
} }
// Complete completes al the required options
func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args o.Resources = args
o.DryRun = cmdutil.GetDryRunFlag(cmd) o.DryRun = cmdutil.GetDryRunFlag(cmd)
@@ -129,6 +132,7 @@ func (o *UndoOptions) Validate() error {
return nil return nil
} }
// RunUndo performs the execution of 'rollout undo' sub command
func (o *UndoOptions) RunUndo() error { func (o *UndoOptions) RunUndo() error {
r := o.Builder(). r := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).

View File

@@ -360,9 +360,9 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
runObject, err := o.createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "overrides"), namespace) runObject, err := o.createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "overrides"), namespace)
if err != nil { if err != nil {
return err return err
} else {
createdObjects = append(createdObjects, runObject)
} }
createdObjects = append(createdObjects, runObject)
allErrs := []error{} allErrs := []error{}
if o.Expose { if o.Expose {
serviceGenerator := cmdutil.GetFlagString(cmd, "service-generator") serviceGenerator := cmdutil.GetFlagString(cmd, "service-generator")
@@ -567,9 +567,8 @@ func getRestartPolicy(cmd *cobra.Command, interactive bool) (corev1.RestartPolic
if len(restart) == 0 { if len(restart) == 0 {
if interactive { if interactive {
return corev1.RestartPolicyOnFailure, nil return corev1.RestartPolicyOnFailure, nil
} else {
return corev1.RestartPolicyAlways, nil
} }
return corev1.RestartPolicyAlways, nil
} }
switch corev1.RestartPolicy(restart) { switch corev1.RestartPolicy(restart) {
case corev1.RestartPolicyAlways: case corev1.RestartPolicyAlways:

View File

@@ -25,18 +25,19 @@ import (
) )
var ( var (
set_long = templates.LongDesc(` setLong = templates.LongDesc(`
Configure application resources Configure application resources
These commands help you make changes to existing application resources.`) These commands help you make changes to existing application resources.`)
) )
// NewCmdSet returns an initialized Command instance for 'set' sub command
func NewCmdSet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdSet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "set SUBCOMMAND", Use: "set SUBCOMMAND",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Set specific features on objects"), Short: i18n.T("Set specific features on objects"),
Long: set_long, Long: setLong,
Run: cmdutil.DefaultSubCommandRun(streams.ErrOut), Run: cmdutil.DefaultSubCommandRun(streams.ErrOut),
} }

View File

@@ -97,6 +97,7 @@ var (
env | grep RAILS_ | kubectl set env -e - deployment/registry`) env | grep RAILS_ | kubectl set env -e - deployment/registry`)
) )
// EnvOptions holds values for 'set env' command-lone options
type EnvOptions struct { type EnvOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
resource.FilenameOptions resource.FilenameOptions
@@ -202,6 +203,7 @@ func contains(key string, keyList []string) bool {
return false return false
} }
// Complete completes all required options
func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if o.All && len(o.Selector) > 0 { if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time") return fmt.Errorf("cannot set --all and --selector at the same time")
@@ -242,6 +244,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
return nil return nil
} }
// Validate makes sure provided values for EnvOptions are valid
func (o *EnvOptions) Validate() error { func (o *EnvOptions) Validate() error {
if len(o.Filenames) == 0 && len(o.resources) < 1 { if len(o.Filenames) == 0 && len(o.resources) < 1 {
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>") return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
@@ -471,7 +474,7 @@ func (o *EnvOptions) RunEnv() error {
for _, patch := range patches { for _, patch := range patches {
info := patch.Info info := patch.Info
if patch.Err != nil { if patch.Err != nil {
allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v", info.Mapping.Resource, info.Name, patch.Err))
continue continue
} }
@@ -489,7 +492,7 @@ func (o *EnvOptions) RunEnv() error {
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil) actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil)
if err != nil { if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch env update to pod template: %v\n", err)) allErrs = append(allErrs, fmt.Errorf("failed to patch env update to pod template: %v", err))
continue continue
} }

View File

@@ -63,16 +63,16 @@ type SetImageOptions struct {
} }
var ( var (
image_resources = ` imageResources = `
pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs)` pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs)`
image_long = templates.LongDesc(` imageLong = templates.LongDesc(`
Update existing container image(s) of resources. Update existing container image(s) of resources.
Possible resources include (case insensitive): Possible resources include (case insensitive):
` + image_resources) ` + imageResources)
image_example = templates.Examples(` imageExample = templates.Examples(`
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'. # Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1 kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
@@ -86,6 +86,7 @@ var (
kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml`) kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml`)
) )
// NewImageOptions returns an initialized SetImageOptions instance
func NewImageOptions(streams genericclioptions.IOStreams) *SetImageOptions { func NewImageOptions(streams genericclioptions.IOStreams) *SetImageOptions {
return &SetImageOptions{ return &SetImageOptions{
PrintFlags: genericclioptions.NewPrintFlags("image updated").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("image updated").WithTypeSetter(scheme.Scheme),
@@ -97,6 +98,7 @@ func NewImageOptions(streams genericclioptions.IOStreams) *SetImageOptions {
} }
} }
// NewCmdImage returns an initialized Command instance for the 'set image' sub command
func NewCmdImage(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdImage(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewImageOptions(streams) o := NewImageOptions(streams)
@@ -104,8 +106,8 @@ func NewCmdImage(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.
Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N", Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Update image of a pod template"), Short: i18n.T("Update image of a pod template"),
Long: image_long, Long: imageLong,
Example: image_example, Example: imageExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -126,6 +128,7 @@ func NewCmdImage(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.
return cmd return cmd
} }
// Complete completes all required options
func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error var err error
@@ -191,6 +194,7 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
return nil return nil
} }
// Validate makes sure provided values in SetImageOptions are valid
func (o *SetImageOptions) Validate() error { func (o *SetImageOptions) Validate() error {
errors := []error{} errors := []error{}
if o.All && len(o.Selector) > 0 { if o.All && len(o.Selector) > 0 {
@@ -207,6 +211,7 @@ func (o *SetImageOptions) Validate() error {
return utilerrors.NewAggregate(errors) return utilerrors.NewAggregate(errors)
} }
// Run performs the execution of 'set image' sub command
func (o *SetImageOptions) Run() error { func (o *SetImageOptions) Run() error {
allErrs := []error{} allErrs := []error{}
@@ -265,7 +270,7 @@ func (o *SetImageOptions) Run() error {
for _, patch := range patches { for _, patch := range patches {
info := patch.Info info := patch.Info
if patch.Err != nil { if patch.Err != nil {
allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v", info.Mapping.Resource, info.Name, patch.Err))
continue continue
} }
@@ -284,7 +289,7 @@ func (o *SetImageOptions) Run() error {
// patch the change // patch the change
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil) actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil)
if err != nil { if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v\n", err)) allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v", err))
continue continue
} }

View File

@@ -38,14 +38,14 @@ import (
) )
var ( var (
resources_long = templates.LongDesc(` resourcesLong = templates.LongDesc(`
Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits. Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit. for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
Possible resources include (case insensitive): %s.`) Possible resources include (case insensitive): %s.`)
resources_example = templates.Examples(` resourcesExample = templates.Examples(`
# Set a deployments nginx container cpu limits to "200m" and memory to "512Mi" # Set a deployments nginx container cpu limits to "200m" and memory to "512Mi"
kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
@@ -59,7 +59,7 @@ var (
kubectl set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --local -o yaml`) kubectl set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --local -o yaml`)
) )
// ResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of // SetResourcesOptions 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 // referencing the cmd.Flags
type SetResourcesOptions struct { type SetResourcesOptions struct {
resource.FilenameOptions resource.FilenameOptions
@@ -104,6 +104,7 @@ func NewResourcesOptions(streams genericclioptions.IOStreams) *SetResourcesOptio
} }
} }
// NewCmdResources returns initialized Command instance for the 'set resources' sub command
func NewCmdResources(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdResources(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewResourcesOptions(streams) o := NewResourcesOptions(streams)
@@ -111,8 +112,8 @@ func NewCmdResources(f cmdutil.Factory, streams genericclioptions.IOStreams) *co
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]", Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Update resource requests/limits on objects with pod templates"), Short: i18n.T("Update resource requests/limits on objects with pod templates"),
Long: fmt.Sprintf(resources_long, cmdutil.SuggestApiResources("kubectl")), Long: fmt.Sprintf(resourcesLong, cmdutil.SuggestAPIResources("kubectl")),
Example: resources_example, Example: resourcesExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -138,6 +139,7 @@ func NewCmdResources(f cmdutil.Factory, streams genericclioptions.IOStreams) *co
return cmd return cmd
} }
// Complete completes all required options
func (o *SetResourcesOptions) 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 var err error
@@ -197,6 +199,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar
return nil return nil
} }
// Validate makes sure that provided values in ResourcesOptions are valid
func (o *SetResourcesOptions) Validate() error { func (o *SetResourcesOptions) Validate() error {
var err error var err error
if o.All && len(o.Selector) > 0 { if o.All && len(o.Selector) > 0 {
@@ -214,6 +217,7 @@ func (o *SetResourcesOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of 'set resources' sub command
func (o *SetResourcesOptions) Run() error { func (o *SetResourcesOptions) Run() error {
allErrs := []error{} allErrs := []error{}
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) { patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
@@ -259,13 +263,13 @@ func (o *SetResourcesOptions) Run() error {
for _, patch := range patches { for _, patch := range patches {
info := patch.Info info := patch.Info
if patch.Err != nil { if patch.Err != nil {
allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v", info.Mapping.Resource, info.Name, patch.Err))
continue continue
} }
//no changes //no changes
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
allErrs = append(allErrs, fmt.Errorf("info: %s %q was not changed\n", info.Mapping.Resource, info.Name)) allErrs = append(allErrs, fmt.Errorf("info: %s %q was not changed", info.Mapping.Resource, info.Name))
continue continue
} }
@@ -278,7 +282,7 @@ func (o *SetResourcesOptions) Run() error {
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil) actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil)
if err != nil { if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch limit update to pod template %v\n", err)) allErrs = append(allErrs, fmt.Errorf("failed to patch limit update to pod template %v", err))
continue continue
} }

View File

@@ -36,7 +36,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// SelectorOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of // SetSelectorOptions 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() // referencing the cmd.Flags()
type SetSelectorOptions struct { type SetSelectorOptions struct {
// Bound // Bound
@@ -73,6 +73,7 @@ var (
kubectl create deployment my-dep -o yaml --dry-run | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -`) kubectl create deployment my-dep -o yaml --dry-run | kubectl label --local -f - environment=qa -o yaml | kubectl create -f -`)
) )
// NewSelectorOptions returns an initialized SelectorOptions instance
func NewSelectorOptions(streams genericclioptions.IOStreams) *SetSelectorOptions { func NewSelectorOptions(streams genericclioptions.IOStreams) *SetSelectorOptions {
return &SetSelectorOptions{ return &SetSelectorOptions{
ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags(). ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags().

View File

@@ -56,7 +56,7 @@ var (
`)) `))
) )
// serviceAccountConfig encapsulates the data required to perform the operation. // SetServiceAccountOptions encapsulates the data required to perform the operation.
type SetServiceAccountOptions struct { type SetServiceAccountOptions struct {
PrintFlags *genericclioptions.PrintFlags PrintFlags *genericclioptions.PrintFlags
RecordFlags *genericclioptions.RecordFlags RecordFlags *genericclioptions.RecordFlags
@@ -77,6 +77,7 @@ type SetServiceAccountOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewSetServiceAccountOptions returns an initialized SetServiceAccountOptions instance
func NewSetServiceAccountOptions(streams genericclioptions.IOStreams) *SetServiceAccountOptions { func NewSetServiceAccountOptions(streams genericclioptions.IOStreams) *SetServiceAccountOptions {
return &SetServiceAccountOptions{ return &SetServiceAccountOptions{
PrintFlags: genericclioptions.NewPrintFlags("serviceaccount updated").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("serviceaccount updated").WithTypeSetter(scheme.Scheme),
@@ -193,7 +194,7 @@ func (o *SetServiceAccountOptions) Run() error {
for _, patch := range patches { for _, patch := range patches {
info := patch.Info info := patch.Info
if patch.Err != nil { if patch.Err != nil {
patchErrs = append(patchErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) patchErrs = append(patchErrs, fmt.Errorf("error: %s/%s %v", info.Mapping.Resource, info.Name, patch.Err))
continue continue
} }
if o.local || o.dryRun { if o.local || o.dryRun {

View File

@@ -37,10 +37,10 @@ import (
) )
var ( var (
subject_long = templates.LongDesc(` subjectLong = templates.LongDesc(`
Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding.`) Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding.`)
subject_example = templates.Examples(` subjectExample = templates.Examples(`
# Update a ClusterRoleBinding for serviceaccount1 # Update a ClusterRoleBinding for serviceaccount1
kubectl set subject clusterrolebinding admin --serviceaccount=namespace:serviceaccount1 kubectl set subject clusterrolebinding admin --serviceaccount=namespace:serviceaccount1
@@ -79,6 +79,7 @@ type SubjectOptions struct {
genericclioptions.IOStreams genericclioptions.IOStreams
} }
// NewSubjectOptions returns an initialized SubjectOptions instance
func NewSubjectOptions(streams genericclioptions.IOStreams) *SubjectOptions { func NewSubjectOptions(streams genericclioptions.IOStreams) *SubjectOptions {
return &SubjectOptions{ return &SubjectOptions{
PrintFlags: genericclioptions.NewPrintFlags("subjects updated").WithTypeSetter(scheme.Scheme), PrintFlags: genericclioptions.NewPrintFlags("subjects updated").WithTypeSetter(scheme.Scheme),
@@ -87,14 +88,15 @@ func NewSubjectOptions(streams genericclioptions.IOStreams) *SubjectOptions {
} }
} }
// NewCmdSubject returns the "new subject" sub command
func NewCmdSubject(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewCmdSubject(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewSubjectOptions(streams) o := NewSubjectOptions(streams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]", Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding"), Short: i18n.T("Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding"),
Long: subject_long, Long: subjectLong,
Example: subject_example, Example: subjectExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())
@@ -116,6 +118,7 @@ func NewCmdSubject(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr
return cmd return cmd
} }
// Complete completes all required options
func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Output = cmdutil.GetFlagString(cmd, "output") o.Output = cmdutil.GetFlagString(cmd, "output")
o.DryRun = cmdutil.GetDryRunFlag(cmd) o.DryRun = cmdutil.GetDryRunFlag(cmd)
@@ -167,6 +170,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
return nil return nil
} }
// Validate makes sure provided values in SubjectOptions are valid
func (o *SubjectOptions) Validate() error { func (o *SubjectOptions) Validate() error {
if o.All && len(o.Selector) > 0 { if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time") return fmt.Errorf("cannot set --all and --selector at the same time")
@@ -192,6 +196,7 @@ func (o *SubjectOptions) Validate() error {
return nil return nil
} }
// Run performs the execution of "set subject" sub command
func (o *SubjectOptions) Run(fn updateSubjects) error { func (o *SubjectOptions) Run(fn updateSubjects) error {
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) { patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
subjects := []rbacv1.Subject{} subjects := []rbacv1.Subject{}
@@ -238,13 +243,13 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
for _, patch := range patches { for _, patch := range patches {
info := patch.Info info := patch.Info
if patch.Err != nil { if patch.Err != nil {
allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v\n", info.Mapping.Resource, info.Name, patch.Err)) allErrs = append(allErrs, fmt.Errorf("error: %s/%s %v", info.Mapping.Resource, info.Name, patch.Err))
continue continue
} }
//no changes //no changes
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 { if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
allErrs = append(allErrs, fmt.Errorf("info: %s %q was not changed\n", info.Mapping.Resource, info.Name)) allErrs = append(allErrs, fmt.Errorf("info: %s %q was not changed", info.Mapping.Resource, info.Name))
continue continue
} }
@@ -257,7 +262,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil) actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch, nil)
if err != nil { if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch subjects to rolebinding: %v\n", err)) allErrs = append(allErrs, fmt.Errorf("failed to patch subjects to rolebinding: %v", err))
continue continue
} }

View File

@@ -237,7 +237,7 @@ func TestTaint(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints) oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &corev1.Node{} newNode := &corev1.Node{}
tainted := false tainted := false
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup() defer tf.Cleanup()
@@ -274,13 +274,13 @@ func TestTaint(t *testing.T) {
} }
// decode the patch // decode the patch
if err := runtime.DecodeInto(codec, appliedPatch, new_node); err != nil { if err := runtime.DecodeInto(codec, appliedPatch, newNode); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) { if !equalTaints(expectNewNode.Spec.Taints, newNode.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, newNode.Spec.Taints)
} }
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, newNode)}, nil
case m.isFor("PUT", "/nodes/node-name"): case m.isFor("PUT", "/nodes/node-name"):
tainted = true tainted = true
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(req.Body)
@@ -288,13 +288,13 @@ func TestTaint(t *testing.T) {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
defer req.Body.Close() defer req.Body.Close()
if err := runtime.DecodeInto(codec, data, new_node); err != nil { if err := runtime.DecodeInto(codec, data, newNode); err != nil {
t.Fatalf("%s: unexpected error: %v", test.description, err) t.Fatalf("%s: unexpected error: %v", test.description, err)
} }
if !equalTaints(expectNewNode.Spec.Taints, new_node.Spec.Taints) { if !equalTaints(expectNewNode.Spec.Taints, newNode.Spec.Taints) {
t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, new_node.Spec.Taints) t.Fatalf("%s: expected:\n%v\nsaw:\n%v\n", test.description, expectNewNode.Spec.Taints, newNode.Spec.Taints)
} }
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, new_node)}, nil return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, newNode)}, nil
default: default:
t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req) t.Fatalf("%s: unexpected request: %v %#v\n%#v", test.description, req.Method, req.URL, req)
return nil, nil return nil, nil
@@ -305,7 +305,7 @@ func TestTaint(t *testing.T) {
cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard()) cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard())
saw_fatal := false sawFatal := false
func() { func() {
defer func() { defer func() {
// Recover from the panic below. // Recover from the panic below.
@@ -316,13 +316,13 @@ func TestTaint(t *testing.T) {
// Restore cmdutil behavior // Restore cmdutil behavior
cmdutil.DefaultBehaviorOnFatal() cmdutil.DefaultBehaviorOnFatal()
}() }()
cmdutil.BehaviorOnFatal(func(e string, code int) { saw_fatal = true; panic(e) }) cmdutil.BehaviorOnFatal(func(e string, code int) { sawFatal = true; panic(e) })
cmd.SetArgs(test.args) cmd.SetArgs(test.args)
cmd.Execute() cmd.Execute()
}() }()
if test.expectFatal { if test.expectFatal {
if !saw_fatal { if !sawFatal {
t.Fatalf("%s: unexpected non-error", test.description) t.Fatalf("%s: unexpected non-error", test.description)
} }
} }

View File

@@ -51,6 +51,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/validation" "k8s.io/kubernetes/pkg/kubectl/validation"
) )
// InternalType is the schema for internal type
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type InternalType struct { type InternalType struct {
@@ -60,6 +61,7 @@ type InternalType struct {
Name string Name string
} }
// ExternalType is the schema for external type
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ExternalType struct { type ExternalType struct {
@@ -69,6 +71,7 @@ type ExternalType struct {
Name string `json:"name"` Name string `json:"name"`
} }
// ExternalType2 is another schema for external type
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ExternalType2 struct { type ExternalType2 struct {
@@ -78,28 +81,46 @@ type ExternalType2 struct {
Name string `json:"name"` Name string `json:"name"`
} }
// GetObjectKind returns the ObjectKind schema
func (obj *InternalType) GetObjectKind() schema.ObjectKind { return obj } func (obj *InternalType) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind sets the version and kind
func (obj *InternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *InternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns GroupVersionKind schema
func (obj *InternalType) GroupVersionKind() schema.GroupVersionKind { func (obj *InternalType) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// GetObjectKind returns the ObjectKind schema
func (obj *ExternalType) GetObjectKind() schema.ObjectKind { return obj } func (obj *ExternalType) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind returns the GroupVersionKind schema
func (obj *ExternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *ExternalType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns the GroupVersionKind schema
func (obj *ExternalType) GroupVersionKind() schema.GroupVersionKind { func (obj *ExternalType) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// GetObjectKind returns the ObjectKind schema
func (obj *ExternalType2) GetObjectKind() schema.ObjectKind { return obj } func (obj *ExternalType2) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind sets the API version and obj kind from schema
func (obj *ExternalType2) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *ExternalType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns the FromAPIVersionAndKind schema
func (obj *ExternalType2) GroupVersionKind() schema.GroupVersionKind { func (obj *ExternalType2) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// NewInternalType returns an initialized InternalType instance
func NewInternalType(kind, apiversion, name string) *InternalType { func NewInternalType(kind, apiversion, name string) *InternalType {
item := InternalType{Kind: kind, item := InternalType{Kind: kind,
APIVersion: apiversion, APIVersion: apiversion,
@@ -107,6 +128,7 @@ func NewInternalType(kind, apiversion, name string) *InternalType {
return &item return &item
} }
// InternalNamespacedType schema for internal namespaced types
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type InternalNamespacedType struct { type InternalNamespacedType struct {
@@ -117,6 +139,7 @@ type InternalNamespacedType struct {
Namespace string Namespace string
} }
// ExternalNamespacedType schema for external namespaced types
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ExternalNamespacedType struct { type ExternalNamespacedType struct {
@@ -127,6 +150,7 @@ type ExternalNamespacedType struct {
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
} }
// ExternalNamespacedType2 schema for external namespaced types
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ExternalNamespacedType2 struct { type ExternalNamespacedType2 struct {
@@ -137,28 +161,46 @@ type ExternalNamespacedType2 struct {
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
} }
// GetObjectKind returns the ObjectKind schema
func (obj *InternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj } func (obj *InternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind sets the API group and kind from schema
func (obj *InternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *InternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns the GroupVersionKind schema
func (obj *InternalNamespacedType) GroupVersionKind() schema.GroupVersionKind { func (obj *InternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// GetObjectKind returns the ObjectKind schema
func (obj *ExternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj } func (obj *ExternalNamespacedType) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind sets the API version and kind from schema
func (obj *ExternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *ExternalNamespacedType) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns the GroupVersionKind schema
func (obj *ExternalNamespacedType) GroupVersionKind() schema.GroupVersionKind { func (obj *ExternalNamespacedType) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// GetObjectKind returns the ObjectKind schema
func (obj *ExternalNamespacedType2) GetObjectKind() schema.ObjectKind { return obj } func (obj *ExternalNamespacedType2) GetObjectKind() schema.ObjectKind { return obj }
// SetGroupVersionKind sets the API version and kind from schema
func (obj *ExternalNamespacedType2) SetGroupVersionKind(gvk schema.GroupVersionKind) { func (obj *ExternalNamespacedType2) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind() obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
} }
// GroupVersionKind returns the GroupVersionKind schema
func (obj *ExternalNamespacedType2) GroupVersionKind() schema.GroupVersionKind { func (obj *ExternalNamespacedType2) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
} }
// NewInternalNamespacedType returns an initialized instance of InternalNamespacedType
func NewInternalNamespacedType(kind, apiversion, name, namespace string) *InternalNamespacedType { func NewInternalNamespacedType(kind, apiversion, name, namespace string) *InternalNamespacedType {
item := InternalNamespacedType{Kind: kind, item := InternalNamespacedType{Kind: kind,
APIVersion: apiversion, APIVersion: apiversion,
@@ -167,26 +209,35 @@ func NewInternalNamespacedType(kind, apiversion, name, namespace string) *Intern
return &item return &item
} }
var versionErr = errors.New("not a version") var errInvalidVersion = errors.New("not a version")
func versionErrIfFalse(b bool) error { func versionErrIfFalse(b bool) error {
if b { if b {
return nil return nil
} }
return versionErr return errInvalidVersion
} }
// ValidVersion of API
var ValidVersion = "v1" var ValidVersion = "v1"
// InternalGV is the internal group version object
var InternalGV = schema.GroupVersion{Group: "apitest", Version: runtime.APIVersionInternal} var InternalGV = schema.GroupVersion{Group: "apitest", Version: runtime.APIVersionInternal}
// UnlikelyGV is a group version object for unrecognised version
var UnlikelyGV = schema.GroupVersion{Group: "apitest", Version: "unlikelyversion"} var UnlikelyGV = schema.GroupVersion{Group: "apitest", Version: "unlikelyversion"}
// ValidVersionGV is the valid group version object
var ValidVersionGV = schema.GroupVersion{Group: "apitest", Version: ValidVersion} var ValidVersionGV = schema.GroupVersion{Group: "apitest", Version: ValidVersion}
// NewExternalScheme returns required objects for ExternalScheme
func NewExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) { func NewExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
mapper, codec := AddToScheme(scheme) mapper, codec := AddToScheme(scheme)
return scheme, mapper, codec return scheme, mapper, codec
} }
// AddToScheme adds required objects into scheme
func AddToScheme(scheme *runtime.Scheme) (meta.RESTMapper, runtime.Codec) { func AddToScheme(scheme *runtime.Scheme) (meta.RESTMapper, runtime.Codec) {
scheme.AddKnownTypeWithName(InternalGV.WithKind("Type"), &InternalType{}) scheme.AddKnownTypeWithName(InternalGV.WithKind("Type"), &InternalType{})
scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("Type"), &ExternalType{}) scheme.AddKnownTypeWithName(UnlikelyGV.WithKind("Type"), &ExternalType{})
@@ -228,6 +279,7 @@ func (d *fakeCachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList
return []*metav1.APIResourceList{}, nil return []*metav1.APIResourceList{}, nil
} }
// TestFactory extends cmdutil.Factory
type TestFactory struct { type TestFactory struct {
cmdutil.Factory cmdutil.Factory
@@ -245,6 +297,7 @@ type TestFactory struct {
OpenAPISchemaFunc func() (openapi.Resources, error) OpenAPISchemaFunc func() (openapi.Resources, error)
} }
// NewTestFactory returns an initialized TestFactory instance
func NewTestFactory() *TestFactory { func NewTestFactory() *TestFactory {
// specify an optionalClientConfig to explicitly use in testing // specify an optionalClientConfig to explicitly use in testing
// to avoid polluting an existing user config. // to avoid polluting an existing user config.
@@ -281,11 +334,13 @@ func NewTestFactory() *TestFactory {
} }
} }
// WithNamespace is used to mention namespace reactively
func (f *TestFactory) WithNamespace(ns string) *TestFactory { func (f *TestFactory) WithNamespace(ns string) *TestFactory {
f.kubeConfigFlags.WithNamespace(ns) f.kubeConfigFlags.WithNamespace(ns)
return f return f
} }
// Cleanup cleans up TestFactory temp config file
func (f *TestFactory) Cleanup() { func (f *TestFactory) Cleanup() {
if f.tempConfigFile == nil { if f.tempConfigFile == nil {
return return
@@ -294,14 +349,17 @@ func (f *TestFactory) Cleanup() {
os.Remove(f.tempConfigFile.Name()) os.Remove(f.tempConfigFile.Name())
} }
// ToRESTConfig is used to get ClientConfigVal from a TestFactory
func (f *TestFactory) ToRESTConfig() (*restclient.Config, error) { func (f *TestFactory) ToRESTConfig() (*restclient.Config, error) {
return f.ClientConfigVal, nil return f.ClientConfigVal, nil
} }
// ClientForMapping is used to Client from a TestFactory
func (f *TestFactory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { func (f *TestFactory) ClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.Client, nil return f.Client, nil
} }
// UnstructuredClientForMapping is used to get UnstructuredClient from a TestFactory
func (f *TestFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) { func (f *TestFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) {
if f.UnstructuredClientForMappingFunc != nil { if f.UnstructuredClientForMappingFunc != nil {
return f.UnstructuredClientForMappingFunc(mapping.GroupVersionKind.GroupVersion()) return f.UnstructuredClientForMappingFunc(mapping.GroupVersionKind.GroupVersion())
@@ -309,10 +367,12 @@ func (f *TestFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (r
return f.UnstructuredClient, nil return f.UnstructuredClient, nil
} }
// Validator returns a validation schema
func (f *TestFactory) Validator(validate bool) (validation.Schema, error) { func (f *TestFactory) Validator(validate bool) (validation.Schema, error) {
return validation.NullSchema{}, nil return validation.NullSchema{}, nil
} }
// OpenAPISchema returns openapi resources
func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) { func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) {
if f.OpenAPISchemaFunc != nil { if f.OpenAPISchemaFunc != nil {
return f.OpenAPISchemaFunc() return f.OpenAPISchemaFunc()
@@ -320,6 +380,7 @@ func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) {
return openapitesting.EmptyResources{}, nil return openapitesting.EmptyResources{}, nil
} }
// NewBuilder returns an initialized resource.Builder instance
func (f *TestFactory) NewBuilder() *resource.Builder { func (f *TestFactory) NewBuilder() *resource.Builder {
return resource.NewFakeBuilder( return resource.NewFakeBuilder(
func(version schema.GroupVersion) (resource.RESTClient, error) { func(version schema.GroupVersion) (resource.RESTClient, error) {
@@ -338,6 +399,7 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
) )
} }
// KubernetesClientSet initializes and returns the Clientset using TestFactory
func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) { func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
fakeClient := f.Client.(*fake.RESTClient) fakeClient := f.Client.(*fake.RESTClient)
clientset := kubernetes.NewForConfigOrDie(f.ClientConfigVal) clientset := kubernetes.NewForConfigOrDie(f.ClientConfigVal)
@@ -365,6 +427,7 @@ func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
return clientset, nil return clientset, nil
} }
// DynamicClient returns a dynamic client from TestFactory
func (f *TestFactory) DynamicClient() (dynamic.Interface, error) { func (f *TestFactory) DynamicClient() (dynamic.Interface, error) {
if f.FakeDynamicClient != nil { if f.FakeDynamicClient != nil {
return f.FakeDynamicClient, nil return f.FakeDynamicClient, nil
@@ -372,6 +435,7 @@ func (f *TestFactory) DynamicClient() (dynamic.Interface, error) {
return f.Factory.DynamicClient() return f.Factory.DynamicClient()
} }
// RESTClient returns a REST client from TestFactory
func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) { func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) {
// Swap out the HTTP client out of the client with the fake's version. // Swap out the HTTP client out of the client with the fake's version.
fakeClient := f.Client.(*fake.RESTClient) fakeClient := f.Client.(*fake.RESTClient)
@@ -383,6 +447,7 @@ func (f *TestFactory) RESTClient() (*restclient.RESTClient, error) {
return restClient, nil return restClient, nil
} }
// DiscoveryClient returns a discovery client from TestFactory
func (f *TestFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) { func (f *TestFactory) DiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
fakeClient := f.Client.(*fake.RESTClient) fakeClient := f.Client.(*fake.RESTClient)
@@ -413,6 +478,7 @@ func testRESTMapper() meta.RESTMapper {
return expander return expander
} }
// ScaleClient returns the ScalesGetter from a TestFactory
func (f *TestFactory) ScaleClient() (scaleclient.ScalesGetter, error) { func (f *TestFactory) ScaleClient() (scaleclient.ScalesGetter, error) {
return f.ScaleGetter, nil return f.ScaleGetter, nil
} }

View File

@@ -46,7 +46,7 @@ const (
func TestTopNodeAllMetrics(t *testing.T) { func TestTopNodeAllMetrics(t *testing.T) {
cmdtesting.InitTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
metrics, nodes := testNodeV1alpha1MetricsData() metrics, nodes := testNodeV1alpha1MetricsData()
expectedMetricsPath := fmt.Sprintf("%s/%s/nodes", baseMetricsAddress, metricsApiVersion) expectedMetricsPath := fmt.Sprintf("%s/%s/nodes", baseMetricsAddress, metricsAPIVersion)
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion) expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
@@ -102,7 +102,7 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
cmdtesting.InitTestErrorHandler(t) cmdtesting.InitTestErrorHandler(t)
metrics, nodes := testNodeV1alpha1MetricsData() metrics, nodes := testNodeV1alpha1MetricsData()
expectedMetricsPath := fmt.Sprintf("%s/%s/nodes", customBaseMetricsAddress, metricsApiVersion) expectedMetricsPath := fmt.Sprintf("%s/%s/nodes", customBaseMetricsAddress, metricsAPIVersion)
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion) expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
@@ -165,7 +165,7 @@ func TestTopNodeWithNameMetrics(t *testing.T) {
ListMeta: metrics.ListMeta, ListMeta: metrics.ListMeta,
Items: metrics.Items[1:], Items: metrics.Items[1:],
} }
expectedPath := fmt.Sprintf("%s/%s/nodes/%s", baseMetricsAddress, metricsApiVersion, expectedMetrics.Name) expectedPath := fmt.Sprintf("%s/%s/nodes/%s", baseMetricsAddress, metricsAPIVersion, expectedMetrics.Name)
expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name) expectedNodePath := fmt.Sprintf("/%s/%s/nodes/%s", apiPrefix, apiVersion, expectedMetrics.Name)
tf := cmdtesting.NewTestFactory().WithNamespace("test") tf := cmdtesting.NewTestFactory().WithNamespace("test")
@@ -230,7 +230,7 @@ func TestTopNodeWithLabelSelectorMetrics(t *testing.T) {
Items: metrics.Items[1:], Items: metrics.Items[1:],
} }
label := "key=value" label := "key=value"
expectedPath := fmt.Sprintf("%s/%s/nodes", baseMetricsAddress, metricsApiVersion) expectedPath := fmt.Sprintf("%s/%s/nodes", baseMetricsAddress, metricsAPIVersion)
expectedQuery := fmt.Sprintf("labelSelector=%s", url.QueryEscape(label)) expectedQuery := fmt.Sprintf("labelSelector=%s", url.QueryEscape(label))
expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion) expectedNodePath := fmt.Sprintf("/%s/%s/nodes", apiPrefix, apiVersion)

View File

@@ -45,7 +45,7 @@ import (
) )
const ( const (
topPathPrefix = baseMetricsAddress + "/" + metricsApiVersion topPathPrefix = baseMetricsAddress + "/" + metricsAPIVersion
topMetricsAPIPathPrefix = "/apis/metrics.k8s.io/v1beta1" topMetricsAPIPathPrefix = "/apis/metrics.k8s.io/v1beta1"
apibody = `{ apibody = `{
"kind": "APIVersions", "kind": "APIVersions",
@@ -440,7 +440,7 @@ func (d *fakeDiscovery) RESTClient() restclient.Interface {
func TestTopPodCustomDefaults(t *testing.T) { func TestTopPodCustomDefaults(t *testing.T) {
customBaseHeapsterServiceAddress := "/api/v1/namespaces/custom-namespace/services/https:custom-heapster-service:/proxy" customBaseHeapsterServiceAddress := "/api/v1/namespaces/custom-namespace/services/https:custom-heapster-service:/proxy"
customBaseMetricsAddress := customBaseHeapsterServiceAddress + "/apis/metrics" customBaseMetricsAddress := customBaseHeapsterServiceAddress + "/apis/metrics"
customTopPathPrefix := customBaseMetricsAddress + "/" + metricsApiVersion customTopPathPrefix := customBaseMetricsAddress + "/" + metricsAPIVersion
testNS := "custom-namespace" testNS := "custom-namespace"
testCases := []struct { testCases := []struct {

View File

@@ -38,7 +38,7 @@ const (
baseHeapsterServiceAddress = "/api/v1/namespaces/kube-system/services/http:heapster:/proxy" baseHeapsterServiceAddress = "/api/v1/namespaces/kube-system/services/http:heapster:/proxy"
baseMetricsAddress = baseHeapsterServiceAddress + "/apis/metrics" baseMetricsAddress = baseHeapsterServiceAddress + "/apis/metrics"
baseMetricsServerAddress = "/apis/metrics.k8s.io/v1beta1" baseMetricsServerAddress = "/apis/metrics.k8s.io/v1beta1"
metricsApiVersion = "v1alpha1" metricsAPIVersion = "v1alpha1"
) )
func TestTopSubcommandsExist(t *testing.T) { func TestTopSubcommandsExist(t *testing.T) {

View File

@@ -81,6 +81,7 @@ type EditOptions struct {
updatedResultGetter func(data []byte) *resource.Result updatedResultGetter func(data []byte) *resource.Result
} }
// NewEditOptions returns an initialized EditOptions instance
func NewEditOptions(editMode EditMode, ioStreams genericclioptions.IOStreams) *EditOptions { func NewEditOptions(editMode EditMode, ioStreams genericclioptions.IOStreams) *EditOptions {
return &EditOptions{ return &EditOptions{
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
@@ -216,6 +217,7 @@ func (o *EditOptions) Validate() error {
return nil return nil
} }
// Run performs the execution
func (o *EditOptions) Run() error { func (o *EditOptions) Run() error {
edit := NewDefaultEditor(editorEnvs()) edit := NewDefaultEditor(editorEnvs())
// editFn is invoked for each edit session (once with a list for normal edit, once for each individual resource in a edit-on-create invocation) // editFn is invoked for each edit session (once with a list for normal edit, once for each individual resource in a edit-on-create invocation)
@@ -399,7 +401,7 @@ func (o *EditOptions) Run() error {
return err return err
} }
if len(infos) == 0 { if len(infos) == 0 {
return errors.New("edit cancelled, no objects found.") return errors.New("edit cancelled, no objects found")
} }
return editFn(infos) return editFn(infos)
case ApplyEditMode: case ApplyEditMode:
@@ -459,12 +461,12 @@ func (o *EditOptions) visitToApplyEditPatch(originalInfos []*resource.Info, patc
return fmt.Errorf("no original object found for %#v", info.Object) return fmt.Errorf("no original object found for %#v", info.Object)
} }
originalJS, err := encodeToJson(originalInfo.Object.(runtime.Unstructured)) originalJS, err := encodeToJSON(originalInfo.Object.(runtime.Unstructured))
if err != nil { if err != nil {
return err return err
} }
editedJS, err := encodeToJson(info.Object.(runtime.Unstructured)) editedJS, err := encodeToJSON(info.Object.(runtime.Unstructured))
if err != nil { if err != nil {
return err return err
} }
@@ -474,21 +476,18 @@ func (o *EditOptions) visitToApplyEditPatch(originalInfos []*resource.Info, patc
if err != nil { if err != nil {
return err return err
} }
printer.PrintObj(info.Object, o.Out) return printer.PrintObj(info.Object, o.Out)
return nil
} else {
err := o.annotationPatch(info)
if err != nil {
return err
}
printer, err := o.ToPrinter("edited")
if err != nil {
return err
}
printer.PrintObj(info.Object, o.Out)
return nil
} }
err = o.annotationPatch(info)
if err != nil {
return err
}
printer, err := o.ToPrinter("edited")
if err != nil {
return err
}
return printer.PrintObj(info.Object, o.Out)
}) })
return err return err
} }
@@ -511,8 +510,9 @@ func (o *EditOptions) annotationPatch(update *resource.Info) error {
return nil return nil
} }
// GetApplyPatch is used to get and apply patches
func GetApplyPatch(obj runtime.Unstructured) ([]byte, []byte, types.PatchType, error) { func GetApplyPatch(obj runtime.Unstructured) ([]byte, []byte, types.PatchType, error) {
beforeJSON, err := encodeToJson(obj) beforeJSON, err := encodeToJSON(obj)
if err != nil { if err != nil {
return nil, []byte(""), types.MergePatchType, err return nil, []byte(""), types.MergePatchType, err
} }
@@ -527,7 +527,7 @@ func GetApplyPatch(obj runtime.Unstructured) ([]byte, []byte, types.PatchType, e
} }
annotations[corev1.LastAppliedConfigAnnotation] = string(beforeJSON) annotations[corev1.LastAppliedConfigAnnotation] = string(beforeJSON)
accessor.SetAnnotations(objCopy, annotations) accessor.SetAnnotations(objCopy, annotations)
afterJSON, err := encodeToJson(objCopy.(runtime.Unstructured)) afterJSON, err := encodeToJSON(objCopy.(runtime.Unstructured))
if err != nil { if err != nil {
return nil, beforeJSON, types.MergePatchType, err return nil, beforeJSON, types.MergePatchType, err
} }
@@ -535,7 +535,7 @@ func GetApplyPatch(obj runtime.Unstructured) ([]byte, []byte, types.PatchType, e
return patch, beforeJSON, types.MergePatchType, err return patch, beforeJSON, types.MergePatchType, err
} }
func encodeToJson(obj runtime.Unstructured) ([]byte, error) { func encodeToJSON(obj runtime.Unstructured) ([]byte, error) {
serialization, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) serialization, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -569,12 +569,12 @@ func (o *EditOptions) visitToPatch(originalInfos []*resource.Info, patchVisitor
return fmt.Errorf("no original object found for %#v", info.Object) return fmt.Errorf("no original object found for %#v", info.Object)
} }
originalJS, err := encodeToJson(originalInfo.Object.(runtime.Unstructured)) originalJS, err := encodeToJSON(originalInfo.Object.(runtime.Unstructured))
if err != nil { if err != nil {
return err return err
} }
editedJS, err := encodeToJson(info.Object.(runtime.Unstructured)) editedJS, err := encodeToJSON(info.Object.(runtime.Unstructured))
if err != nil { if err != nil {
return err return err
} }
@@ -585,8 +585,7 @@ func (o *EditOptions) visitToPatch(originalInfos []*resource.Info, patchVisitor
if err != nil { if err != nil {
return err return err
} }
printer.PrintObj(info.Object, o.Out) return printer.PrintObj(info.Object, o.Out)
return nil
} }
preconditions := []mergepatch.PreconditionFunc{ preconditions := []mergepatch.PreconditionFunc{
@@ -643,8 +642,7 @@ func (o *EditOptions) visitToPatch(originalInfos []*resource.Info, patchVisitor
if err != nil { if err != nil {
return err return err
} }
printer.PrintObj(info.Object, o.Out) return printer.PrintObj(info.Object, o.Out)
return nil
}) })
return err return err
} }
@@ -658,8 +656,7 @@ func (o *EditOptions) visitToCreate(createVisitor resource.Visitor) error {
if err != nil { if err != nil {
return err return err
} }
printer.PrintObj(info.Object, o.Out) return printer.PrintObj(info.Object, o.Out)
return nil
}) })
return err return err
} }
@@ -683,12 +680,18 @@ func (o *EditOptions) visitAnnotation(annotationVisitor resource.Visitor) error
return err return err
} }
// EditMode can be either NormalEditMode, EditBeforeCreateMode or ApplyEditMode
type EditMode string type EditMode string
const ( const (
NormalEditMode EditMode = "normal_mode" // NormalEditMode is an edit mode
NormalEditMode EditMode = "normal_mode"
// EditBeforeCreateMode is an edit mode
EditBeforeCreateMode EditMode = "edit_before_create_mode" EditBeforeCreateMode EditMode = "edit_before_create_mode"
ApplyEditMode EditMode = "edit_last_applied_mode"
// ApplyEditMode is an edit mode
ApplyEditMode EditMode = "edit_last_applied_mode"
) )
// editReason preserves a message about the reason this file must be edited again // editReason preserves a message about the reason this file must be edited again

View File

@@ -43,6 +43,7 @@ const (
windowsShell = "cmd" windowsShell = "cmd"
) )
// Editor holds the command-line args to fire up the editor
type Editor struct { type Editor struct {
Args []string Args []string
Shell bool Shell bool

View File

@@ -290,7 +290,7 @@ func messageForError(err error) string {
func UsageErrorf(cmd *cobra.Command, format string, args ...interface{}) error { func UsageErrorf(cmd *cobra.Command, format string, args ...interface{}) error {
msg := fmt.Sprintf(format, args...) msg := fmt.Sprintf(format, args...)
return fmt.Errorf("%s\nSee '%s -h' for help and examples.", msg, cmd.CommandPath()) return fmt.Errorf("%s\nSee '%s -h' for help and examples", msg, cmd.CommandPath())
} }
func IsFilenameSliceEmpty(filenames []string) bool { func IsFilenameSliceEmpty(filenames []string) bool {

View File

@@ -92,7 +92,7 @@ func (f *MatchVersionFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterf
return f.Delegate.ToDiscoveryClient() return f.Delegate.ToDiscoveryClient()
} }
// RESTMapper returns a mapper. // ToRESTMapper returns a mapper.
func (f *MatchVersionFlags) ToRESTMapper() (meta.RESTMapper, error) { func (f *MatchVersionFlags) ToRESTMapper() (meta.RESTMapper, error) {
if err := f.checkMatchingServerVersion(); err != nil { if err := f.checkMatchingServerVersion(); err != nil {
return nil, err return nil, err

View File

@@ -22,8 +22,8 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// SuggestApiResources returns a suggestion to use the "api-resources" command // SuggestAPIResources returns a suggestion to use the "api-resources" command
// to retrieve a supported list of resources // to retrieve a supported list of resources
func SuggestApiResources(parent string) string { func SuggestAPIResources(parent string) string {
return templates.LongDesc(fmt.Sprintf("Use \"%s api-resources\" for a complete list of supported resources.", parent)) return templates.LongDesc(fmt.Sprintf("Use \"%s api-resources\" for a complete list of supported resources.", parent))
} }

View File

@@ -28,20 +28,27 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/templates" "k8s.io/kubernetes/pkg/kubectl/util/templates"
) )
// CmdCheck is the commom type of functions to check cobra commands
type CmdCheck func(cmd *cobra.Command) []error type CmdCheck func(cmd *cobra.Command) []error
// GlobalCheck is the common type of functions to check global flags
type GlobalCheck func() []error type GlobalCheck func() []error
var ( var (
// AllCmdChecks is the list of CmdCheck type functions
AllCmdChecks = []CmdCheck{ AllCmdChecks = []CmdCheck{
CheckLongDesc, CheckLongDesc,
CheckExamples, CheckExamples,
CheckFlags, CheckFlags,
} }
// AllGlobalChecks is the list of GlobalCheck type functions
AllGlobalChecks = []GlobalCheck{ AllGlobalChecks = []GlobalCheck{
CheckGlobalVarFlags, CheckGlobalVarFlags,
} }
) )
// RunGlobalChecks runs all the GlobalCheck functions passed and checks for error
func RunGlobalChecks(globalChecks []GlobalCheck) []error { func RunGlobalChecks(globalChecks []GlobalCheck) []error {
fmt.Fprint(os.Stdout, "---+ RUNNING GLOBAL CHECKS\n") fmt.Fprint(os.Stdout, "---+ RUNNING GLOBAL CHECKS\n")
errors := []error{} errors := []error{}
@@ -51,6 +58,7 @@ func RunGlobalChecks(globalChecks []GlobalCheck) []error {
return errors return errors
} }
// RunCmdChecks runs all the CmdCheck functions passed, skipping skippable commands and looks for error
func RunCmdChecks(cmd *cobra.Command, cmdChecks []CmdCheck, skipCmd []string) []error { func RunCmdChecks(cmd *cobra.Command, cmdChecks []CmdCheck, skipCmd []string) []error {
cmdPath := cmd.CommandPath() cmdPath := cmd.CommandPath()
@@ -80,6 +88,7 @@ func RunCmdChecks(cmd *cobra.Command, cmdChecks []CmdCheck, skipCmd []string) []
return errors return errors
} }
// CheckLongDesc checks if the long description is valid
func CheckLongDesc(cmd *cobra.Command) []error { func CheckLongDesc(cmd *cobra.Command) []error {
fmt.Fprint(os.Stdout, " ↳ checking long description\n") fmt.Fprint(os.Stdout, " ↳ checking long description\n")
cmdPath := cmd.CommandPath() cmdPath := cmd.CommandPath()
@@ -92,6 +101,7 @@ func CheckLongDesc(cmd *cobra.Command) []error {
return nil return nil
} }
// CheckExamples checks if the command examples are valid
func CheckExamples(cmd *cobra.Command) []error { func CheckExamples(cmd *cobra.Command) []error {
fmt.Fprint(os.Stdout, " ↳ checking examples\n") fmt.Fprint(os.Stdout, " ↳ checking examples\n")
cmdPath := cmd.CommandPath() cmdPath := cmd.CommandPath()
@@ -110,6 +120,7 @@ func CheckExamples(cmd *cobra.Command) []error {
return errors return errors
} }
// CheckFlags checks if the command-line flags are valid
func CheckFlags(cmd *cobra.Command) []error { func CheckFlags(cmd *cobra.Command) []error {
allFlagsSlice := []*pflag.Flag{} allFlagsSlice := []*pflag.Flag{}
@@ -140,6 +151,7 @@ func CheckFlags(cmd *cobra.Command) []error {
return errors return errors
} }
// CheckGlobalVarFlags checks if the global flags are valid
func CheckGlobalVarFlags() []error { func CheckGlobalVarFlags() []error {
fmt.Fprint(os.Stdout, " ↳ checking flags from global vars\n") fmt.Fprint(os.Stdout, " ↳ checking flags from global vars\n")
errors := []error{} errors := []error{}

View File

@@ -44,7 +44,7 @@ import (
) )
var ( var (
wait_long = templates.LongDesc(` waitLong = templates.LongDesc(`
Experimental: Wait for a specific condition on one or many resources. Experimental: Wait for a specific condition on one or many resources.
The command takes multiple resources and waits until the specified condition The command takes multiple resources and waits until the specified condition
@@ -56,7 +56,7 @@ var (
A successful message will be printed to stdout indicating when the specified A successful message will be printed to stdout indicating when the specified
condition has been met. One can use -o option to change to output destination.`) condition has been met. One can use -o option to change to output destination.`)
wait_example = templates.Examples(` waitExample = templates.Examples(`
# Wait for the pod "busybox1" to contain the status condition of type "Ready". # Wait for the pod "busybox1" to contain the status condition of type "Ready".
kubectl wait --for=condition=Ready pod/busybox1 kubectl wait --for=condition=Ready pod/busybox1
@@ -106,8 +106,8 @@ func NewCmdWait(restClientGetter genericclioptions.RESTClientGetter, streams gen
Use: "wait resource.group/name [--for=delete|--for condition=available]", Use: "wait resource.group/name [--for=delete|--for condition=available]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: "Experimental: Wait for a specific condition on one or many resources.", Short: "Experimental: Wait for a specific condition on one or many resources.",
Long: wait_long, Long: waitLong,
Example: wait_example, Example: waitExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
o, err := flags.ToOptions(args) o, err := flags.ToOptions(args)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)
@@ -191,12 +191,14 @@ func conditionFuncFor(condition string, errOut io.Writer) (ConditionFunc, error)
return nil, fmt.Errorf("unrecognized condition: %q", condition) return nil, fmt.Errorf("unrecognized condition: %q", condition)
} }
// ResourceLocation holds the location of a resource
type ResourceLocation struct { type ResourceLocation struct {
GroupResource schema.GroupResource GroupResource schema.GroupResource
Namespace string Namespace string
Name string Name string
} }
// UIDMap maps ResourceLocation with UID
type UIDMap map[ResourceLocation]types.UID type UIDMap map[ResourceLocation]types.UID
// WaitOptions is a set of options that allows you to wait. This is the object reflects the runtime needs of a wait // WaitOptions is a set of options that allows you to wait. This is the object reflects the runtime needs of a wait