Cleanup kubectl describe code

This commit is contained in:
xiangpengzhao 2017-04-01 17:26:19 +08:00
parent dee81ed56a
commit 6ec162d816
2 changed files with 94 additions and 121 deletions

View File

@ -80,7 +80,6 @@ go_library(
"//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller/deployment/util:go_default_library",
"//pkg/fieldpath:go_default_library",

View File

@ -18,6 +18,7 @@ package internalversion
import (
"bytes"
"crypto/x509"
"encoding/json"
"fmt"
"io"
@ -64,7 +65,6 @@ import (
extensionsclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/extensions/v1beta1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
"k8s.io/kubernetes/pkg/controller"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/fieldpath"
@ -851,13 +851,15 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
return "", err
}
storage := pv.Spec.Capacity[api.ResourceStorage]
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = d.Core().Events(namespace).Search(api.Scheme, pv)
}
return describePersistentVolume(pv, events)
}
func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", pv.Name)
@ -872,6 +874,7 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
}
w.Write(LEVEL_0, "Reclaim Policy:\t%v\n", pv.Spec.PersistentVolumeReclaimPolicy)
w.Write(LEVEL_0, "Access Modes:\t%s\n", helper.GetAccessModesAsString(pv.Spec.AccessModes))
storage := pv.Spec.Capacity[api.ResourceStorage]
w.Write(LEVEL_0, "Capacity:\t%s\n", storage.String())
w.Write(LEVEL_0, "Message:\t%s\n", pv.Status.Message)
w.Write(LEVEL_0, "Source:\n")
@ -927,17 +930,12 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
return "", err
}
storage := pvc.Spec.Resources.Requests[api.ResourceStorage]
capacity := ""
accessModes := ""
if pvc.Spec.VolumeName != "" {
accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes)
storage = pvc.Status.Capacity[api.ResourceStorage]
capacity = storage.String()
}
events, _ := d.Core().Events(namespace).Search(api.Scheme, pvc)
return describePersistentVolumeClaim(pvc, events)
}
func describePersistentVolumeClaim(pvc *api.PersistentVolumeClaim, events *api.EventList) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", pvc.Name)
@ -947,6 +945,14 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
w.Write(LEVEL_0, "Volume:\t%s\n", pvc.Spec.VolumeName)
printLabelsMultiline(w, "Labels", pvc.Labels)
printAnnotationsMultiline(w, "Annotations", pvc.Annotations)
storage := pvc.Spec.Resources.Requests[api.ResourceStorage]
capacity := ""
accessModes := ""
if pvc.Spec.VolumeName != "" {
accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes)
storage = pvc.Status.Capacity[api.ResourceStorage]
capacity = storage.String()
}
w.Write(LEVEL_0, "Capacity:\t%s\n", capacity)
w.Write(LEVEL_0, "Access Modes:\t%s\n", accessModes)
if events != nil {
@ -2150,6 +2156,15 @@ func (p *StatefulSetDescriber) Describe(namespace, name string, describerSetting
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = p.client.Core().Events(namespace).Search(api.Scheme, ps)
}
return describeStatefulSet(ps, selector, events, running, waiting, succeeded, failed)
}
func describeStatefulSet(ps *apps.StatefulSet, selector labels.Selector, events *api.EventList, running, waiting, succeeded, failed int) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", ps.ObjectMeta.Name)
@ -2162,12 +2177,10 @@ func (p *StatefulSetDescriber) Describe(namespace, name string, describerSetting
w.Write(LEVEL_0, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
DescribePodTemplate(&ps.Spec.Template, w)
describeVolumeClaimTemplates(ps.Spec.VolumeClaimTemplates, w)
if describerSettings.ShowEvents {
events, _ := p.client.Core().Events(namespace).Search(api.Scheme, ps)
if events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
@ -2191,6 +2204,15 @@ func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, de
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = p.client.Core().Events(namespace).Search(api.Scheme, csr)
}
return describeCertificateSigningRequest(csr, cr, status, events)
}
func describeCertificateSigningRequest(csr *certificates.CertificateSigningRequest, cr *x509.CertificateRequest, status string, events *api.EventList) (string, error) {
printListHelper := func(w PrefixWriter, prefix, name string, values []string) {
if len(values) == 0 {
return
@ -2231,12 +2253,10 @@ func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, de
printListHelper(w, "\t", "IP Addresses", ipaddrs)
}
if describerSettings.ShowEvents {
events, _ := p.client.Core().Events(namespace).Search(api.Scheme, csr)
if events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
@ -2251,6 +2271,16 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
if err != nil {
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = d.client.Core().Events(namespace).Search(api.Scheme, hpa)
}
return describeHorizontalPodAutoscaler(hpa, events, d)
}
func describeHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, events *api.EventList, d *HorizontalPodAutoscalerDescriber) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", hpa.Name)
@ -2318,12 +2348,10 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
}
}
if describerSettings.ShowEvents {
events, _ := d.client.Core().Events(namespace).Search(api.Scheme, hpa)
if events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
@ -2369,20 +2397,6 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node
return nil
}
func filterTerminatedPods(pods []*api.Pod) []*api.Pod {
if len(pods) == 0 {
return pods
}
result := []*api.Pod{}
for _, pod := range pods {
if pod.Status.Phase == api.PodSucceeded || pod.Status.Phase == api.PodFailed {
continue
}
result = append(result, pod)
}
return result
}
func getPodsTotalRequestsAndLimits(podList *api.PodList) (reqs map[api.ResourceName]resource.Quantity, limits map[api.ResourceName]resource.Quantity, err error) {
reqs, limits = map[api.ResourceName]resource.Quantity{}, map[api.ResourceName]resource.Quantity{}
for _, pod := range podList.Items {
@ -2450,6 +2464,16 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting
if err := api.Scheme.Convert(d, internalDeployment, extensions.SchemeGroupVersion); err != nil {
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = dd.Core().Events(namespace).Search(api.Scheme, d)
}
return describeDeployment(d, selector, internalDeployment, events, dd)
}
func describeDeployment(d *versionedextension.Deployment, selector labels.Selector, internalDeployment *extensions.Deployment, events *api.EventList, dd *DeploymentDescriber) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", d.ObjectMeta.Name)
@ -2486,58 +2510,14 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting
if len(overlapWith) > 0 {
w.Write(LEVEL_0, "!!!WARNING!!! This deployment has overlapping label selector with deployment %q and won't behave as expected. Please fix it before continuing.\n", overlapWith)
}
if describerSettings.ShowEvents {
events, err := dd.Core().Events(namespace).Search(api.Scheme, d)
if err == nil && events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
// Get all daemon set whose selectors would match a given set of labels.
// TODO: Move this to pkg/client and ideally implement it server-side (instead
// of getting all DS's and searching through them manually).
// TODO: write an interface for controllers and fuse getReplicationControllersForLabels
// and getDaemonSetsForLabels.
func getDaemonSetsForLabels(c extensionsclient.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) {
// Get all daemon sets
// TODO: this needs a namespace scope as argument
dss, err := c.List(metav1.ListOptions{})
if err != nil {
return nil, fmt.Errorf("error getting daemon set: %v", err)
}
// Find the ones that match labelsToMatch.
var matchingDaemonSets []extensions.DaemonSet
for _, ds := range dss.Items {
selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector)
if err != nil {
// this should never happen if the DaemonSet passed validation
return nil, err
}
if selector.Matches(labelsToMatch) {
matchingDaemonSets = append(matchingDaemonSets, ds)
}
}
return matchingDaemonSets, nil
}
func printReplicationControllersByLabels(matchingRCs []*api.ReplicationController) string {
// Format the matching RC's into strings.
rcStrings := make([]string, 0, len(matchingRCs))
for _, controller := range matchingRCs {
rcStrings = append(rcStrings, fmt.Sprintf("%s (%d/%d replicas created)", controller.Name, controller.Status.Replicas, controller.Spec.Replicas))
}
list := strings.Join(rcStrings, ", ")
if list == "" {
return "<none>"
}
return list
}
func printReplicaSetsByLabels(matchingRSs []*versionedextension.ReplicaSet) string {
// Format the matching ReplicaSets into strings.
rsStrings := make([]string, 0, len(matchingRSs))
@ -2689,6 +2669,16 @@ func (s *StorageClassDescriber) Describe(namespace, name string, describerSettin
if err != nil {
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = s.Core().Events(namespace).Search(api.Scheme, sc)
}
return describeStorageClass(sc, events)
}
func describeStorageClass(sc *storage.StorageClass, events *api.EventList) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", sc.Name)
@ -2696,15 +2686,10 @@ func (s *StorageClassDescriber) Describe(namespace, name string, describerSettin
w.Write(LEVEL_0, "Annotations:\t%s\n", labels.FormatLabels(sc.Annotations))
w.Write(LEVEL_0, "Provisioner:\t%s\n", sc.Provisioner)
w.Write(LEVEL_0, "Parameters:\t%s\n", labels.FormatLabels(sc.Parameters))
if describerSettings.ShowEvents {
events, err := s.Core().Events(namespace).Search(api.Scheme, sc)
if err != nil {
return err
}
if events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
@ -2718,6 +2703,16 @@ func (p *PodDisruptionBudgetDescriber) Describe(namespace, name string, describe
if err != nil {
return "", err
}
var events *api.EventList
if describerSettings.ShowEvents {
events, _ = p.Core().Events(namespace).Search(api.Scheme, pdb)
}
return describePodDisruptionBudget(pdb, events)
}
func describePodDisruptionBudget(pdb *policy.PodDisruptionBudget, events *api.EventList) (string, error) {
return tabbedString(func(out io.Writer) error {
w := NewPrefixWriter(out)
w.Write(LEVEL_0, "Name:\t%s\n", pdb.Name)
@ -2732,15 +2727,10 @@ func (p *PodDisruptionBudgetDescriber) Describe(namespace, name string, describe
w.Write(LEVEL_2, "Current:\t%d\n", pdb.Status.CurrentHealthy)
w.Write(LEVEL_2, "Desired:\t%d\n", pdb.Status.DesiredHealthy)
w.Write(LEVEL_2, "Total:\t%d\n", pdb.Status.ExpectedPods)
if describerSettings.ShowEvents {
events, err := p.Core().Events(namespace).Search(api.Scheme, pdb)
if err != nil {
return err
}
if events != nil {
DescribeEvents(events, w)
}
if events != nil {
DescribeEvents(events, w)
}
return nil
})
}
@ -2886,11 +2876,6 @@ func (fn typeFunc) Describe(exact interface{}, extra ...interface{}) (string, er
return s, err
}
// printLabelsMultilineWithFilter prints filtered multiple labels with a proper alignment.
func printLabelsMultilineWithFilter(w PrefixWriter, title string, labels map[string]string, skip sets.String) {
printLabelsMultilineWithIndent(w, "", title, "\t", labels, skip)
}
// printLabelsMultiline prints multiple labels with a proper alignment.
func printLabelsMultiline(w PrefixWriter, title string, labels map[string]string) {
printLabelsMultilineWithIndent(w, "", title, "\t", labels, sets.NewString())
@ -2898,7 +2883,6 @@ func printLabelsMultiline(w PrefixWriter, title string, labels map[string]string
// printLabelsMultiline prints multiple labels with a user-defined alignment.
func printLabelsMultilineWithIndent(w PrefixWriter, initialIndent, title, innerIndent string, labels map[string]string, skip sets.String) {
w.Write(LEVEL_0, "%s%s:%s", initialIndent, title, innerIndent)
if labels == nil || len(labels) == 0 {
@ -3077,16 +3061,6 @@ func (list SortableVolumeMounts) Less(i, j int) bool {
return list[i].MountPath < list[j].MountPath
}
// SortedQoSResourceNames returns the sorted resource names of a QoS list.
func SortedQoSResourceNames(list qos.QOSList) []api.ResourceName {
resources := make([]api.ResourceName, 0, len(list))
for res := range list {
resources = append(resources, api.ResourceName(res))
}
sort.Sort(SortableResourceNames(resources))
return resources
}
func versionedClientsetForDeployment(internalClient clientset.Interface) versionedclientset.Interface {
if internalClient == nil {
return &versionedclientset.Clientset{}