Add table printer for 3rdpartyResource and deployment

This commit is contained in:
Haoran Wang
2017-07-27 17:22:48 +08:00
parent d3d18b5f51
commit 143cc77976
2 changed files with 74 additions and 61 deletions

View File

@@ -61,7 +61,6 @@ const loadBalancerWidth = 16
// NOTE: When adding a new resource type here, please update the list // NOTE: When adding a new resource type here, please update the list
// pkg/kubectl/cmd/get.go to reflect the new resource type. // pkg/kubectl/cmd/get.go to reflect the new resource type.
var ( var (
thirdPartyResourceColumns = []string{"NAME", "DESCRIPTION", "VERSION(S)"}
roleBindingColumns = []string{"NAME", "AGE"} roleBindingColumns = []string{"NAME", "AGE"}
roleBindingWideColumns = []string{"ROLE", "USERS", "GROUPS", "SERVICEACCOUNTS"} roleBindingWideColumns = []string{"ROLE", "USERS", "GROUPS", "SERVICEACCOUNTS"}
clusterRoleBindingColumns = []string{"NAME", "AGE"} clusterRoleBindingColumns = []string{"NAME", "AGE"}
@@ -70,8 +69,6 @@ var (
statusColumns = []string{"STATUS", "REASON", "MESSAGE"} statusColumns = []string{"STATUS", "REASON", "MESSAGE"}
horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGETS", "MINPODS", "MAXPODS", "REPLICAS", "AGE"} horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGETS", "MINPODS", "MAXPODS", "REPLICAS", "AGE"}
deploymentColumns = []string{"NAME", "DESIRED", "CURRENT", "UP-TO-DATE", "AVAILABLE", "AGE"}
deploymentWideColumns = []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
configMapColumns = []string{"NAME", "DATA", "AGE"} configMapColumns = []string{"NAME", "DATA", "AGE"}
podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "SELINUX", "RUNASUSER", "FSGROUP", "SUPGROUP", "READONLYROOTFS", "VOLUMES"} podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "SELINUX", "RUNASUSER", "FSGROUP", "SUPGROUP", "READONLYROOTFS", "VOLUMES"}
clusterColumns = []string{"NAME", "STATUS", "AGE"} clusterColumns = []string{"NAME", "STATUS", "AGE"}
@@ -313,10 +310,29 @@ func AddHandlers(h printers.PrintHandler) {
h.TableHandler(componentStatusColumnDefinitions, printComponentStatus) h.TableHandler(componentStatusColumnDefinitions, printComponentStatus)
h.TableHandler(componentStatusColumnDefinitions, printComponentStatusList) h.TableHandler(componentStatusColumnDefinitions, printComponentStatusList)
h.Handler(thirdPartyResourceColumns, nil, printThirdPartyResource) thirdPartyResourceColumnDefinitions := []metav1alpha1.TableColumnDefinition{
h.Handler(thirdPartyResourceColumns, nil, printThirdPartyResourceList) {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
h.Handler(deploymentColumns, deploymentWideColumns, printDeployment) {Name: "Description", Type: "string", Description: extensionsv1beta1.ThirdPartyResource{}.SwaggerDoc()["description"]},
h.Handler(deploymentColumns, deploymentWideColumns, printDeploymentList) {Name: "version(s)", Type: "string", Description: extensionsv1beta1.ThirdPartyResource{}.SwaggerDoc()["versions"]},
}
h.TableHandler(thirdPartyResourceColumnDefinitions, printThirdPartyResource)
h.TableHandler(thirdPartyResourceColumnDefinitions, printThirdPartyResourceList)
deploymentColumnDefinitions := []metav1alpha1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Desired", Type: "string", Description: extensionsv1beta1.DeploymentSpec{}.SwaggerDoc()["replicas"]},
{Name: "Current", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["replicas"]},
{Name: "Up-to-date", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["updatedReplicas"]},
{Name: "Available", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["availableReplicas"]},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
{Name: "Containers", Type: "string", Priority: 1, Description: "Names of each container in the template."},
{Name: "Images", Type: "string", Priority: 1, Description: "Images referenced by each container in the template."},
{Name: "Selector", Type: "string", Priority: 1, Description: extensionsv1beta1.DeploymentSpec{}.SwaggerDoc()["selector"]},
}
h.TableHandler(deploymentColumnDefinitions, printDeployment)
h.TableHandler(deploymentColumnDefinitions, printDeploymentList)
h.Handler(horizontalPodAutoscalerColumns, nil, printHorizontalPodAutoscaler) h.Handler(horizontalPodAutoscalerColumns, nil, printHorizontalPodAutoscaler)
h.Handler(horizontalPodAutoscalerColumns, nil, printHorizontalPodAutoscalerList) h.Handler(horizontalPodAutoscalerColumns, nil, printHorizontalPodAutoscalerList)
h.Handler(configMapColumns, nil, printConfigMap) h.Handler(configMapColumns, nil, printConfigMap)
@@ -1408,29 +1424,31 @@ func printComponentStatusList(list *api.ComponentStatusList, options printers.Pr
return rows, nil return rows, nil
} }
func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, options printers.PrintOptions) error { func printThirdPartyResource(obj *extensions.ThirdPartyResource, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
name := printers.FormatResourceName(options.Kind, rsrc.Name, options.WithKind) row := metav1alpha1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
versions := make([]string, len(rsrc.Versions)) versions := make([]string, len(obj.Versions))
for ix := range rsrc.Versions { for ix := range obj.Versions {
version := &rsrc.Versions[ix] version := &obj.Versions[ix]
versions[ix] = fmt.Sprintf("%s", version.Name) versions[ix] = fmt.Sprintf("%s", version.Name)
} }
versionsString := strings.Join(versions, ",") versionsString := strings.Join(versions, ",")
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", name, rsrc.Description, versionsString); err != nil { row.Cells = append(row.Cells, obj.Name, obj.Description, versionsString)
return err return []metav1alpha1.TableRow{row}, nil
}
return nil
} }
func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, w io.Writer, options printers.PrintOptions) error { func printThirdPartyResourceList(list *extensions.ThirdPartyResourceList, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
for _, item := range list.Items { rows := make([]metav1alpha1.TableRow, 0, len(list.Items))
if err := printThirdPartyResource(&item, w, options); err != nil { for i := range list.Items {
return err r, err := printThirdPartyResource(&list.Items[i], options)
if err != nil {
return nil, err
} }
rows = append(rows, r...)
} }
return rows, nil
return nil
} }
func truncate(str string, maxLen int) string { func truncate(str string, maxLen int) string {
@@ -1440,53 +1458,39 @@ func truncate(str string, maxLen int) string {
return str return str
} }
func printDeployment(deployment *extensions.Deployment, w io.Writer, options printers.PrintOptions) error { func printDeployment(obj *extensions.Deployment, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
name := printers.FormatResourceName(options.Kind, deployment.Name, options.WithKind) row := metav1alpha1.TableRow{
Object: runtime.RawExtension{Object: obj},
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", deployment.Namespace); err != nil {
return err
} }
} desiredReplicas := obj.Spec.Replicas
currentReplicas := obj.Status.Replicas
desiredReplicas := deployment.Spec.Replicas updatedReplicas := obj.Status.UpdatedReplicas
currentReplicas := deployment.Status.Replicas availableReplicas := obj.Status.AvailableReplicas
updatedReplicas := deployment.Status.UpdatedReplicas age := translateTimestamp(obj.CreationTimestamp)
availableReplicas := deployment.Status.AvailableReplicas containers := obj.Spec.Template.Spec.Containers
age := translateTimestamp(deployment.CreationTimestamp) selector, err := metav1.LabelSelectorAsSelector(obj.Spec.Selector)
containers := deployment.Spec.Template.Spec.Containers
selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
if err != nil { if err != nil {
// this shouldn't happen if LabelSelector passed validation // this shouldn't happen if LabelSelector passed validation
return err return nil, err
}
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil {
return err
} }
row.Cells = append(row.Cells, obj.Name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age)
if options.Wide { if options.Wide {
if err := layoutContainers(containers, w); err != nil { containers, images := layoutContainerCells(containers)
return err row.Cells = append(row.Cells, containers, images, selector.String())
} }
if _, err := fmt.Fprintf(w, "\t%s", selector.String()); err != nil { return []metav1alpha1.TableRow{row}, nil
return err
}
}
if _, err := fmt.Fprint(w, printers.AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil {
return err
}
_, err = fmt.Fprint(w, printers.AppendAllLabels(options.ShowLabels, deployment.Labels))
return err
} }
func printDeploymentList(list *extensions.DeploymentList, w io.Writer, options printers.PrintOptions) error { func printDeploymentList(list *extensions.DeploymentList, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
for _, item := range list.Items { rows := make([]metav1alpha1.TableRow, 0, len(list.Items))
if err := printDeployment(&item, w, options); err != nil { for i := range list.Items {
return err r, err := printDeployment(&list.Items[i], options)
if err != nil {
return nil, err
} }
rows = append(rows, r...)
} }
return nil return rows, nil
} }
func formatHPAMetrics(specs []autoscaling.MetricSpec, statuses []autoscaling.MetricStatus) string { func formatHPAMetrics(specs []autoscaling.MetricSpec, statuses []autoscaling.MetricStatus) string {

View File

@@ -1902,13 +1902,22 @@ func TestPrintDeployment(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
for _, test := range tests { for _, test := range tests {
printDeployment(&test.deployment, buf, printers.PrintOptions{}) table, err := printers.NewTablePrinter().With(AddHandlers).PrintTable(&test.deployment, printers.PrintOptions{})
if err != nil {
t.Fatal(err)
}
if err := printers.PrintTable(table, buf, printers.PrintOptions{NoHeaders: true}); err != nil {
t.Fatal(err)
}
if buf.String() != test.expect { if buf.String() != test.expect {
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
} }
buf.Reset() buf.Reset()
table, err = printers.NewTablePrinter().With(AddHandlers).PrintTable(&test.deployment, printers.PrintOptions{Wide: true})
// print deployment with '-o wide' option // print deployment with '-o wide' option
printDeployment(&test.deployment, buf, printers.PrintOptions{Wide: true}) if err := printers.PrintTable(table, buf, printers.PrintOptions{Wide: true, NoHeaders: true}); err != nil {
t.Fatal(err)
}
if buf.String() != test.wideExpect { if buf.String() != test.wideExpect {
t.Fatalf("Expected: %s, got: %s", test.wideExpect, buf.String()) t.Fatalf("Expected: %s, got: %s", test.wideExpect, buf.String())
} }