diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl index ba60f1c73a8..546399b77be 100644 --- a/contrib/completions/bash/kubectl +++ b/contrib/completions/bash/kubectl @@ -330,6 +330,7 @@ _kubectl_describe() must_have_one_flag=() must_have_one_noun=() + must_have_one_noun+=("endpoints") must_have_one_noun+=("limitrange") must_have_one_noun+=("namespace") must_have_one_noun+=("node") diff --git a/docs/man/man1/kubectl-describe.1 b/docs/man/man1/kubectl-describe.1 index 6dfa016aafc..72da6e21d77 100644 --- a/docs/man/man1/kubectl-describe.1 +++ b/docs/man/man1/kubectl-describe.1 @@ -30,7 +30,7 @@ exists, it will output details for every resource that has a name prefixed with Possible resource types include (case insensitive): pods (po), services (svc), replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), -namespaces (ns), serviceaccounts or secrets. +namespaces (ns), serviceaccounts, endpoints (ep) or secrets. .SH OPTIONS diff --git a/docs/user-guide/kubectl/kubectl_describe.md b/docs/user-guide/kubectl/kubectl_describe.md index 4ed18fc99f2..e8c89526a8b 100644 --- a/docs/user-guide/kubectl/kubectl_describe.md +++ b/docs/user-guide/kubectl/kubectl_describe.md @@ -51,7 +51,7 @@ exists, it will output details for every resource that has a name prefixed with Possible resource types include (case insensitive): pods (po), services (svc), replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), -namespaces (ns), serviceaccounts or secrets. +namespaces (ns), serviceaccounts, endpoints (ep) or secrets. ``` kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME) @@ -119,7 +119,7 @@ $ kubectl describe pods frontend * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-09-22 12:53:42.289638749 +0000 UTC +###### Auto generated by spf13/cobra on 5-Nov-2015 [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_describe.md?pixel)]() diff --git a/pkg/kubectl/cmd/describe.go b/pkg/kubectl/cmd/describe.go index eaa061014c9..c0d9afc1346 100644 --- a/pkg/kubectl/cmd/describe.go +++ b/pkg/kubectl/cmd/describe.go @@ -52,7 +52,7 @@ exists, it will output details for every resource that has a name prefixed with Possible resource types include (case insensitive): pods (po), services (svc), replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), -namespaces (ns), serviceaccounts or secrets.` +namespaces (ns), serviceaccounts, endpoints (ep) or secrets.` describe_example = `# Describe a node $ kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index 56779a31f05..453ab2da7ea 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -79,6 +79,7 @@ func describerMap(c *client.Client) map[string]Describer { "PersistentVolume": &PersistentVolumeDescriber{c}, "PersistentVolumeClaim": &PersistentVolumeClaimDescriber{c}, "Namespace": &NamespaceDescriber{c}, + "Endpoints": &EndpointsDescriber{c}, } return m } @@ -1105,6 +1106,76 @@ func describeService(service *api.Service, endpoints *api.Endpoints, events *api }) } +// EndpointsDescriber generates information about an Endpoint. +type EndpointsDescriber struct { + client.Interface +} + +func (d *EndpointsDescriber) Describe(namespace, name string) (string, error) { + c := d.Endpoints(namespace) + + ep, err := c.Get(name) + if err != nil { + return "", err + } + + events, _ := d.Events(namespace).Search(ep) + + return describeEndpoints(ep, events) +} + +func describeEndpoints(ep *api.Endpoints, events *api.EventList) (string, error) { + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", ep.Name) + fmt.Fprintf(out, "Namespace:\t%s\n", ep.Namespace) + fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(ep.Labels)) + + fmt.Fprintf(out, "Subsets:\n") + for i := range ep.Subsets { + subset := &ep.Subsets[i] + + addresses := []string{} + for _, addr := range subset.Addresses { + addresses = append(addresses, addr.IP) + } + addressesString := strings.Join(addresses, ",") + if len(addressesString) == 0 { + addressesString = "" + } + fmt.Fprintf(out, " Addresses:\t%s\n", addressesString) + + notReadyAddresses := []string{} + for _, addr := range subset.NotReadyAddresses { + notReadyAddresses = append(notReadyAddresses, addr.IP) + } + notReadyAddressesString := strings.Join(notReadyAddresses, ",") + if len(notReadyAddressesString) == 0 { + notReadyAddressesString = "" + } + fmt.Fprintf(out, " NotReadyAddresses:\t%s\n", notReadyAddressesString) + + if len(subset.Ports) > 0 { + fmt.Fprintf(out, " Ports:\n") + fmt.Fprintf(out, " Name\tPort\tProtocol\n") + fmt.Fprintf(out, " ----\t----\t--------\n") + for _, port := range subset.Ports { + name := port.Name + if len(name) == 0 { + name = "" + } + fmt.Fprintf(out, " %s\t%d\t%s\n", name, port.Port, port.Protocol) + } + } + fmt.Fprintf(out, "\n") + } + + if events != nil { + DescribeEvents(events, out) + } + return nil + }) +} + // ServiceAccountDescriber generates information about a service. type ServiceAccountDescriber struct { client.Interface