mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #24554 from ingvagabund/dhodovska-events-flag-for-describers
Automatic merge from submit-queue Introduce events flag for describers Printing events for a given object is not always needed. Thus, introducing --show-events=false to ``kubectl describe`` to skip events printing. Fixes: #24239
This commit is contained in:
commit
41b7b04faf
@ -497,6 +497,7 @@ _kubectl_describe()
|
|||||||
flags+=("-R")
|
flags+=("-R")
|
||||||
flags+=("--selector=")
|
flags+=("--selector=")
|
||||||
two_word_flags+=("-l")
|
two_word_flags+=("-l")
|
||||||
|
flags+=("--show-events")
|
||||||
flags+=("--alsologtostderr")
|
flags+=("--alsologtostderr")
|
||||||
flags+=("--api-version=")
|
flags+=("--api-version=")
|
||||||
flags+=("--as=")
|
flags+=("--as=")
|
||||||
|
@ -51,6 +51,10 @@ componentstatuses (cs), endpoints (ep), and secrets.
|
|||||||
\fB\-l\fP, \fB\-\-selector\fP=""
|
\fB\-l\fP, \fB\-\-selector\fP=""
|
||||||
Selector (label query) to filter on
|
Selector (label query) to filter on
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-show\-events\fP=true
|
||||||
|
If true, display events related to the described object.
|
||||||
|
|
||||||
|
|
||||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||||
.PP
|
.PP
|
||||||
|
@ -89,6 +89,7 @@ kubectl describe pods frontend
|
|||||||
--include-extended-apis[=true]: If true, include definitions of new APIs via calls to the API server. [default true]
|
--include-extended-apis[=true]: If true, include definitions of new APIs via calls to the API server. [default true]
|
||||||
-R, --recursive[=false]: If true, process directory recursively.
|
-R, --recursive[=false]: If true, process directory recursively.
|
||||||
-l, --selector="": Selector (label query) to filter on
|
-l, --selector="": Selector (label query) to filter on
|
||||||
|
--show-events[=true]: If true, display events related to the described object.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options inherited from parent commands
|
### Options inherited from parent commands
|
||||||
@ -123,7 +124,7 @@ kubectl describe pods frontend
|
|||||||
|
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 30-Mar-2016
|
###### Auto generated by spf13/cobra on 26-Apr-2016
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
[]()
|
[]()
|
||||||
|
@ -33,6 +33,9 @@ options:
|
|||||||
- name: selector
|
- name: selector
|
||||||
shorthand: l
|
shorthand: l
|
||||||
usage: Selector (label query) to filter on
|
usage: Selector (label query) to filter on
|
||||||
|
- name: show-events
|
||||||
|
default_value: "true"
|
||||||
|
usage: If true, display events related to the described object.
|
||||||
inherited_options:
|
inherited_options:
|
||||||
- name: alsologtostderr
|
- name: alsologtostderr
|
||||||
default_value: "false"
|
default_value: "false"
|
||||||
|
@ -108,6 +108,44 @@ kube::test::describe_object_assert() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kube::test::describe_object_events_assert() {
|
||||||
|
local resource=$1
|
||||||
|
local object=$2
|
||||||
|
local showevents=${3:-"true"}
|
||||||
|
|
||||||
|
if [[ -z "${3:-}" ]]; then
|
||||||
|
result=$(eval kubectl describe "${kube_flags[@]}" $resource $object)
|
||||||
|
else
|
||||||
|
result=$(eval kubectl describe "${kube_flags[@]}" "--show-events=$showevents" $resource $object)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $(echo "$result" | grep "No events.\|Events:") ]]; then
|
||||||
|
local has_events="true"
|
||||||
|
else
|
||||||
|
local has_events="false"
|
||||||
|
fi
|
||||||
|
if [[ $showevents == $has_events ]]; then
|
||||||
|
echo -n ${green}
|
||||||
|
echo "Successful describe"
|
||||||
|
echo "$result"
|
||||||
|
echo ${reset}
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo ${bold}${red}
|
||||||
|
echo "FAIL"
|
||||||
|
if [[ $showevents == "false" ]]; then
|
||||||
|
echo " Events information should not be described in:"
|
||||||
|
else
|
||||||
|
echo " Events information not found in:"
|
||||||
|
fi
|
||||||
|
echo $result
|
||||||
|
echo ${reset}${red}
|
||||||
|
caller
|
||||||
|
echo ${reset}
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
kube::test::describe_resource_assert() {
|
kube::test::describe_resource_assert() {
|
||||||
local resource=$1
|
local resource=$1
|
||||||
local matches=${@:2}
|
local matches=${@:2}
|
||||||
@ -136,6 +174,38 @@ kube::test::describe_resource_assert() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kube::test::describe_resource_events_assert() {
|
||||||
|
local resource=$1
|
||||||
|
local showevents=${2:-"true"}
|
||||||
|
|
||||||
|
result=$(eval kubectl describe "${kube_flags[@]}" "--show-events=$showevents" $resource)
|
||||||
|
|
||||||
|
if [[ $(echo "$result" | grep "No events.\|Events:") ]]; then
|
||||||
|
local has_events="true"
|
||||||
|
else
|
||||||
|
local has_events="false"
|
||||||
|
fi
|
||||||
|
if [[ $showevents == $has_events ]]; then
|
||||||
|
echo -n ${green}
|
||||||
|
echo "Successful describe"
|
||||||
|
echo "$result"
|
||||||
|
echo -n ${reset}
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo ${bold}${red}
|
||||||
|
echo "FAIL"
|
||||||
|
if [[ $showevents == "false" ]]; then
|
||||||
|
echo " Events information should not be described in:"
|
||||||
|
else
|
||||||
|
echo " Events information not found in:"
|
||||||
|
fi
|
||||||
|
echo $result
|
||||||
|
caller
|
||||||
|
echo ${reset}
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
kube::test::if_has_string() {
|
kube::test::if_has_string() {
|
||||||
local message=$1
|
local message=$1
|
||||||
local match=$2
|
local match=$2
|
||||||
|
@ -392,9 +392,21 @@ runTests() {
|
|||||||
kube::test::get_object_jsonpath_assert 'pods/valid-pod' "{$id_field}" 'valid-pod'
|
kube::test::get_object_jsonpath_assert 'pods/valid-pod' "{$id_field}" 'valid-pod'
|
||||||
# Describe command should print detailed information
|
# Describe command should print detailed information
|
||||||
kube::test::describe_object_assert pods 'valid-pod' "Name:" "Image:" "Node:" "Labels:" "Status:" "Controllers"
|
kube::test::describe_object_assert pods 'valid-pod' "Name:" "Image:" "Node:" "Labels:" "Status:" "Controllers"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_object_events_assert pods 'valid-pod'
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_object_events_assert pods 'valid-pod' false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_object_events_assert pods 'valid-pod' true
|
||||||
# Describe command (resource only) should print detailed information
|
# Describe command (resource only) should print detailed information
|
||||||
kube::test::describe_resource_assert pods "Name:" "Image:" "Node:" "Labels:" "Status:" "Controllers"
|
kube::test::describe_resource_assert pods "Name:" "Image:" "Node:" "Labels:" "Status:" "Controllers"
|
||||||
|
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_resource_events_assert pods
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_resource_events_assert pods false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_resource_events_assert pods true
|
||||||
### Validate Export ###
|
### Validate Export ###
|
||||||
kube::test::get_object_assert 'pods/valid-pod' "{{.metadata.namespace}} {{.metadata.name}}" '<no value> valid-pod' "--export=true"
|
kube::test::get_object_assert 'pods/valid-pod' "{{.metadata.namespace}} {{.metadata.name}}" '<no value> valid-pod' "--export=true"
|
||||||
|
|
||||||
@ -1244,8 +1256,20 @@ __EOF__
|
|||||||
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" 'kubernetes:redis-master:'
|
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" 'kubernetes:redis-master:'
|
||||||
# Describe command should print detailed information
|
# Describe command should print detailed information
|
||||||
kube::test::describe_object_assert services 'redis-master' "Name:" "Labels:" "Selector:" "IP:" "Port:" "Endpoints:" "Session Affinity:"
|
kube::test::describe_object_assert services 'redis-master' "Name:" "Labels:" "Selector:" "IP:" "Port:" "Endpoints:" "Session Affinity:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_object_events_assert services 'redis-master'
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_object_events_assert services 'redis-master' false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_object_events_assert services 'redis-master' true
|
||||||
# Describe command (resource only) should print detailed information
|
# Describe command (resource only) should print detailed information
|
||||||
kube::test::describe_resource_assert services "Name:" "Labels:" "Selector:" "IP:" "Port:" "Endpoints:" "Session Affinity:"
|
kube::test::describe_resource_assert services "Name:" "Labels:" "Selector:" "IP:" "Port:" "Endpoints:" "Session Affinity:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_resource_events_assert services
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_resource_events_assert services false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_resource_events_assert services true
|
||||||
|
|
||||||
### Dump current redis-master service
|
### Dump current redis-master service
|
||||||
output_service=$(kubectl get service redis-master -o json --output-version=v1 "${kube_flags[@]}")
|
output_service=$(kubectl get service redis-master -o json --output-version=v1 "${kube_flags[@]}")
|
||||||
@ -1351,8 +1375,20 @@ __EOF__
|
|||||||
kube::test::get_object_assert rc "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
|
kube::test::get_object_assert rc "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
|
||||||
# Describe command should print detailed information
|
# Describe command should print detailed information
|
||||||
kube::test::describe_object_assert rc 'frontend' "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
kube::test::describe_object_assert rc 'frontend' "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_object_events_assert rc 'frontend'
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_object_events_assert rc 'frontend' false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_object_events_assert rc 'frontend' true
|
||||||
# Describe command (resource only) should print detailed information
|
# Describe command (resource only) should print detailed information
|
||||||
kube::test::describe_resource_assert rc "Name:" "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
kube::test::describe_resource_assert rc "Name:" "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_resource_events_assert rc
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_resource_events_assert rc false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_resource_events_assert rc true
|
||||||
|
|
||||||
### Scale replication controller frontend with current-replicas and replicas
|
### Scale replication controller frontend with current-replicas and replicas
|
||||||
# Pre-condition: 3 replicas
|
# Pre-condition: 3 replicas
|
||||||
@ -1606,8 +1642,20 @@ __EOF__
|
|||||||
kube::test::get_object_assert rs "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
|
kube::test::get_object_assert rs "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
|
||||||
# Describe command should print detailed information
|
# Describe command should print detailed information
|
||||||
kube::test::describe_object_assert rs 'frontend' "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
kube::test::describe_object_assert rs 'frontend' "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_object_events_assert rs 'frontend'
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_object_events_assert rs 'frontend' false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_object_events_assert rs 'frontend' true
|
||||||
# Describe command (resource only) should print detailed information
|
# Describe command (resource only) should print detailed information
|
||||||
kube::test::describe_resource_assert rs "Name:" "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
kube::test::describe_resource_assert rs "Name:" "Name:" "Image(s):" "Labels:" "Selector:" "Replicas:" "Pods Status:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_resource_events_assert rs
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_resource_events_assert rs false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_resource_events_assert rs true
|
||||||
|
|
||||||
### Scale replica set frontend with current-replicas and replicas
|
### Scale replica set frontend with current-replicas and replicas
|
||||||
# Pre-condition: 3 replicas
|
# Pre-condition: 3 replicas
|
||||||
@ -1901,8 +1949,20 @@ __EOF__
|
|||||||
kube::test::get_object_assert nodes "{{range.items}}{{$id_field}}:{{end}}" '127.0.0.1:'
|
kube::test::get_object_assert nodes "{{range.items}}{{$id_field}}:{{end}}" '127.0.0.1:'
|
||||||
|
|
||||||
kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_object_events_assert nodes "127.0.0.1"
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_object_events_assert nodes "127.0.0.1" false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_object_events_assert nodes "127.0.0.1" true
|
||||||
# Describe command (resource only) should print detailed information
|
# Describe command (resource only) should print detailed information
|
||||||
kube::test::describe_resource_assert nodes "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
kube::test::describe_resource_assert nodes "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
||||||
|
# Describe command should print events information by default
|
||||||
|
kube::test::describe_resource_events_assert nodes
|
||||||
|
# Describe command should not print events information when show-events=false
|
||||||
|
kube::test::describe_resource_events_assert nodes false
|
||||||
|
# Describe command should print events information when show-events=true
|
||||||
|
kube::test::describe_resource_events_assert nodes true
|
||||||
|
|
||||||
### kubectl patch update can mark node unschedulable
|
### kubectl patch update can mark node unschedulable
|
||||||
# Pre-condition: node is schedulable
|
# Pre-condition: node is schedulable
|
||||||
|
@ -378,6 +378,7 @@ service-overrides
|
|||||||
service-sync-period
|
service-sync-period
|
||||||
session-affinity
|
session-affinity
|
||||||
show-all
|
show-all
|
||||||
|
show-events
|
||||||
show-labels
|
show-labels
|
||||||
shutdown-fd
|
shutdown-fd
|
||||||
shutdown-fifo
|
shutdown-fifo
|
||||||
|
@ -151,12 +151,14 @@ func (t *testPrinter) HandledResources() []string {
|
|||||||
|
|
||||||
type testDescriber struct {
|
type testDescriber struct {
|
||||||
Name, Namespace string
|
Name, Namespace string
|
||||||
|
Settings kubectl.DescriberSettings
|
||||||
Output string
|
Output string
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testDescriber) Describe(namespace, name string) (output string, err error) {
|
func (t *testDescriber) Describe(namespace, name string, describerSettings kubectl.DescriberSettings) (output string, err error) {
|
||||||
t.Namespace, t.Name = namespace, name
|
t.Namespace, t.Name = namespace, name
|
||||||
|
t.Settings = describerSettings
|
||||||
return t.Output, t.Err
|
return t.Output, t.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ kubectl describe pods frontend`
|
|||||||
|
|
||||||
func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
options := &DescribeOptions{}
|
options := &DescribeOptions{}
|
||||||
|
describerSettings := &kubectl.DescriberSettings{}
|
||||||
|
|
||||||
validArgs := kubectl.DescribableResources()
|
validArgs := kubectl.DescribableResources()
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
@ -83,7 +84,7 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
Long: describe_long,
|
Long: describe_long,
|
||||||
Example: describe_example,
|
Example: describe_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunDescribe(f, out, cmd, args, options)
|
err := RunDescribe(f, out, cmd, args, options, describerSettings)
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
},
|
},
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
@ -93,11 +94,12 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
||||||
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
|
||||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
||||||
|
cmd.Flags().BoolVar(&describerSettings.ShowEvents, "show-events", true, "If true, display events related to the described object.")
|
||||||
cmdutil.AddInclude3rdPartyFlags(cmd)
|
cmdutil.AddInclude3rdPartyFlags(cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *DescribeOptions) error {
|
func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *DescribeOptions, describerSettings *kubectl.DescriberSettings) error {
|
||||||
selector := cmdutil.GetFlagString(cmd, "selector")
|
selector := cmdutil.GetFlagString(cmd, "selector")
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,7 +128,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
|||||||
infos, err := r.Infos()
|
infos, err := r.Infos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if apierrors.IsNotFound(err) && len(args) == 2 {
|
if apierrors.IsNotFound(err) && len(args) == 2 {
|
||||||
return DescribeMatchingResources(mapper, typer, f, cmdNamespace, args[0], args[1], out, err)
|
return DescribeMatchingResources(mapper, typer, f, cmdNamespace, args[0], args[1], describerSettings, out, err)
|
||||||
}
|
}
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
@ -138,7 +140,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
|||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s, err := describer.Describe(info.Namespace, info.Name)
|
s, err := describer.Describe(info.Namespace, info.Name, *describerSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
continue
|
continue
|
||||||
@ -149,7 +151,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
|
|||||||
return utilerrors.NewAggregate(allErrs)
|
return utilerrors.NewAggregate(allErrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper, f *cmdutil.Factory, namespace, rsrc, prefix string, out io.Writer, originalError error) error {
|
func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper, f *cmdutil.Factory, namespace, rsrc, prefix string, describerSettings *kubectl.DescriberSettings, out io.Writer, originalError error) error {
|
||||||
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
|
||||||
NamespaceParam(namespace).DefaultNamespace().
|
NamespaceParam(namespace).DefaultNamespace().
|
||||||
ResourceTypeOrNameArgs(true, rsrc).
|
ResourceTypeOrNameArgs(true, rsrc).
|
||||||
@ -173,7 +175,7 @@ func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper
|
|||||||
info := infos[ix]
|
info := infos[ix]
|
||||||
if strings.HasPrefix(info.Name, prefix) {
|
if strings.HasPrefix(info.Name, prefix) {
|
||||||
isFound = true
|
isFound = true
|
||||||
s, err := describer.Describe(info.Namespace, info.Name)
|
s, err := describer.Describe(info.Namespace, info.Name, *describerSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -100,3 +100,43 @@ func TestDescribeListObjects(t *testing.T) {
|
|||||||
t.Errorf("unexpected output: %s", buf.String())
|
t.Errorf("unexpected output: %s", buf.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDescribeObjectShowEvents(t *testing.T) {
|
||||||
|
pods, _, _ := testData()
|
||||||
|
f, tf, codec := NewAPIFactory()
|
||||||
|
d := &testDescriber{Output: "test output"}
|
||||||
|
tf.Describer = d
|
||||||
|
tf.Client = &fake.RESTClient{
|
||||||
|
Codec: codec,
|
||||||
|
Resp: &http.Response{StatusCode: 200, Body: objBody(codec, pods)},
|
||||||
|
}
|
||||||
|
|
||||||
|
tf.Namespace = "test"
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
cmd := NewCmdDescribe(f, buf)
|
||||||
|
cmd.Flags().Set("show-events", "true")
|
||||||
|
cmd.Run(cmd, []string{"pods"})
|
||||||
|
if d.Settings.ShowEvents != true {
|
||||||
|
t.Errorf("ShowEvents = true expected, got ShowEvents = %v", d.Settings.ShowEvents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDescribeObjectSkipEvents(t *testing.T) {
|
||||||
|
pods, _, _ := testData()
|
||||||
|
f, tf, codec := NewAPIFactory()
|
||||||
|
d := &testDescriber{Output: "test output"}
|
||||||
|
tf.Describer = d
|
||||||
|
tf.Client = &fake.RESTClient{
|
||||||
|
Codec: codec,
|
||||||
|
Resp: &http.Response{StatusCode: 200, Body: objBody(codec, pods)},
|
||||||
|
}
|
||||||
|
|
||||||
|
tf.Namespace = "test"
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
cmd := NewCmdDescribe(f, buf)
|
||||||
|
cmd.Flags().Set("show-events", "false")
|
||||||
|
cmd.Run(cmd, []string{"pods"})
|
||||||
|
if d.Settings.ShowEvents != false {
|
||||||
|
t.Errorf("ShowEvents = false expected, got ShowEvents = %v", d.Settings.ShowEvents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -54,7 +54,13 @@ import (
|
|||||||
// if the output could not be generated. Implementers typically
|
// if the output could not be generated. Implementers typically
|
||||||
// abstract the retrieval of the named object from a remote server.
|
// abstract the retrieval of the named object from a remote server.
|
||||||
type Describer interface {
|
type Describer interface {
|
||||||
Describe(namespace, name string) (output string, err error)
|
Describe(namespace, name string, describerSettings DescriberSettings) (output string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescriberSettings holds display configuration for each object
|
||||||
|
// describer to control what is printed.
|
||||||
|
type DescriberSettings struct {
|
||||||
|
ShowEvents bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectDescriber is an interface for displaying arbitrary objects with extra
|
// ObjectDescriber is an interface for displaying arbitrary objects with extra
|
||||||
@ -151,7 +157,7 @@ type NamespaceDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *NamespaceDescriber) Describe(namespace, name string) (string, error) {
|
func (d *NamespaceDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
ns, err := d.Namespaces().Get(name)
|
ns, err := d.Namespaces().Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -307,7 +313,7 @@ type LimitRangeDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LimitRangeDescriber) Describe(namespace, name string) (string, error) {
|
func (d *LimitRangeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
lr := d.LimitRanges(namespace)
|
lr := d.LimitRanges(namespace)
|
||||||
|
|
||||||
limitRange, err := lr.Get(name)
|
limitRange, err := lr.Get(name)
|
||||||
@ -394,7 +400,7 @@ type ResourceQuotaDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ResourceQuotaDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ResourceQuotaDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
rq := d.ResourceQuotas(namespace)
|
rq := d.ResourceQuotas(namespace)
|
||||||
|
|
||||||
resourceQuota, err := rq.Get(name)
|
resourceQuota, err := rq.Get(name)
|
||||||
@ -463,29 +469,33 @@ type PodDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PodDescriber) Describe(namespace, name string) (string, error) {
|
func (d *PodDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
pod, err := d.Pods(namespace).Get(name)
|
pod, err := d.Pods(namespace).Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
eventsInterface := d.Events(namespace)
|
if describerSettings.ShowEvents {
|
||||||
selector := eventsInterface.GetFieldSelector(&name, &namespace, nil, nil)
|
eventsInterface := d.Events(namespace)
|
||||||
options := api.ListOptions{FieldSelector: selector}
|
selector := eventsInterface.GetFieldSelector(&name, &namespace, nil, nil)
|
||||||
events, err2 := eventsInterface.List(options)
|
options := api.ListOptions{FieldSelector: selector}
|
||||||
if err2 == nil && len(events.Items) > 0 {
|
events, err2 := eventsInterface.List(options)
|
||||||
return tabbedString(func(out io.Writer) error {
|
if describerSettings.ShowEvents && err2 == nil && len(events.Items) > 0 {
|
||||||
fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err)
|
return tabbedString(func(out io.Writer) error {
|
||||||
DescribeEvents(events, out)
|
fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err)
|
||||||
return nil
|
DescribeEvents(events, out)
|
||||||
})
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var events *api.EventList
|
var events *api.EventList
|
||||||
if ref, err := api.GetReference(pod); err != nil {
|
if describerSettings.ShowEvents {
|
||||||
glog.Errorf("Unable to construct reference to '%#v': %v", pod, err)
|
if ref, err := api.GetReference(pod); err != nil {
|
||||||
} else {
|
glog.Errorf("Unable to construct reference to '%#v': %v", pod, err)
|
||||||
ref.Kind = ""
|
} else {
|
||||||
events, _ = d.Events(namespace).Search(ref)
|
ref.Kind = ""
|
||||||
|
events, _ = d.Events(namespace).Search(ref)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return describePod(pod, events)
|
return describePod(pod, events)
|
||||||
@ -692,7 +702,7 @@ type PersistentVolumeDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PersistentVolumeDescriber) Describe(namespace, name string) (string, error) {
|
func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.PersistentVolumes()
|
c := d.PersistentVolumes()
|
||||||
|
|
||||||
pv, err := c.Get(name)
|
pv, err := c.Get(name)
|
||||||
@ -742,7 +752,7 @@ type PersistentVolumeClaimDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string) (string, error) {
|
func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.PersistentVolumeClaims(namespace)
|
c := d.PersistentVolumeClaims(namespace)
|
||||||
|
|
||||||
pvc, err := c.Get(name)
|
pvc, err := c.Get(name)
|
||||||
@ -970,7 +980,7 @@ type ReplicationControllerDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ReplicationControllerDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ReplicationControllerDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
rc := d.ReplicationControllers(namespace)
|
rc := d.ReplicationControllers(namespace)
|
||||||
pc := d.Pods(namespace)
|
pc := d.Pods(namespace)
|
||||||
|
|
||||||
@ -984,7 +994,10 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.Events(namespace).Search(controller)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.Events(namespace).Search(controller)
|
||||||
|
}
|
||||||
|
|
||||||
return describeReplicationController(controller, events, running, waiting, succeeded, failed)
|
return describeReplicationController(controller, events, running, waiting, succeeded, failed)
|
||||||
}
|
}
|
||||||
@ -1033,7 +1046,7 @@ type ReplicaSetDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ReplicaSetDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
rsc := d.Extensions().ReplicaSets(namespace)
|
rsc := d.Extensions().ReplicaSets(namespace)
|
||||||
pc := d.Pods(namespace)
|
pc := d.Pods(namespace)
|
||||||
|
|
||||||
@ -1052,7 +1065,10 @@ func (d *ReplicaSetDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.Events(namespace).Search(rs)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.Events(namespace).Search(rs)
|
||||||
|
}
|
||||||
|
|
||||||
return describeReplicaSet(rs, events, running, waiting, succeeded, failed)
|
return describeReplicaSet(rs, events, running, waiting, succeeded, failed)
|
||||||
}
|
}
|
||||||
@ -1079,13 +1095,16 @@ type JobDescriber struct {
|
|||||||
client *client.Client
|
client *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *JobDescriber) Describe(namespace, name string) (string, error) {
|
func (d *JobDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
job, err := d.client.Extensions().Jobs(namespace).Get(name)
|
job, err := d.client.Extensions().Jobs(namespace).Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.client.Events(namespace).Search(job)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.client.Events(namespace).Search(job)
|
||||||
|
}
|
||||||
|
|
||||||
return describeJob(job, events)
|
return describeJob(job, events)
|
||||||
}
|
}
|
||||||
@ -1124,7 +1143,7 @@ type DaemonSetDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DaemonSetDescriber) Describe(namespace, name string) (string, error) {
|
func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
dc := d.Extensions().DaemonSets(namespace)
|
dc := d.Extensions().DaemonSets(namespace)
|
||||||
pc := d.Pods(namespace)
|
pc := d.Pods(namespace)
|
||||||
|
|
||||||
@ -1142,7 +1161,10 @@ func (d *DaemonSetDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.Events(namespace).Search(daemon)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.Events(namespace).Search(daemon)
|
||||||
|
}
|
||||||
|
|
||||||
return describeDaemonSet(daemon, events, running, waiting, succeeded, failed)
|
return describeDaemonSet(daemon, events, running, waiting, succeeded, failed)
|
||||||
}
|
}
|
||||||
@ -1175,7 +1197,7 @@ type SecretDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SecretDescriber) Describe(namespace, name string) (string, error) {
|
func (d *SecretDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.Secrets(namespace)
|
c := d.Secrets(namespace)
|
||||||
|
|
||||||
secret, err := c.Get(name)
|
secret, err := c.Get(name)
|
||||||
@ -1213,13 +1235,13 @@ type IngressDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IngressDescriber) Describe(namespace, name string) (string, error) {
|
func (i *IngressDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := i.Extensions().Ingress(namespace)
|
c := i.Extensions().Ingress(namespace)
|
||||||
ing, err := c.Get(name)
|
ing, err := c.Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return i.describeIngress(ing)
|
return i.describeIngress(ing, describerSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IngressDescriber) describeBackend(ns string, backend *extensions.IngressBackend) string {
|
func (i *IngressDescriber) describeBackend(ns string, backend *extensions.IngressBackend) string {
|
||||||
@ -1242,7 +1264,7 @@ func (i *IngressDescriber) describeBackend(ns string, backend *extensions.Ingres
|
|||||||
return formatEndpoints(endpoints, sets.NewString(spName))
|
return formatEndpoints(endpoints, sets.NewString(spName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IngressDescriber) describeIngress(ing *extensions.Ingress) (string, error) {
|
func (i *IngressDescriber) describeIngress(ing *extensions.Ingress, describerSettings DescriberSettings) (string, error) {
|
||||||
return tabbedString(func(out io.Writer) error {
|
return tabbedString(func(out io.Writer) error {
|
||||||
fmt.Fprintf(out, "Name:\t%v\n", ing.Name)
|
fmt.Fprintf(out, "Name:\t%v\n", ing.Name)
|
||||||
fmt.Fprintf(out, "Namespace:\t%v\n", ing.Namespace)
|
fmt.Fprintf(out, "Namespace:\t%v\n", ing.Namespace)
|
||||||
@ -1275,9 +1297,11 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress) (string, err
|
|||||||
}
|
}
|
||||||
describeIngressAnnotations(out, ing.Annotations)
|
describeIngressAnnotations(out, ing.Annotations)
|
||||||
|
|
||||||
events, _ := i.Events(ing.Namespace).Search(ing)
|
if describerSettings.ShowEvents {
|
||||||
if events != nil {
|
events, _ := i.Events(ing.Namespace).Search(ing)
|
||||||
DescribeEvents(events, out)
|
if events != nil {
|
||||||
|
DescribeEvents(events, out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -1314,7 +1338,7 @@ type ServiceDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ServiceDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ServiceDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.Services(namespace)
|
c := d.Services(namespace)
|
||||||
|
|
||||||
service, err := c.Get(name)
|
service, err := c.Get(name)
|
||||||
@ -1323,8 +1347,10 @@ func (d *ServiceDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
endpoints, _ := d.Endpoints(namespace).Get(name)
|
endpoints, _ := d.Endpoints(namespace).Get(name)
|
||||||
events, _ := d.Events(namespace).Search(service)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.Events(namespace).Search(service)
|
||||||
|
}
|
||||||
return describeService(service, endpoints, events)
|
return describeService(service, endpoints, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,7 +1411,7 @@ type EndpointsDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *EndpointsDescriber) Describe(namespace, name string) (string, error) {
|
func (d *EndpointsDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.Endpoints(namespace)
|
c := d.Endpoints(namespace)
|
||||||
|
|
||||||
ep, err := c.Get(name)
|
ep, err := c.Get(name)
|
||||||
@ -1393,7 +1419,10 @@ func (d *EndpointsDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.Events(namespace).Search(ep)
|
var events *api.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.Events(namespace).Search(ep)
|
||||||
|
}
|
||||||
|
|
||||||
return describeEndpoints(ep, events)
|
return describeEndpoints(ep, events)
|
||||||
}
|
}
|
||||||
@ -1455,7 +1484,7 @@ type ServiceAccountDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ServiceAccountDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ServiceAccountDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.ServiceAccounts(namespace)
|
c := d.ServiceAccounts(namespace)
|
||||||
|
|
||||||
serviceAccount, err := c.Get(name)
|
serviceAccount, err := c.Get(name)
|
||||||
@ -1536,7 +1565,7 @@ type NodeDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *NodeDescriber) Describe(namespace, name string) (string, error) {
|
func (d *NodeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
mc := d.Nodes()
|
mc := d.Nodes()
|
||||||
node, err := mc.Get(name)
|
node, err := mc.Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1559,12 +1588,14 @@ func (d *NodeDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var events *api.EventList
|
var events *api.EventList
|
||||||
if ref, err := api.GetReference(node); err != nil {
|
if describerSettings.ShowEvents {
|
||||||
glog.Errorf("Unable to construct reference to '%#v': %v", node, err)
|
if ref, err := api.GetReference(node); err != nil {
|
||||||
} else {
|
glog.Errorf("Unable to construct reference to '%#v': %v", node, err)
|
||||||
// TODO: We haven't decided the namespace for Node object yet.
|
} else {
|
||||||
ref.UID = types.UID(ref.Name)
|
// TODO: We haven't decided the namespace for Node object yet.
|
||||||
events, _ = d.Events("").Search(ref)
|
ref.UID = types.UID(ref.Name)
|
||||||
|
events, _ = d.Events("").Search(ref)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return describeNode(node, nodeNonTerminatedPodsList, events, canViewPods)
|
return describeNode(node, nodeNonTerminatedPodsList, events, canViewPods)
|
||||||
@ -1635,7 +1666,7 @@ type PetSetDescriber struct {
|
|||||||
client *client.Client
|
client *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PetSetDescriber) Describe(namespace, name string) (string, error) {
|
func (p *PetSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
ps, err := p.client.Apps().PetSets(namespace).Get(name)
|
ps, err := p.client.Apps().PetSets(namespace).Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -1663,9 +1694,11 @@ func (p *PetSetDescriber) Describe(namespace, name string) (string, error) {
|
|||||||
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", ps.CreationTimestamp.Time.Format(time.RFC1123Z))
|
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", ps.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||||
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
|
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
|
||||||
describeVolumes(ps.Spec.Template.Spec.Volumes, out, "")
|
describeVolumes(ps.Spec.Template.Spec.Volumes, out, "")
|
||||||
events, _ := p.client.Events(namespace).Search(ps)
|
if describerSettings.ShowEvents {
|
||||||
if events != nil {
|
events, _ := p.client.Events(namespace).Search(ps)
|
||||||
DescribeEvents(events, out)
|
if events != nil {
|
||||||
|
DescribeEvents(events, out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -1676,7 +1709,7 @@ type HorizontalPodAutoscalerDescriber struct {
|
|||||||
client *client.Client
|
client *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (string, error) {
|
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
hpa, err := d.client.Extensions().HorizontalPodAutoscalers(namespace).Get(name)
|
hpa, err := d.client.Extensions().HorizontalPodAutoscalers(namespace).Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -1718,9 +1751,11 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
events, _ := d.client.Events(namespace).Search(hpa)
|
if describerSettings.ShowEvents {
|
||||||
if events != nil {
|
events, _ := d.client.Events(namespace).Search(hpa)
|
||||||
DescribeEvents(events, out)
|
if events != nil {
|
||||||
|
DescribeEvents(events, out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -1827,7 +1862,7 @@ type DeploymentDescriber struct {
|
|||||||
clientset.Interface
|
clientset.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error) {
|
func (dd *DeploymentDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
d, err := dd.Extensions().Deployments(namespace).Get(name)
|
d, err := dd.Extensions().Deployments(namespace).Get(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -1861,9 +1896,11 @@ func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error)
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(out, "NewReplicaSet:\t%s\n", printReplicaSetsByLabels(newRSs))
|
fmt.Fprintf(out, "NewReplicaSet:\t%s\n", printReplicaSetsByLabels(newRSs))
|
||||||
}
|
}
|
||||||
events, err := dd.Core().Events(namespace).Search(d)
|
if describerSettings.ShowEvents {
|
||||||
if err == nil && events != nil {
|
events, err := dd.Core().Events(namespace).Search(d)
|
||||||
DescribeEvents(events, out)
|
if err == nil && events != nil {
|
||||||
|
DescribeEvents(events, out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -1951,7 +1988,7 @@ type ConfigMapDescriber struct {
|
|||||||
client.Interface
|
client.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ConfigMapDescriber) Describe(namespace, name string) (string, error) {
|
func (d *ConfigMapDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||||
c := d.ConfigMaps(namespace)
|
c := d.ConfigMaps(namespace)
|
||||||
|
|
||||||
configMap, err := c.Get(name)
|
configMap, err := c.Get(name)
|
||||||
|
@ -49,7 +49,7 @@ func TestDescribePod(t *testing.T) {
|
|||||||
})
|
})
|
||||||
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
||||||
d := PodDescriber{c}
|
d := PodDescriber{c}
|
||||||
out, err := d.Describe("foo", "bar")
|
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ func TestDescribeService(t *testing.T) {
|
|||||||
})
|
})
|
||||||
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
||||||
d := ServiceDescriber{c}
|
d := ServiceDescriber{c}
|
||||||
out, err := d.Describe("foo", "bar")
|
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ func TestPodDescribeResultsSorted(t *testing.T) {
|
|||||||
d := PodDescriber{c}
|
d := PodDescriber{c}
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
out, err := d.Describe("foo", "bar")
|
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -492,7 +492,7 @@ func TestPersistentVolumeDescriber(t *testing.T) {
|
|||||||
for name, pv := range tests {
|
for name, pv := range tests {
|
||||||
fake := testclient.NewSimpleFake(pv)
|
fake := testclient.NewSimpleFake(pv)
|
||||||
c := PersistentVolumeDescriber{fake}
|
c := PersistentVolumeDescriber{fake}
|
||||||
str, err := c.Describe("foo", "bar")
|
str, err := c.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error for test %s: %v", name, err)
|
t.Errorf("Unexpected error for test %s: %v", name, err)
|
||||||
}
|
}
|
||||||
@ -513,7 +513,7 @@ func TestDescribeDeployment(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
d := DeploymentDescriber{fake}
|
d := DeploymentDescriber{fake}
|
||||||
out, err := d.Describe("foo", "bar")
|
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -521,3 +521,116 @@ func TestDescribeDeployment(t *testing.T) {
|
|||||||
t.Errorf("unexpected out: %s", out)
|
t.Errorf("unexpected out: %s", out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDescribeEvents(t *testing.T) {
|
||||||
|
|
||||||
|
events := &api.EventList{
|
||||||
|
Items: []api.Event{
|
||||||
|
{
|
||||||
|
Source: api.EventSource{Component: "kubelet"},
|
||||||
|
Message: "Item 1",
|
||||||
|
FirstTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)),
|
||||||
|
LastTimestamp: unversioned.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)),
|
||||||
|
Count: 1,
|
||||||
|
Type: api.EventTypeNormal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := map[string]Describer{
|
||||||
|
"DaemonSetDescriber": &DaemonSetDescriber{
|
||||||
|
testclient.NewSimpleFake(&extensions.DaemonSet{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"DeploymentDescriber": &DeploymentDescriber{
|
||||||
|
fake.NewSimpleClientset(&extensions.Deployment{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"EndpointsDescriber": &EndpointsDescriber{
|
||||||
|
testclient.NewSimpleFake(&api.Endpoints{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
// TODO(jchaloup): add tests for:
|
||||||
|
// - HorizontalPodAutoscalerDescriber
|
||||||
|
// - IngressDescriber
|
||||||
|
// - JobDescriber
|
||||||
|
"NodeDescriber": &NodeDescriber{
|
||||||
|
testclient.NewSimpleFake(&api.Node{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
SelfLink: "url/url/url",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"PodDescriber": &PodDescriber{
|
||||||
|
testclient.NewSimpleFake(&api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
SelfLink: "url/url/url",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"ReplicaSetDescriber": &ReplicaSetDescriber{
|
||||||
|
testclient.NewSimpleFake(&extensions.ReplicaSet{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"ReplicationControllerDescriber": &ReplicationControllerDescriber{
|
||||||
|
testclient.NewSimpleFake(&api.ReplicationController{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
"Service": &ServiceDescriber{
|
||||||
|
testclient.NewSimpleFake(&api.Service{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, d := range m {
|
||||||
|
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error for %q: %v", name, err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(out, "bar") {
|
||||||
|
t.Errorf("unexpected out for %q: %s", name, out)
|
||||||
|
}
|
||||||
|
if !strings.Contains(out, "Events:") {
|
||||||
|
t.Errorf("events not found for %q when ShowEvents=true: %s", name, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = d.Describe("foo", "bar", DescriberSettings{ShowEvents: false})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error for %q: %s", name, err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(out, "bar") {
|
||||||
|
t.Errorf("unexpected out for %q: %s", name, out)
|
||||||
|
}
|
||||||
|
if strings.Contains(out, "Events:") {
|
||||||
|
t.Errorf("events found for %q when ShowEvents=false: %s", name, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user