2014-10-06 01:24:19 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-10-06 01:24:19 +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 (
2014-11-01 22:44:03 +00:00
"fmt"
2014-10-06 01:24:19 +00:00
"io"
2015-08-10 11:02:14 +00:00
"github.com/spf13/cobra"
2015-10-13 18:36:22 +00:00
"k8s.io/kubernetes/pkg/api/meta"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
2015-10-20 05:44:48 +00:00
"k8s.io/kubernetes/pkg/runtime"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/watch"
2014-10-06 01:24:19 +00:00
)
2015-08-14 18:46:43 +00:00
// GetOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags()
type GetOptions struct {
Filenames [ ] string
}
2015-02-20 21:28:43 +00:00
const (
get_long = ` Display one or many resources .
2014-10-06 01:24:19 +00:00
2015-07-06 11:31:27 +00:00
Possible resource types include ( case insensitive ) : pods ( po ) , services ( svc ) ,
2015-07-06 11:36:06 +00:00
replicationcontrollers ( rc ) , nodes ( no ) , events ( ev ) , componentstatuses ( cs ) ,
limitranges ( limits ) , persistentvolumes ( pv ) , persistentvolumeclaims ( pvc ) ,
2015-11-19 14:16:26 +00:00
resourcequotas ( quota ) , namespaces ( ns ) , endpoints ( ep ) ,
horizontalpodautoscalers ( hpa ) , serviceaccounts or secrets .
2014-10-06 01:24:19 +00:00
2015-02-03 17:59:21 +00:00
By specifying the output as ' template ' and providing a Go template as the value
2015-02-20 21:28:43 +00:00
of the -- template flag , you can filter the attributes of the fetched resource ( s ) . `
2015-08-12 16:50:09 +00:00
get_example = ` # List all pods in ps output format .
2015-02-20 21:28:43 +00:00
$ kubectl get pods
2014-10-06 01:24:19 +00:00
2015-08-12 16:50:09 +00:00
# List all pods in ps output format with more information ( such as node name ) .
2015-06-29 18:36:06 +00:00
$ kubectl get pods - o wide
2015-08-12 16:50:09 +00:00
# List a single replication controller with specified NAME in ps output format .
2015-05-21 00:17:01 +00:00
$ kubectl get replicationcontroller web
2014-10-06 01:24:19 +00:00
2015-08-12 16:50:09 +00:00
# List a single pod in JSON output format .
2015-03-25 05:01:07 +00:00
$ kubectl get - o json pod web - pod - 13 je7
2014-12-31 00:42:55 +00:00
2015-08-10 11:02:14 +00:00
# List a pod identified by type and name specified in "pod.yaml" in JSON output format .
$ kubectl get - f pod . yaml - o json
2015-08-12 16:50:09 +00:00
# Return only the phase value of the specified pod .
2015-08-17 18:53:43 +00:00
$ kubectl get - o template pod / web - pod - 13 je7 -- template = { { . status . phase } } -- api - version = v1
2015-02-03 17:59:21 +00:00
2015-08-12 16:50:09 +00:00
# List all replication controllers and services together in ps output format .
2015-03-25 05:01:07 +00:00
$ kubectl get rc , services
2015-08-12 16:50:09 +00:00
# List one or more resources by their type and names .
2015-03-25 05:01:07 +00:00
$ kubectl get rc / web service / frontend pods / web - pod - 13 je7 `
2015-02-20 21:28:43 +00:00
)
2015-02-03 17:59:21 +00:00
2015-02-20 21:28:43 +00:00
// NewCmdGet creates a command object for the generic "get" action, which
// retrieves one or more resources from a server.
2015-04-07 18:21:25 +00:00
func NewCmdGet ( f * cmdutil . Factory , out io . Writer ) * cobra . Command {
2015-08-14 18:46:43 +00:00
options := & GetOptions { }
2015-03-17 17:01:57 +00:00
2015-09-02 22:38:40 +00:00
// retrieve a list of handled resources from printer as valid args
validArgs := [ ] string { }
2015-11-10 11:34:28 +00:00
p , err := f . Printer ( nil , false , false , false , false , false , [ ] string { } )
2015-09-02 22:38:40 +00:00
cmdutil . CheckErr ( err )
if p != nil {
validArgs = p . HandledResources ( )
}
2015-02-20 21:28:43 +00:00
cmd := & cobra . Command {
2015-08-21 13:09:41 +00:00
Use : "get [(-o|--output=)json|yaml|wide|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]" ,
2015-02-20 21:28:43 +00:00
Short : "Display one or many resources" ,
Long : get_long ,
Example : get_example ,
2014-10-06 01:24:19 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2015-08-14 18:46:43 +00:00
err := RunGet ( f , out , cmd , args , options )
2015-04-07 18:21:25 +00:00
cmdutil . CheckErr ( err )
2014-12-31 00:42:55 +00:00
} ,
2015-03-17 17:01:57 +00:00
ValidArgs : validArgs ,
2014-12-31 00:42:55 +00:00
}
2015-04-07 18:21:25 +00:00
cmdutil . AddPrinterFlags ( cmd )
2014-12-31 00:42:55 +00:00
cmd . Flags ( ) . StringP ( "selector" , "l" , "" , "Selector (label query) to filter on" )
cmd . Flags ( ) . BoolP ( "watch" , "w" , false , "After listing/getting the requested object, watch for changes." )
2015-01-18 07:32:34 +00:00
cmd . Flags ( ) . Bool ( "watch-only" , false , "Watch for changes to the requested object(s), without listing/getting first." )
2015-05-12 11:14:31 +00:00
cmd . Flags ( ) . Bool ( "all-namespaces" , false , "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace." )
2015-08-05 14:21:47 +00:00
cmd . Flags ( ) . StringSliceP ( "label-columns" , "L" , [ ] string { } , "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2..." )
2015-12-02 20:20:10 +00:00
cmd . Flags ( ) . Bool ( "export" , false , "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information." )
2015-08-10 11:02:14 +00:00
usage := "Filename, directory, or URL to a file identifying the resource to get from a server."
2015-08-14 18:46:43 +00:00
kubectl . AddJsonFilenameFlag ( cmd , & options . Filenames , usage )
2014-12-31 00:42:55 +00:00
return cmd
}
2014-10-27 19:56:34 +00:00
2014-12-31 00:42:55 +00:00
// RunGet implements the generic Get command
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd
2015-08-14 18:46:43 +00:00
func RunGet ( f * cmdutil . Factory , out io . Writer , cmd * cobra . Command , args [ ] string , options * GetOptions ) error {
2015-04-07 18:21:25 +00:00
selector := cmdutil . GetFlagString ( cmd , "selector" )
2015-05-12 11:14:31 +00:00
allNamespaces := cmdutil . GetFlagBool ( cmd , "all-namespaces" )
2015-03-14 10:45:18 +00:00
mapper , typer := f . Object ( )
2014-12-31 00:42:55 +00:00
2015-08-10 11:02:14 +00:00
cmdNamespace , enforceNamespace , err := f . DefaultNamespace ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-01-02 18:08:37 +00:00
2015-08-14 18:46:43 +00:00
if len ( args ) == 0 && len ( options . Filenames ) == 0 {
2015-12-09 10:31:35 +00:00
fmt . Fprint ( out , "You must specify the type of resource to get. " , valid_resources )
2015-07-07 03:14:28 +00:00
return cmdutil . UsageError ( cmd , "Required resource not specified." )
2015-06-09 22:04:56 +00:00
}
2015-12-03 19:32:22 +00:00
// always show resources when getting by name or filename
argsHasNames , err := resource . HasNames ( args )
if err != nil {
return err
}
if len ( options . Filenames ) > 0 || argsHasNames {
cmd . Flag ( "show-all" ) . Value . Set ( "true" )
}
2015-12-02 20:20:10 +00:00
export := cmdutil . GetFlagBool ( cmd , "export" )
2015-12-03 19:32:22 +00:00
2014-12-31 00:42:55 +00:00
// handle watch separately since we cannot watch multiple resource types
2015-04-07 18:21:25 +00:00
isWatch , isWatchOnly := cmdutil . GetFlagBool ( cmd , "watch" ) , cmdutil . GetFlagBool ( cmd , "watch-only" )
2014-12-31 00:42:55 +00:00
if isWatch || isWatchOnly {
2015-12-21 05:37:49 +00:00
r := resource . NewBuilder ( mapper , typer , resource . ClientMapperFunc ( f . ClientForMapping ) , f . Decoder ( true ) ) .
2015-05-12 11:14:31 +00:00
NamespaceParam ( cmdNamespace ) . DefaultNamespace ( ) . AllNamespaces ( allNamespaces ) .
2015-08-14 18:46:43 +00:00
FilenameParam ( enforceNamespace , options . Filenames ... ) .
2014-12-31 00:42:55 +00:00
SelectorParam ( selector ) .
2015-12-02 20:20:10 +00:00
ExportParam ( export ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , args ... ) .
2014-12-31 00:42:55 +00:00
SingleResourceType ( ) .
2015-08-10 11:02:14 +00:00
Latest ( ) .
2014-12-31 00:42:55 +00:00
Do ( )
2015-09-09 10:02:22 +00:00
err := r . Err ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-08-10 11:02:14 +00:00
infos , err := r . Infos ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-08-10 11:02:14 +00:00
if len ( infos ) != 1 {
2015-10-14 22:06:06 +00:00
return fmt . Errorf ( "watch is only supported on individual resources and resource collections - %d resources were found" , len ( infos ) )
2015-08-10 11:02:14 +00:00
}
info := infos [ 0 ]
mapping := info . ResourceMapping ( )
2015-05-12 11:14:31 +00:00
printer , err := f . PrinterForMapping ( cmd , mapping , allNamespaces )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-12-31 00:42:55 +00:00
obj , err := r . Object ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-12-31 00:42:55 +00:00
rv , err := mapping . MetadataAccessor . ResourceVersion ( obj )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-12-31 00:42:55 +00:00
// print the current object
if ! isWatchOnly {
if err := printer . PrintObj ( obj , out ) ; err != nil {
2015-03-09 22:08:16 +00:00
return fmt . Errorf ( "unable to output the provided object: %v" , err )
2014-12-31 00:42:55 +00:00
}
}
2014-10-27 19:56:34 +00:00
2014-12-31 00:42:55 +00:00
// print watched changes
w , err := r . Watch ( rv )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-10-27 19:56:34 +00:00
2014-12-31 00:42:55 +00:00
kubectl . WatchLoop ( w , func ( e watch . Event ) error {
return printer . PrintObj ( e . Object , out )
} )
2015-03-09 22:08:16 +00:00
return nil
2014-12-31 00:42:55 +00:00
}
2014-10-27 19:56:34 +00:00
2015-12-21 05:37:49 +00:00
b := resource . NewBuilder ( mapper , typer , resource . ClientMapperFunc ( f . ClientForMapping ) , f . Decoder ( true ) ) .
2015-05-12 11:14:31 +00:00
NamespaceParam ( cmdNamespace ) . DefaultNamespace ( ) . AllNamespaces ( allNamespaces ) .
2015-08-14 18:46:43 +00:00
FilenameParam ( enforceNamespace , options . Filenames ... ) .
2014-12-31 00:42:55 +00:00
SelectorParam ( selector ) .
2015-12-02 20:20:10 +00:00
ExportParam ( export ) .
2015-02-12 14:59:58 +00:00
ResourceTypeOrNameArgs ( true , args ... ) .
2015-03-25 05:01:07 +00:00
ContinueOnError ( ) .
2014-12-31 00:42:55 +00:00
Latest ( )
2015-04-07 18:21:25 +00:00
printer , generic , err := cmdutil . PrinterForCommand ( cmd )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-11-01 22:44:03 +00:00
2014-12-31 00:42:55 +00:00
if generic {
2015-03-14 10:45:18 +00:00
clientConfig , err := f . ClientConfig ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-01-02 18:08:37 +00:00
2015-04-16 23:21:13 +00:00
singular := false
2015-03-04 03:18:15 +00:00
r := b . Flatten ( ) . Do ( )
2015-04-16 23:21:13 +00:00
infos , err := r . IntoSingular ( & singular ) . Infos ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2014-11-18 18:04:10 +00:00
2015-04-16 23:21:13 +00:00
// the outermost object will be converted to the output-version, but inner
// objects can use their mappings
2015-12-01 16:52:11 +00:00
version , err := cmdutil . OutputVersion ( cmd , clientConfig . GroupVersion )
if err != nil {
return err
}
2015-12-21 05:37:49 +00:00
obj , err := resource . AsVersionedObject ( infos , ! singular , version . String ( ) , f . JSONEncoder ( ) )
2015-04-16 23:21:13 +00:00
if err != nil {
return err
2015-03-04 03:18:15 +00:00
}
2015-03-09 22:08:16 +00:00
return printer . PrintObj ( obj , out )
2014-12-31 00:42:55 +00:00
}
2014-11-12 01:31:13 +00:00
2015-10-20 05:44:48 +00:00
infos , err := b . Flatten ( ) . Do ( ) . Infos ( )
if err != nil {
return err
}
objs := make ( [ ] runtime . Object , len ( infos ) )
for ix := range infos {
objs [ ix ] = infos [ ix ] . Object
}
sorting , err := cmd . Flags ( ) . GetString ( "sort-by" )
var sorter * kubectl . RuntimeSort
2016-01-13 17:11:46 +00:00
if err == nil && len ( sorting ) > 0 && len ( objs ) > 1 {
2015-12-21 05:37:49 +00:00
// TODO: questionable
if sorter , err = kubectl . SortObjects ( f . Decoder ( true ) , objs , sorting ) ; err != nil {
2015-10-20 05:44:48 +00:00
return err
}
}
2014-12-31 00:42:55 +00:00
// use the default printer for each object
2015-10-13 18:36:22 +00:00
printer = nil
var lastMapping * meta . RESTMapping
2015-10-14 01:48:06 +00:00
w := kubectl . GetNewTabWriter ( out )
2015-10-13 18:36:22 +00:00
defer w . Flush ( )
2015-10-20 05:44:48 +00:00
for ix := range objs {
var mapping * meta . RESTMapping
if sorter != nil {
mapping = infos [ sorter . OriginalPosition ( ix ) ] . Mapping
} else {
mapping = infos [ ix ] . Mapping
2015-06-15 02:48:56 +00:00
}
2015-10-20 05:44:48 +00:00
if printer == nil || lastMapping == nil || mapping == nil || mapping . Resource != lastMapping . Resource {
printer , err = f . PrinterForMapping ( cmd , mapping , allNamespaces )
2015-10-13 18:36:22 +00:00
if err != nil {
return err
}
2015-10-20 05:44:48 +00:00
lastMapping = mapping
2015-10-13 18:36:22 +00:00
}
if _ , found := printer . ( * kubectl . HumanReadablePrinter ) ; found {
2015-10-20 05:44:48 +00:00
if err := printer . PrintObj ( objs [ ix ] , w ) ; err != nil {
return err
}
2015-11-09 05:42:52 +00:00
continue
2015-10-20 05:44:48 +00:00
}
if err := printer . PrintObj ( objs [ ix ] , out ) ; err != nil {
return err
2014-12-31 00:42:55 +00:00
}
2015-10-20 05:44:48 +00:00
}
return nil
2014-12-31 00:42:55 +00:00
}