2014-10-06 01:24:19 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
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-10-27 19:56:34 +00:00
"fmt"
2015-04-29 23:47:10 +00:00
"strings"
2014-10-06 01:24:19 +00:00
"github.com/spf13/cobra"
2015-04-08 13:34:07 +00:00
2017-01-13 17:48:50 +00:00
apierrors "k8s.io/apimachinery/pkg/api/errors"
2018-04-25 23:58:24 +00:00
"k8s.io/apimachinery/pkg/api/meta"
2017-01-11 14:09:48 +00:00
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
2016-10-07 22:24:42 +00:00
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
2015-08-05 22:03:47 +00:00
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2018-04-25 23:58:24 +00:00
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
2018-05-10 12:20:27 +00:00
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
2017-07-07 04:04:11 +00:00
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
2017-02-19 22:56:11 +00:00
"k8s.io/kubernetes/pkg/printers"
2014-10-06 01:24:19 +00:00
)
2016-05-20 17:49:56 +00:00
var (
2017-10-24 01:14:31 +00:00
describeLong = templates . LongDesc ( `
Show details of a specific resource or group of resources
Print a detailed description of the selected resources , including related resources such
as events or controllers . You may select a single object by name , all objects of that
type , provide a name prefix , or label selector . For example :
2014-10-06 01:24:19 +00:00
2016-10-07 22:24:42 +00:00
$ kubectl describe TYPE NAME_PREFIX
2015-07-07 23:57:37 +00:00
2016-05-20 17:49:56 +00:00
will first check for an exact match on TYPE and NAME_PREFIX . If no such resource
2017-10-24 01:14:31 +00:00
exists , it will output details for every resource that has a name prefixed with NAME_PREFIX . ` )
2015-07-07 03:14:28 +00:00
2017-10-24 01:14:31 +00:00
describeExample = templates . Examples ( i18n . T ( `
2016-05-20 17:49:56 +00:00
# Describe a node
2016-05-05 20:41:49 +00:00
kubectl describe nodes kubernetes - node - emt8 . c . myproject . internal
2015-04-23 21:21:13 +00:00
2016-05-20 17:49:56 +00:00
# Describe a pod
kubectl describe pods / nginx
2015-06-12 07:08:28 +00:00
2016-05-20 17:49:56 +00:00
# Describe a pod identified by type and name in "pod.json"
kubectl describe - f pod . json
2015-07-07 07:31:08 +00:00
2016-05-20 17:49:56 +00:00
# Describe all pods
kubectl describe pods
2015-08-04 07:12:29 +00:00
2016-05-20 17:49:56 +00:00
# Describe pods by label name = myLabel
kubectl describe po - l name = myLabel
2015-07-07 23:57:37 +00:00
2016-05-20 17:49:56 +00:00
# Describe all pods managed by the ' frontend ' replication controller ( rc - created pods
# get the name of the rc as a prefix in the pod the name ) .
2017-03-15 03:49:10 +00:00
kubectl describe pods frontend ` ) )
2015-07-07 23:57:37 +00:00
)
2018-04-25 23:58:24 +00:00
type DescribeOptions struct {
CmdParent string
Selector string
Namespace string
2018-05-02 20:53:26 +00:00
Describer func ( * meta . RESTMapping ) ( printers . Describer , error )
NewBuilder func ( ) * resource . Builder
2018-04-25 23:58:24 +00:00
BuilderArgs [ ] string
EnforceNamespace bool
AllNamespaces bool
IncludeUninitialized bool
DescriberSettings * printers . DescriberSettings
FilenameOptions * resource . FilenameOptions
genericclioptions . IOStreams
}
func NewCmdDescribe ( parent string , f cmdutil . Factory , streams genericclioptions . IOStreams ) * cobra . Command {
o := & DescribeOptions {
FilenameOptions : & resource . FilenameOptions { } ,
DescriberSettings : & printers . DescriberSettings {
ShowEvents : true ,
} ,
CmdParent : parent ,
IOStreams : streams ,
2018-03-01 05:23:49 +00:00
}
2015-08-14 18:46:43 +00:00
2015-07-07 23:57:37 +00:00
cmd := & cobra . Command {
2017-10-11 06:26:02 +00:00
Use : "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)" ,
DisableFlagsInUseLine : true ,
2017-01-25 01:00:32 +00:00
Short : i18n . T ( "Show details of a specific resource or group of resources" ) ,
2018-04-25 23:55:26 +00:00
Long : describeLong + "\n\n" + cmdutil . SuggestApiResources ( parent ) ,
2017-10-24 01:14:31 +00:00
Example : describeExample ,
2014-10-06 01:24:19 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2018-04-25 23:58:24 +00:00
cmdutil . CheckErr ( o . Complete ( f , cmd , args ) )
cmdutil . CheckErr ( o . Run ( ) )
2015-03-09 22:08:16 +00:00
} ,
}
2016-08-17 18:28:07 +00:00
usage := "containing the resource to describe"
2018-04-25 23:58:24 +00:00
cmdutil . AddFilenameOptionFlags ( cmd , o . FilenameOptions , usage )
2018-05-10 08:48:37 +00:00
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 . AllNamespaces , "all-namespaces" , o . AllNamespaces , "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace." )
2018-04-25 23:58:24 +00:00
cmd . Flags ( ) . BoolVar ( & o . DescriberSettings . ShowEvents , "show-events" , o . DescriberSettings . ShowEvents , "If true, display events related to the described object." )
2017-08-11 06:21:44 +00:00
cmdutil . AddIncludeUninitializedFlag ( cmd )
2015-03-09 22:08:16 +00:00
return cmd
}
2015-01-02 18:08:37 +00:00
2018-04-25 23:58:24 +00:00
func ( o * DescribeOptions ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string ) error {
var err error
2018-05-24 13:33:36 +00:00
o . Namespace , o . EnforceNamespace , err = f . ToRawKubeConfigLoader ( ) . Namespace ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2018-04-25 23:58:24 +00:00
if o . AllNamespaces {
o . EnforceNamespace = false
2016-05-25 22:08:56 +00:00
}
2018-04-25 23:58:24 +00:00
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 ) )
2015-07-07 03:14:28 +00:00
}
2018-04-25 23:58:24 +00:00
o . BuilderArgs = args
2018-05-23 21:43:04 +00:00
o . Describer = func ( mapping * meta . RESTMapping ) ( printers . Describer , error ) {
return cmdutil . DescriberFn ( f , mapping )
}
2018-05-02 20:53:26 +00:00
o . NewBuilder = f . NewBuilder
2018-04-25 23:58:24 +00:00
2017-08-11 06:21:44 +00:00
// include the uninitialized objects by default
// unless user explicitly set --include-uninitialized=false
2018-04-25 23:58:24 +00:00
o . IncludeUninitialized = cmdutil . ShouldIncludeUninitialized ( cmd , true )
return nil
}
func ( o * DescribeOptions ) Validate ( args [ ] string ) error {
return nil
}
func ( o * DescribeOptions ) Run ( ) error {
2018-05-02 20:53:26 +00:00
r := o . NewBuilder ( ) .
2017-11-14 04:01:51 +00:00
Unstructured ( ) .
2015-04-08 13:34:07 +00:00
ContinueOnError ( ) .
2018-04-25 23:58:24 +00:00
NamespaceParam ( o . Namespace ) . DefaultNamespace ( ) . AllNamespaces ( o . AllNamespaces ) .
FilenameParam ( o . EnforceNamespace , o . FilenameOptions ) .
LabelSelectorParam ( o . Selector ) .
IncludeUninitialized ( o . IncludeUninitialized ) .
ResourceTypeOrNameArgs ( true , o . BuilderArgs ... ) .
2015-04-08 13:34:07 +00:00
Flatten ( ) .
Do ( )
2018-04-25 23:58:24 +00:00
err := r . Err ( )
2015-04-08 13:34:07 +00:00
if err != nil {
return err
}
2014-10-27 19:56:34 +00:00
2015-07-07 07:31:08 +00:00
allErrs := [ ] error { }
2015-04-08 13:34:07 +00:00
infos , err := r . Infos ( )
if err != nil {
2018-04-25 23:58:24 +00:00
if apierrors . IsNotFound ( err ) && len ( o . BuilderArgs ) == 2 {
return o . DescribeMatchingResources ( err , o . BuilderArgs [ 0 ] , o . BuilderArgs [ 1 ] )
2015-04-29 23:47:10 +00:00
}
2015-07-07 07:31:08 +00:00
allErrs = append ( allErrs , err )
2015-04-08 13:34:07 +00:00
}
2015-03-09 22:08:16 +00:00
2016-11-09 21:28:36 +00:00
errs := sets . NewString ( )
2016-08-13 23:07:28 +00:00
first := true
2015-06-12 07:08:28 +00:00
for _ , info := range infos {
2015-07-07 07:31:08 +00:00
mapping := info . ResourceMapping ( )
2018-04-25 23:58:24 +00:00
describer , err := o . Describer ( mapping )
2015-07-07 07:31:08 +00:00
if err != nil {
2016-11-09 21:28:36 +00:00
if errs . Has ( err . Error ( ) ) {
continue
}
2015-07-07 07:31:08 +00:00
allErrs = append ( allErrs , err )
2016-11-09 21:28:36 +00:00
errs . Insert ( err . Error ( ) )
2015-07-07 07:31:08 +00:00
continue
}
2018-04-25 23:58:24 +00:00
s , err := describer . Describe ( info . Namespace , info . Name , * o . DescriberSettings )
2015-06-12 07:08:28 +00:00
if err != nil {
2016-11-09 21:28:36 +00:00
if errs . Has ( err . Error ( ) ) {
continue
}
2015-07-07 07:31:08 +00:00
allErrs = append ( allErrs , err )
2016-11-09 21:28:36 +00:00
errs . Insert ( err . Error ( ) )
2015-07-07 07:31:08 +00:00
continue
2015-06-12 07:08:28 +00:00
}
2016-08-13 23:07:28 +00:00
if first {
first = false
2018-04-25 23:58:24 +00:00
fmt . Fprint ( o . Out , s )
2016-08-13 23:07:28 +00:00
} else {
2018-04-25 23:58:24 +00:00
fmt . Fprintf ( o . Out , "\n\n%s" , s )
2016-08-13 23:07:28 +00:00
}
2015-03-09 22:08:16 +00:00
}
2015-06-12 07:08:28 +00:00
2015-10-14 05:18:37 +00:00
return utilerrors . NewAggregate ( allErrs )
2014-10-06 01:24:19 +00:00
}
2015-04-29 23:47:10 +00:00
2018-04-25 23:58:24 +00:00
func ( o * DescribeOptions ) DescribeMatchingResources ( originalError error , resource , prefix string ) error {
2018-05-02 20:53:26 +00:00
r := o . NewBuilder ( ) .
2017-11-15 06:10:30 +00:00
Unstructured ( ) .
2018-04-25 23:58:24 +00:00
NamespaceParam ( o . Namespace ) . DefaultNamespace ( ) .
ResourceTypeOrNameArgs ( true , resource ) .
2015-04-29 23:47:10 +00:00
SingleResourceType ( ) .
Flatten ( ) .
Do ( )
2015-07-07 07:31:08 +00:00
mapping , err := r . ResourceMapping ( )
if err != nil {
return err
}
2018-04-25 23:58:24 +00:00
describer , err := o . Describer ( mapping )
2015-07-07 07:31:08 +00:00
if err != nil {
return err
}
2015-04-29 23:47:10 +00:00
infos , err := r . Infos ( )
if err != nil {
return err
}
2015-06-30 06:12:58 +00:00
isFound := false
2015-04-29 23:47:10 +00:00
for ix := range infos {
info := infos [ ix ]
if strings . HasPrefix ( info . Name , prefix ) {
2015-06-30 06:12:58 +00:00
isFound = true
2018-04-25 23:58:24 +00:00
s , err := describer . Describe ( info . Namespace , info . Name , * o . DescriberSettings )
2015-04-29 23:47:10 +00:00
if err != nil {
return err
}
2018-04-25 23:58:24 +00:00
fmt . Fprintf ( o . Out , "%s\n" , s )
2015-04-29 23:47:10 +00:00
}
}
2015-06-30 06:12:58 +00:00
if ! isFound {
2015-07-03 07:28:05 +00:00
return originalError
2015-06-30 06:12:58 +00:00
}
2015-04-29 23:47:10 +00:00
return nil
}