2015-10-15 22:15:13 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2015 The Kubernetes Authors .
2015-10-15 22:15:13 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package cmd
import (
"fmt"
"io"
2017-01-11 14:09:48 +00:00
utilerrors "k8s.io/apimachinery/pkg/util/errors"
2015-10-15 22:15:13 +00:00
"k8s.io/kubernetes/pkg/kubectl"
2016-10-07 22:24:42 +00:00
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
2015-10-15 22:15:13 +00:00
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"github.com/spf13/cobra"
)
2016-05-20 17:49:56 +00:00
var (
2016-10-07 22:24:42 +00:00
autoscaleLong = templates . LongDesc ( `
2016-05-20 17:49:56 +00:00
Creates an autoscaler that automatically chooses and sets the number of pods that run in a kubernetes cluster .
2015-10-15 22:15:13 +00:00
2016-05-20 17:49:56 +00:00
Looks up a Deployment , ReplicaSet , or ReplicationController by name and creates an autoscaler that uses the given resource as a reference .
An autoscaler can automatically increase or decrease number of pods deployed within the system as needed . ` )
2015-10-15 22:15:13 +00:00
2016-10-07 22:24:42 +00:00
autoscaleExample = templates . Examples ( `
2016-08-02 16:51:51 +00:00
# Auto scale a deployment "foo" , with the number of pods between 2 and 10 , target CPU utilization specified so a default autoscaling policy will be used :
2016-05-20 17:49:56 +00:00
kubectl autoscale deployment foo -- min = 2 -- max = 10
2015-10-15 22:15:13 +00:00
2016-08-02 16:51:51 +00:00
# Auto scale a replication controller "foo" , with the number of pods between 1 and 5 , target CPU utilization at 80 % :
2016-05-20 17:49:56 +00:00
kubectl autoscale rc foo -- max = 5 -- cpu - percent = 80 ` )
2015-10-15 22:15:13 +00:00
)
2016-10-13 00:18:39 +00:00
func NewCmdAutoscale ( f cmdutil . Factory , out io . Writer ) * cobra . Command {
2016-08-17 18:28:07 +00:00
options := & resource . FilenameOptions { }
2016-03-28 19:44:21 +00:00
2016-08-22 02:46:50 +00:00
validArgs := [ ] string { "deployment" , "replicaset" , "replicationcontroller" }
argAliases := kubectl . ResourceAliases ( validArgs )
2015-10-15 22:15:13 +00:00
cmd := & cobra . Command {
Use : "autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [flags]" ,
2016-03-21 21:00:43 +00:00
Short : "Auto-scale a Deployment, ReplicaSet, or ReplicationController" ,
2015-10-15 22:15:13 +00:00
Long : autoscaleLong ,
Example : autoscaleExample ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
2016-03-28 19:44:21 +00:00
err := RunAutoscale ( f , out , cmd , args , options )
2015-10-15 22:15:13 +00:00
cmdutil . CheckErr ( err )
} ,
2016-08-22 02:46:50 +00:00
ValidArgs : validArgs ,
ArgAliases : argAliases ,
2015-10-15 22:15:13 +00:00
}
cmdutil . AddPrinterFlags ( cmd )
2016-06-03 11:31:50 +00:00
cmd . Flags ( ) . String ( "generator" , "horizontalpodautoscaler/v1" , "The name of the API generator to use. Currently there is only 1 generator." )
2015-10-15 22:15:13 +00:00
cmd . Flags ( ) . Int ( "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 ( ) . Int ( "max" , - 1 , "The upper limit for the number of pods that can be set by the autoscaler. Required." )
cmd . MarkFlagRequired ( "max" )
2016-06-03 11:31:50 +00:00
cmd . Flags ( ) . Int ( "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." ) )
2015-10-15 22:15:13 +00:00
cmd . Flags ( ) . String ( "name" , "" , "The name for the newly created object. If not specified, the name of the input resource will be used." )
2016-05-11 00:26:39 +00:00
cmdutil . AddDryRunFlag ( cmd )
2016-08-17 18:28:07 +00:00
usage := "identifying the resource to autoscale."
cmdutil . AddFilenameOptionFlags ( cmd , options , usage )
2015-11-04 21:47:08 +00:00
cmdutil . AddApplyAnnotationFlags ( cmd )
2016-01-22 18:33:23 +00:00
cmdutil . AddRecordFlag ( cmd )
2016-03-10 01:27:19 +00:00
cmdutil . AddInclude3rdPartyFlags ( cmd )
2015-10-15 22:15:13 +00:00
return cmd
}
2016-10-13 00:18:39 +00:00
func RunAutoscale ( f cmdutil . Factory , out io . Writer , cmd * cobra . Command , args [ ] string , options * resource . FilenameOptions ) error {
2015-10-15 22:15:13 +00:00
namespace , enforceNamespace , err := f . DefaultNamespace ( )
if err != nil {
return err
}
// validate flags
if err := validateFlags ( cmd ) ; err != nil {
return err
}
2016-09-16 19:50:34 +00:00
mapper , typer := f . Object ( )
2015-12-21 05:37:49 +00:00
r := resource . NewBuilder ( mapper , typer , resource . ClientMapperFunc ( f . ClientForMapping ) , f . Decoder ( true ) ) .
2015-10-15 22:15:13 +00:00
ContinueOnError ( ) .
NamespaceParam ( namespace ) . DefaultNamespace ( ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( enforceNamespace , options ) .
2015-10-15 22:15:13 +00:00
ResourceTypeOrNameArgs ( false , args ... ) .
Flatten ( ) .
Do ( )
2016-04-14 22:00:40 +00:00
err = r . Err ( )
2015-10-15 22:15:13 +00:00
if err != nil {
return err
}
// Get the generator, setup and validate all required parameters
generatorName := cmdutil . GetFlagString ( cmd , "generator" )
2015-11-19 18:14:10 +00:00
generators := f . Generators ( "autoscale" )
generator , found := generators [ generatorName ]
2015-10-15 22:15:13 +00:00
if ! found {
return cmdutil . UsageError ( cmd , fmt . Sprintf ( "generator %q not found." , generatorName ) )
}
names := generator . ParamNames ( )
2016-04-14 22:00:40 +00:00
count := 0
err = r . Visit ( func ( info * resource . Info , err error ) error {
if err != nil {
return err
}
2015-10-15 22:15:13 +00:00
2016-04-14 22:00:40 +00:00
mapping := info . ResourceMapping ( )
if err := f . CanBeAutoscaled ( mapping . GroupVersionKind . GroupKind ( ) ) ; err != nil {
return err
}
2015-10-15 22:15:13 +00:00
2016-04-14 22:00:40 +00:00
name := info . Name
params := kubectl . MakeParams ( cmd , names )
params [ "default-name" ] = name
2015-10-15 22:15:13 +00:00
2016-04-14 22:00:40 +00:00
params [ "scaleRef-kind" ] = mapping . GroupVersionKind . Kind
params [ "scaleRef-name" ] = name
params [ "scaleRef-apiVersion" ] = mapping . GroupVersionKind . GroupVersion ( ) . String ( )
if err = kubectl . ValidateParams ( names , params ) ; err != nil {
return err
}
// Check for invalid flags used against the present generator.
if err := kubectl . EnsureFlagsValid ( cmd , generators , generatorName ) ; err != nil {
2016-01-22 18:33:23 +00:00
return err
}
2015-10-15 22:15:13 +00:00
2016-04-14 22:00:40 +00:00
// Generate new object
object , err := generator . Generate ( params )
if err != nil {
return err
}
2015-10-15 22:15:13 +00:00
2016-04-14 22:00:40 +00:00
resourceMapper := & resource . Mapper {
ObjectTyper : typer ,
RESTMapper : mapper ,
ClientMapper : resource . ClientMapperFunc ( f . ClientForMapping ) ,
Decoder : f . Decoder ( true ) ,
}
hpa , err := resourceMapper . InfoForObject ( object , nil )
if err != nil {
return err
}
if cmdutil . ShouldRecord ( cmd , hpa ) {
if err := cmdutil . RecordChangeCause ( hpa . Object , f . Command ( ) ) ; err != nil {
return err
}
object = hpa . Object
}
2016-05-11 00:26:39 +00:00
if cmdutil . GetDryRunFlag ( cmd ) {
2016-04-14 22:00:40 +00:00
return f . PrintObject ( cmd , mapper , object , out )
}
if err := kubectl . CreateOrUpdateAnnotation ( cmdutil . GetFlagBool ( cmd , cmdutil . ApplyAnnotationsFlag ) , hpa , f . JSONEncoder ( ) ) ; err != nil {
return err
}
object , err = resource . NewHelper ( hpa . Client , hpa . Mapping ) . Create ( namespace , false , object )
if err != nil {
return err
}
count ++
if len ( cmdutil . GetFlagString ( cmd , "output" ) ) > 0 {
return f . PrintObject ( cmd , mapper , object , out )
}
2016-08-23 18:11:39 +00:00
cmdutil . PrintSuccess ( mapper , false , out , info . Mapping . Resource , info . Name , cmdutil . GetDryRunFlag ( cmd ) , "autoscaled" )
2016-04-14 22:00:40 +00:00
return nil
} )
2015-10-15 22:15:13 +00:00
if err != nil {
return err
}
2016-04-14 22:00:40 +00:00
if count == 0 {
return fmt . Errorf ( "no objects passed to autoscale" )
2015-10-15 22:15:13 +00:00
}
return nil
}
func validateFlags ( cmd * cobra . Command ) error {
errs := [ ] error { }
2016-05-24 12:56:25 +00:00
max , min := cmdutil . GetFlagInt ( cmd , "max" ) , cmdutil . GetFlagInt ( cmd , "min" )
2016-06-22 07:51:15 +00:00
if max < 1 {
2016-08-12 08:19:48 +00:00
errs = append ( errs , fmt . Errorf ( "--max=MAXPODS is required and must be at least 1, max: %d" , max ) )
}
if max < min {
errs = append ( errs , fmt . Errorf ( "--max=MAXPODS must be larger or equal to --min=MINPODS, max: %d, min: %d" , max , min ) )
2015-10-15 22:15:13 +00:00
}
2016-04-14 22:00:40 +00:00
return utilerrors . NewAggregate ( errs )
2015-10-15 22:15:13 +00:00
}