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"
2014-10-06 01:24:19 +00:00
"io"
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"
2017-01-11 14:09:48 +00:00
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/kubectl"
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"
"k8s.io/kubernetes/pkg/kubectl/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"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
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
)
2016-10-13 00:18:39 +00:00
func NewCmdDescribe ( f cmdutil . Factory , out , cmdErr io . Writer ) * cobra . Command {
2016-08-17 18:28:07 +00:00
options := & resource . FilenameOptions { }
2017-02-19 22:56:11 +00:00
describerSettings := & printers . DescriberSettings { }
2015-08-14 18:46:43 +00:00
2017-02-19 22:56:11 +00:00
// TODO: this should come from the factory, and may need to be loaded from the server, and so is probably
// going to have to be removed
validArgs := printersinternal . DescribableResources ( )
2016-03-20 18:14:25 +00:00
argAliases := kubectl . ResourceAliases ( validArgs )
2015-07-07 23:57:37 +00:00
cmd := & cobra . Command {
2015-07-07 07:31:08 +00:00
Use : "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)" ,
2017-01-25 01:00:32 +00:00
Short : i18n . T ( "Show details of a specific resource or group of resources" ) ,
2017-10-24 01:14:31 +00:00
Long : describeLong + "\n\n" + cmdutil . ValidResourceTypeList ( f ) ,
Example : describeExample ,
2014-10-06 01:24:19 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2016-08-23 03:11:05 +00:00
err := RunDescribe ( f , out , cmdErr , cmd , args , options , describerSettings )
2015-04-07 18:21:25 +00:00
cmdutil . CheckErr ( err )
2015-03-09 22:08:16 +00:00
} ,
2016-03-20 18:14:25 +00:00
ValidArgs : validArgs ,
ArgAliases : argAliases ,
2015-03-09 22:08:16 +00:00
}
2016-08-17 18:28:07 +00:00
usage := "containing the resource to describe"
cmdutil . AddFilenameOptionFlags ( cmd , options , usage )
2017-08-17 12:27:11 +00:00
cmd . Flags ( ) . StringP ( "selector" , "l" , "" , "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)" )
2016-05-25 22:08:56 +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." )
2016-04-20 17:27:32 +00:00
cmd . Flags ( ) . BoolVar ( & describerSettings . ShowEvents , "show-events" , true , "If true, display events related to the described object." )
2016-03-10 01:27:19 +00:00
cmdutil . AddInclude3rdPartyFlags ( cmd )
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
2017-02-19 22:56:11 +00:00
func RunDescribe ( f cmdutil . Factory , out , cmdErr io . Writer , cmd * cobra . Command , args [ ] string , options * resource . FilenameOptions , describerSettings * printers . DescriberSettings ) error {
2015-06-12 07:08:28 +00:00
selector := cmdutil . GetFlagString ( cmd , "selector" )
2016-05-25 22:08:56 +00:00
allNamespaces := cmdutil . GetFlagBool ( cmd , "all-namespaces" )
2015-07-07 07:31:08 +00:00
cmdNamespace , enforceNamespace , err := f . DefaultNamespace ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2016-05-25 22:08:56 +00:00
if allNamespaces {
enforceNamespace = false
}
2017-06-14 21:14:42 +00:00
if len ( args ) == 0 && cmdutil . IsFilenameSliceEmpty ( options . Filenames ) {
2017-10-24 01:14:31 +00:00
fmt . Fprint ( cmdErr , "You must specify the type of resource to describe. " , cmdutil . ValidResourceTypeList ( f ) )
2017-06-14 21:14:42 +00:00
return cmdutil . UsageErrorf ( cmd , "Required resource not specified." )
2015-07-07 03:14:28 +00:00
}
2017-08-11 06:21:44 +00:00
// include the uninitialized objects by default
// unless user explicitly set --include-uninitialized=false
includeUninitialized := cmdutil . ShouldIncludeUninitialized ( cmd , true )
2017-11-14 03:43:58 +00:00
r := f . NewBuilder ( ) .
2017-11-14 04:01:51 +00:00
Unstructured ( ) .
2015-04-08 13:34:07 +00:00
ContinueOnError ( ) .
2016-05-25 22:08:56 +00:00
NamespaceParam ( cmdNamespace ) . DefaultNamespace ( ) . AllNamespaces ( allNamespaces ) .
2016-08-17 18:28:07 +00:00
FilenameParam ( enforceNamespace , options ) .
2017-08-04 06:54:17 +00:00
LabelSelectorParam ( selector ) .
2017-08-11 06:21:44 +00:00
IncludeUninitialized ( includeUninitialized ) .
2015-08-04 07:12:29 +00:00
ResourceTypeOrNameArgs ( true , args ... ) .
2015-04-08 13:34:07 +00:00
Flatten ( ) .
Do ( )
err = r . Err ( )
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 {
2015-07-07 03:14:28 +00:00
if apierrors . IsNotFound ( err ) && len ( args ) == 2 {
2017-03-17 13:55:46 +00:00
return DescribeMatchingResources ( f , cmdNamespace , args [ 0 ] , args [ 1 ] , describerSettings , out , err )
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 ( )
describer , err := f . Describer ( mapping )
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
}
2016-04-20 17:27:32 +00:00
s , err := describer . Describe ( info . Namespace , info . Name , * 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
fmt . Fprint ( out , s )
} else {
fmt . Fprintf ( out , "\n\n%s" , s )
}
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
2017-03-17 13:55:46 +00:00
func DescribeMatchingResources ( f cmdutil . Factory , namespace , rsrc , prefix string , describerSettings * printers . DescriberSettings , out io . Writer , originalError error ) error {
2017-11-14 04:01:51 +00:00
r := f . NewBuilder ( ) . Unstructured ( ) .
2015-04-29 23:47:10 +00:00
NamespaceParam ( namespace ) . DefaultNamespace ( ) .
ResourceTypeOrNameArgs ( true , rsrc ) .
SingleResourceType ( ) .
Flatten ( ) .
Do ( )
2015-07-07 07:31:08 +00:00
mapping , err := r . ResourceMapping ( )
if err != nil {
return err
}
describer , err := f . Describer ( mapping )
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
2016-04-20 17:27:32 +00:00
s , err := describer . Describe ( info . Namespace , info . Name , * describerSettings )
2015-04-29 23:47:10 +00:00
if err != nil {
return err
}
fmt . Fprintf ( out , "%s\n" , s )
}
}
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
}