diff --git a/pkg/printers/internalversion/BUILD b/pkg/printers/internalversion/BUILD index b6366fd6ffa..0ed8a396405 100644 --- a/pkg/printers/internalversion/BUILD +++ b/pkg/printers/internalversion/BUILD @@ -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", diff --git a/pkg/printers/internalversion/describe.go b/pkg/printers/internalversion/describe.go index 320c77ab25b..1359a530888 100644 --- a/pkg/printers/internalversion/describe.go +++ b/pkg/printers/internalversion/describe.go @@ -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 "" - } - 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{}