Skip to content

Commit

Permalink
Introduce kubectl describe --show-events
Browse files Browse the repository at this point in the history
Introduce DescriberSettings for Describer display options
Introduce --show-events flag and DescriberSettings in Describer methods
Introduce unit-tests
Regenerated kubectl describe docs
Add events flag tests to test-cmd.sh

Signed-off-by: dhodovsk@redhat.com
Signed-off-by: jchaloup@redhat.com
  • Loading branch information
ingvagabund committed May 6, 2016
1 parent 60324ff commit dd2c9c5
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 76 deletions.
1 change: 1 addition & 0 deletions contrib/completions/bash/kubectl
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ _kubectl_describe()
flags+=("-R")
flags+=("--selector=")
two_word_flags+=("-l")
flags+=("--show-events")
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--as=")
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/kubectl-describe.1
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ componentstatuses (cs), endpoints (ep), and secrets.
\fB\-l\fP, \fB\-\-selector\fP=""
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
.PP
Expand Down
3 changes: 2 additions & 1 deletion docs/user-guide/kubectl/kubectl_describe.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
-R, --recursive[=false]: If true, process directory recursively.
-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
Expand Down Expand Up @@ -123,7 +124,7 @@ kubectl describe pods frontend

* [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 -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_describe.md?pixel)]()
Expand Down
3 changes: 3 additions & 0 deletions docs/yaml/kubectl/kubectl_describe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ options:
- name: selector
shorthand: l
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:
- name: alsologtostderr
default_value: "false"
Expand Down
70 changes: 70 additions & 0 deletions hack/lib/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,44 @@ kube::test::describe_object_assert() {
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() {
local resource=$1
local matches=${@:2}
Expand Down Expand Up @@ -136,6 +174,38 @@ kube::test::describe_resource_assert() {
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() {
local message=$1
local match=$2
Expand Down
60 changes: 60 additions & 0 deletions hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,21 @@ runTests() {
kube::test::get_object_jsonpath_assert 'pods/valid-pod' "{$id_field}" 'valid-pod'
# Describe command should print detailed information
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
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 ###
kube::test::get_object_assert 'pods/valid-pod' "{{.metadata.namespace}} {{.metadata.name}}" '<no value> valid-pod' "--export=true"

Expand Down Expand Up @@ -1220,8 +1232,20 @@ __EOF__
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" 'kubernetes:redis-master:'
# Describe command should print detailed information
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
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
output_service=$(kubectl get service redis-master -o json --output-version=v1 "${kube_flags[@]}")
Expand Down Expand Up @@ -1327,8 +1351,20 @@ __EOF__
kube::test::get_object_assert rc "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
# Describe command should print detailed information
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
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
# Pre-condition: 3 replicas
Expand Down Expand Up @@ -1582,8 +1618,20 @@ __EOF__
kube::test::get_object_assert rs "{{range.items}}{{$id_field}}:{{end}}" 'frontend:'
# Describe command should print detailed information
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
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
# Pre-condition: 3 replicas
Expand Down Expand Up @@ -1877,8 +1925,20 @@ __EOF__
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:"
# 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
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
# Pre-condition: node is schedulable
Expand Down
1 change: 1 addition & 0 deletions hack/verify-flags/known-flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ service-overrides
service-sync-period
session-affinity
show-all
show-events
show-labels
shutdown-fd
shutdown-fifo
Expand Down
4 changes: 3 additions & 1 deletion pkg/kubectl/cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,14 @@ func (t *testPrinter) HandledResources() []string {

type testDescriber struct {
Name, Namespace string
Settings kubectl.DescriberSettings
Output string
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.Settings = describerSettings
return t.Output, t.Err
}

Expand Down
14 changes: 8 additions & 6 deletions pkg/kubectl/cmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ kubectl describe pods frontend`

func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
options := &DescribeOptions{}
describerSettings := &kubectl.DescriberSettings{}

validArgs := kubectl.DescribableResources()
argAliases := kubectl.ResourceAliases(validArgs)
Expand All @@ -83,7 +84,7 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: describe_long,
Example: describe_example,
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)
},
ValidArgs: validArgs,
Expand All @@ -93,11 +94,12 @@ func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
cmdutil.AddRecursiveFlag(cmd, &options.Recursive)
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)
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")
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
Expand Down Expand Up @@ -126,7 +128,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
infos, err := r.Infos()
if err != nil {
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)
}
Expand All @@ -138,7 +140,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
allErrs = append(allErrs, err)
continue
}
s, err := describer.Describe(info.Namespace, info.Name)
s, err := describer.Describe(info.Namespace, info.Name, *describerSettings)
if err != nil {
allErrs = append(allErrs, err)
continue
Expand All @@ -149,7 +151,7 @@ func RunDescribe(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
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)).
NamespaceParam(namespace).DefaultNamespace().
ResourceTypeOrNameArgs(true, rsrc).
Expand All @@ -173,7 +175,7 @@ func DescribeMatchingResources(mapper meta.RESTMapper, typer runtime.ObjectTyper
info := infos[ix]
if strings.HasPrefix(info.Name, prefix) {
isFound = true
s, err := describer.Describe(info.Namespace, info.Name)
s, err := describer.Describe(info.Namespace, info.Name, *describerSettings)
if err != nil {
return err
}
Expand Down
40 changes: 40 additions & 0 deletions pkg/kubectl/cmd/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,43 @@ func TestDescribeListObjects(t *testing.T) {
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)
}
}
Loading

0 comments on commit dd2c9c5

Please sign in to comment.