mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 13:50:01 +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:
		| @@ -497,6 +497,7 @@ _kubectl_describe() | ||||
|     flags+=("-R") | ||||
|     flags+=("--selector=") | ||||
|     two_word_flags+=("-l") | ||||
|     flags+=("--show-events") | ||||
|     flags+=("--alsologtostderr") | ||||
|     flags+=("--api-version=") | ||||
|     flags+=("--as=") | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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 --> | ||||
| []() | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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} | ||||
| @@ -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 | ||||
|   | ||||
| @@ -392,9 +392,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" | ||||
|  | ||||
| @@ -1244,8 +1256,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[@]}") | ||||
| @@ -1351,8 +1375,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 | ||||
| @@ -1606,8 +1642,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 | ||||
| @@ -1901,8 +1949,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 | ||||
|   | ||||
| @@ -378,6 +378,7 @@ service-overrides | ||||
| service-sync-period | ||||
| session-affinity | ||||
| show-all | ||||
| show-events | ||||
| show-labels | ||||
| shutdown-fd | ||||
| shutdown-fifo | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| @@ -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, | ||||
| @@ -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 { | ||||
| @@ -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) | ||||
| 	} | ||||
| @@ -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 | ||||
| @@ -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). | ||||
| @@ -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 | ||||
| 			} | ||||
|   | ||||
| @@ -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) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -54,7 +54,13 @@ import ( | ||||
| // if the output could not be generated. Implementers typically | ||||
| // abstract the retrieval of the named object from a remote server. | ||||
| 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 | ||||
| @@ -151,7 +157,7 @@ type NamespaceDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| @@ -307,7 +313,7 @@ type LimitRangeDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	limitRange, err := lr.Get(name) | ||||
| @@ -394,7 +400,7 @@ type ResourceQuotaDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	resourceQuota, err := rq.Get(name) | ||||
| @@ -463,29 +469,33 @@ type PodDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		eventsInterface := d.Events(namespace) | ||||
| 		selector := eventsInterface.GetFieldSelector(&name, &namespace, nil, nil) | ||||
| 		options := api.ListOptions{FieldSelector: selector} | ||||
| 		events, err2 := eventsInterface.List(options) | ||||
| 		if err2 == nil && len(events.Items) > 0 { | ||||
| 			return tabbedString(func(out io.Writer) error { | ||||
| 				fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err) | ||||
| 				DescribeEvents(events, out) | ||||
| 				return nil | ||||
| 			}) | ||||
| 		if describerSettings.ShowEvents { | ||||
| 			eventsInterface := d.Events(namespace) | ||||
| 			selector := eventsInterface.GetFieldSelector(&name, &namespace, nil, nil) | ||||
| 			options := api.ListOptions{FieldSelector: selector} | ||||
| 			events, err2 := eventsInterface.List(options) | ||||
| 			if describerSettings.ShowEvents && err2 == nil && len(events.Items) > 0 { | ||||
| 				return tabbedString(func(out io.Writer) error { | ||||
| 					fmt.Fprintf(out, "Pod '%v': error '%v', but found events.\n", name, err) | ||||
| 					DescribeEvents(events, out) | ||||
| 					return nil | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	var events *api.EventList | ||||
| 	if ref, err := api.GetReference(pod); err != nil { | ||||
| 		glog.Errorf("Unable to construct reference to '%#v': %v", pod, err) | ||||
| 	} else { | ||||
| 		ref.Kind = "" | ||||
| 		events, _ = d.Events(namespace).Search(ref) | ||||
| 	if describerSettings.ShowEvents { | ||||
| 		if ref, err := api.GetReference(pod); err != nil { | ||||
| 			glog.Errorf("Unable to construct reference to '%#v': %v", pod, err) | ||||
| 		} else { | ||||
| 			ref.Kind = "" | ||||
| 			events, _ = d.Events(namespace).Search(ref) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return describePod(pod, events) | ||||
| @@ -692,7 +702,7 @@ type PersistentVolumeDescriber struct { | ||||
| 	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() | ||||
|  | ||||
| 	pv, err := c.Get(name) | ||||
| @@ -742,7 +752,7 @@ type PersistentVolumeClaimDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	pvc, err := c.Get(name) | ||||
| @@ -970,7 +980,7 @@ type ReplicationControllerDescriber struct { | ||||
| 	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) | ||||
| 	pc := d.Pods(namespace) | ||||
|  | ||||
| @@ -984,7 +994,10 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin | ||||
| 		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) | ||||
| } | ||||
| @@ -1033,7 +1046,7 @@ type ReplicaSetDescriber struct { | ||||
| 	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) | ||||
| 	pc := d.Pods(namespace) | ||||
|  | ||||
| @@ -1052,7 +1065,10 @@ func (d *ReplicaSetDescriber) Describe(namespace, name string) (string, error) { | ||||
| 		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) | ||||
| } | ||||
| @@ -1079,13 +1095,16 @@ type JobDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		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) | ||||
| } | ||||
| @@ -1124,7 +1143,7 @@ type DaemonSetDescriber struct { | ||||
| 	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) | ||||
| 	pc := d.Pods(namespace) | ||||
|  | ||||
| @@ -1142,7 +1161,10 @@ func (d *DaemonSetDescriber) Describe(namespace, name string) (string, error) { | ||||
| 		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) | ||||
| } | ||||
| @@ -1175,7 +1197,7 @@ type SecretDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	secret, err := c.Get(name) | ||||
| @@ -1213,13 +1235,13 @@ type IngressDescriber struct { | ||||
| 	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) | ||||
| 	ing, err := c.Get(name) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return i.describeIngress(ing) | ||||
| 	return i.describeIngress(ing, describerSettings) | ||||
| } | ||||
|  | ||||
| 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)) | ||||
| } | ||||
|  | ||||
| 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 { | ||||
| 		fmt.Fprintf(out, "Name:\t%v\n", ing.Name) | ||||
| 		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) | ||||
|  | ||||
| 		events, _ := i.Events(ing.Namespace).Search(ing) | ||||
| 		if events != nil { | ||||
| 			DescribeEvents(events, out) | ||||
| 		if describerSettings.ShowEvents { | ||||
| 			events, _ := i.Events(ing.Namespace).Search(ing) | ||||
| 			if events != nil { | ||||
| 				DescribeEvents(events, out) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| @@ -1314,7 +1338,7 @@ type ServiceDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	service, err := c.Get(name) | ||||
| @@ -1323,8 +1347,10 @@ func (d *ServiceDescriber) Describe(namespace, name string) (string, error) { | ||||
| 	} | ||||
|  | ||||
| 	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) | ||||
| } | ||||
|  | ||||
| @@ -1385,7 +1411,7 @@ type EndpointsDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	ep, err := c.Get(name) | ||||
| @@ -1393,7 +1419,10 @@ func (d *EndpointsDescriber) Describe(namespace, name string) (string, error) { | ||||
| 		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) | ||||
| } | ||||
| @@ -1455,7 +1484,7 @@ type ServiceAccountDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	serviceAccount, err := c.Get(name) | ||||
| @@ -1536,7 +1565,7 @@ type NodeDescriber struct { | ||||
| 	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() | ||||
| 	node, err := mc.Get(name) | ||||
| 	if err != nil { | ||||
| @@ -1559,12 +1588,14 @@ func (d *NodeDescriber) Describe(namespace, name string) (string, error) { | ||||
| 	} | ||||
|  | ||||
| 	var events *api.EventList | ||||
| 	if ref, err := api.GetReference(node); err != nil { | ||||
| 		glog.Errorf("Unable to construct reference to '%#v': %v", node, err) | ||||
| 	} else { | ||||
| 		// TODO: We haven't decided the namespace for Node object yet. | ||||
| 		ref.UID = types.UID(ref.Name) | ||||
| 		events, _ = d.Events("").Search(ref) | ||||
| 	if describerSettings.ShowEvents { | ||||
| 		if ref, err := api.GetReference(node); err != nil { | ||||
| 			glog.Errorf("Unable to construct reference to '%#v': %v", node, err) | ||||
| 		} else { | ||||
| 			// TODO: We haven't decided the namespace for Node object yet. | ||||
| 			ref.UID = types.UID(ref.Name) | ||||
| 			events, _ = d.Events("").Search(ref) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return describeNode(node, nodeNonTerminatedPodsList, events, canViewPods) | ||||
| @@ -1635,7 +1666,7 @@ type PetSetDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		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, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed) | ||||
| 		describeVolumes(ps.Spec.Template.Spec.Volumes, out, "") | ||||
| 		events, _ := p.client.Events(namespace).Search(ps) | ||||
| 		if events != nil { | ||||
| 			DescribeEvents(events, out) | ||||
| 		if describerSettings.ShowEvents { | ||||
| 			events, _ := p.client.Events(namespace).Search(ps) | ||||
| 			if events != nil { | ||||
| 				DescribeEvents(events, out) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| @@ -1676,7 +1709,7 @@ type HorizontalPodAutoscalerDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| @@ -1718,9 +1751,11 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		events, _ := d.client.Events(namespace).Search(hpa) | ||||
| 		if events != nil { | ||||
| 			DescribeEvents(events, out) | ||||
| 		if describerSettings.ShowEvents { | ||||
| 			events, _ := d.client.Events(namespace).Search(hpa) | ||||
| 			if events != nil { | ||||
| 				DescribeEvents(events, out) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| @@ -1827,7 +1862,7 @@ type DeploymentDescriber struct { | ||||
| 	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) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| @@ -1861,9 +1896,11 @@ func (dd *DeploymentDescriber) Describe(namespace, name string) (string, error) | ||||
| 			} | ||||
| 			fmt.Fprintf(out, "NewReplicaSet:\t%s\n", printReplicaSetsByLabels(newRSs)) | ||||
| 		} | ||||
| 		events, err := dd.Core().Events(namespace).Search(d) | ||||
| 		if err == nil && events != nil { | ||||
| 			DescribeEvents(events, out) | ||||
| 		if describerSettings.ShowEvents { | ||||
| 			events, err := dd.Core().Events(namespace).Search(d) | ||||
| 			if err == nil && events != nil { | ||||
| 				DescribeEvents(events, out) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| @@ -1951,7 +1988,7 @@ type ConfigMapDescriber struct { | ||||
| 	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) | ||||
|  | ||||
| 	configMap, err := c.Get(name) | ||||
|   | ||||
| @@ -49,7 +49,7 @@ func TestDescribePod(t *testing.T) { | ||||
| 	}) | ||||
| 	c := &describeClient{T: t, Namespace: "foo", Interface: fake} | ||||
| 	d := PodDescriber{c} | ||||
| 	out, err := d.Describe("foo", "bar") | ||||
| 	out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("unexpected error: %v", err) | ||||
| 	} | ||||
| @@ -67,7 +67,7 @@ func TestDescribeService(t *testing.T) { | ||||
| 	}) | ||||
| 	c := &describeClient{T: t, Namespace: "foo", Interface: fake} | ||||
| 	d := ServiceDescriber{c} | ||||
| 	out, err := d.Describe("foo", "bar") | ||||
| 	out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("unexpected error: %v", err) | ||||
| 	} | ||||
| @@ -110,7 +110,7 @@ func TestPodDescribeResultsSorted(t *testing.T) { | ||||
| 	d := PodDescriber{c} | ||||
|  | ||||
| 	// Act | ||||
| 	out, err := d.Describe("foo", "bar") | ||||
| 	out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) | ||||
|  | ||||
| 	// Assert | ||||
| 	if err != nil { | ||||
| @@ -492,7 +492,7 @@ func TestPersistentVolumeDescriber(t *testing.T) { | ||||
| 	for name, pv := range tests { | ||||
| 		fake := testclient.NewSimpleFake(pv) | ||||
| 		c := PersistentVolumeDescriber{fake} | ||||
| 		str, err := c.Describe("foo", "bar") | ||||
| 		str, err := c.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) | ||||
| 		if err != nil { | ||||
| 			t.Errorf("Unexpected error for test %s: %v", name, err) | ||||
| 		} | ||||
| @@ -513,7 +513,7 @@ func TestDescribeDeployment(t *testing.T) { | ||||
| 		}, | ||||
| 	}) | ||||
| 	d := DeploymentDescriber{fake} | ||||
| 	out, err := d.Describe("foo", "bar") | ||||
| 	out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("unexpected error: %v", err) | ||||
| 	} | ||||
| @@ -521,3 +521,116 @@ func TestDescribeDeployment(t *testing.T) { | ||||
| 		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) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user