diff --git a/gwctl/cmd/subcommand.go b/gwctl/cmd/subcommand.go index 01a7d8edcf..1adfff3529 100644 --- a/gwctl/cmd/subcommand.go +++ b/gwctl/cmd/subcommand.go @@ -349,7 +349,7 @@ func runGetOrDescribeBackends(f cmdutils.Factory, o *getOrDescribeOptions) { realClock := clock.RealClock{} backendsPrinter := &printer.BackendsPrinter{Writer: o.out, Clock: realClock} if o.cmdName == commandNameGet { - backendsPrinter.Print(resourceModel) + printer.Print(backendsPrinter, resourceModel, o.outputFormat) } else { backendsPrinter.PrintDescribeView(resourceModel) } diff --git a/gwctl/pkg/printer/backends.go b/gwctl/pkg/printer/backends.go index a80ebc9319..36c25d699d 100644 --- a/gwctl/pkg/printer/backends.go +++ b/gwctl/pkg/printer/backends.go @@ -34,9 +34,20 @@ type BackendsPrinter struct { Clock clock.Clock } -func (bp *BackendsPrinter) Print(resourceModel *resourcediscovery.ResourceModel) { +func (bp *BackendsPrinter) GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource { + return NodeResources(maps.Values(resourceModel.GatewayClasses)) +} + +func (bp *BackendsPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) { + var columnNames []string + if wide { + columnNames = []string{"NAMESPACE", "NAME", "TYPE", "AGE", "REFERRED BY ROUTES", "POLICIES"} + } else { + columnNames = []string{"NAMESPACE", "NAME", "TYPE", "AGE"} + } + table := &Table{ - ColumnNames: []string{"NAMESPACE", "NAME", "TYPE", "REFERRED BY ROUTES", "AGE", "POLICIES"}, + ColumnNames: columnNames, UseSeparator: false, } @@ -50,38 +61,38 @@ func (bp *BackendsPrinter) Print(resourceModel *resourcediscovery.ResourceModel) sortedHTTPRouteNodes := SortByString(httpRouteNodes) totalRoutes := len(sortedHTTPRouteNodes) - var referredByRoutes string - if totalRoutes == 0 { - referredByRoutes = "None" - } else { - var routes []string - for i, httpRouteNode := range sortedHTTPRouteNodes { - if i < 2 { - namespacedName := client.ObjectKeyFromObject(httpRouteNode.HTTPRoute).String() - routes = append(routes, namespacedName) - } else { - break - } - } - referredByRoutes = strings.Join(routes, ", ") - if totalRoutes > 2 { - referredByRoutes += fmt.Sprintf(" + %d more", totalRoutes-2) - } - } - namespace := backend.GetNamespace() name := backend.GetName() backendType := backend.GetKind() age := duration.HumanDuration(bp.Clock.Since(backend.GetCreationTimestamp().Time)) - policiesCount := fmt.Sprintf("%d", len(backendNode.Policies)) row := []string{ namespace, name, backendType, - referredByRoutes, age, - policiesCount, + } + if wide { + var referredByRoutes string + if totalRoutes == 0 { + referredByRoutes = "None" + } else { + var routes []string + for i, httpRouteNode := range sortedHTTPRouteNodes { + if i < 2 { + namespacedName := client.ObjectKeyFromObject(httpRouteNode.HTTPRoute).String() + routes = append(routes, namespacedName) + } else { + break + } + } + referredByRoutes = strings.Join(routes, ", ") + if totalRoutes > 2 { + referredByRoutes += fmt.Sprintf(" + %d more", totalRoutes-2) + } + } + policiesCount := fmt.Sprintf("%d", len(backendNode.Policies)) + row = append(row, referredByRoutes, policiesCount) } table.Rows = append(table.Rows, row) } diff --git a/gwctl/pkg/printer/backends_test.go b/gwctl/pkg/printer/backends_test.go index de74327ab3..1ebcfbd039 100644 --- a/gwctl/pkg/printer/backends_test.go +++ b/gwctl/pkg/printer/backends_test.go @@ -196,15 +196,32 @@ func TestBackendsPrinter_Print(t *testing.T) { Clock: fakeClock, } - bp.Print(resourceModel) + bp.PrintTable(resourceModel, false) got := buff.String() want := ` -NAMESPACE NAME TYPE REFERRED BY ROUTES AGE POLICIES -ns1 foo-svc-1 Service ns1/foo-httproute-1 3d 1 -ns1 foo-svc-2 Service ns1/foo-httproute-2, ns1/foo-httproute-3 + 2 more 2d 0 +NAMESPACE NAME TYPE AGE +ns1 foo-svc-1 Service 3d +ns1 foo-svc-2 Service 2d ` if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" { t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff) } + + buff.Reset() + nsp2 := &BackendsPrinter{ + Writer: buff, + Clock: fakeClock, + } + nsp2.PrintTable(resourceModel, true) + + got2 := buff.String() + want2 := ` +NAMESPACE NAME TYPE AGE REFERRED BY ROUTES POLICIES +ns1 foo-svc-1 Service 3d ns1/foo-httproute-1 1 +ns1 foo-svc-2 Service 2d ns1/foo-httproute-2, ns1/foo-httproute-3 + 2 more 0 +` + if diff := cmp.Diff(common.YamlString(want2), common.YamlString(got2), common.YamlStringTransformer); diff != "" { + t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got2, want2, diff) + } } diff --git a/gwctl/pkg/printer/gatewayclasses.go b/gwctl/pkg/printer/gatewayclasses.go index 544720eb6f..534cbfd470 100644 --- a/gwctl/pkg/printer/gatewayclasses.go +++ b/gwctl/pkg/printer/gatewayclasses.go @@ -38,9 +38,15 @@ func (gcp *GatewayClassesPrinter) GetPrintableNodes(resourceModel *resourcedisco return NodeResources(maps.Values(resourceModel.GatewayClasses)) } -func (gcp *GatewayClassesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel) { +func (gcp *GatewayClassesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) { + var columnNames []string + if wide { + columnNames = []string{"NAME", "CONTROLLER", "ACCEPTED", "AGE", "GATEWAYS"} + } else { + columnNames = []string{"NAME", "CONTROLLER", "ACCEPTED", "AGE"} + } table := &Table{ - ColumnNames: []string{"NAME", "CONTROLLER", "ACCEPTED", "AGE"}, + ColumnNames: columnNames, UseSeparator: false, } @@ -62,6 +68,10 @@ func (gcp *GatewayClassesPrinter) PrintTable(resourceModel *resourcediscovery.Re accepted, age, } + if wide { + gatewayCount := fmt.Sprintf("%d", len(gatewayClassNode.Gateways)) + row = append(row, gatewayCount) + } table.Rows = append(table.Rows, row) } diff --git a/gwctl/pkg/printer/gatewayclasses_test.go b/gwctl/pkg/printer/gatewayclasses_test.go index ea74a169e1..cdcdad9c32 100644 --- a/gwctl/pkg/printer/gatewayclasses_test.go +++ b/gwctl/pkg/printer/gatewayclasses_test.go @@ -99,6 +99,37 @@ func TestGatewayClassesPrinter_PrintTable(t *testing.T) { }, }, }, + &gatewayv1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bar-gateway", + CreationTimestamp: metav1.Time{ + Time: fakeClock.Now().Add(-3 * time.Second), + }, + }, + Spec: gatewayv1.GatewaySpec{ + GatewayClassName: "bar-com-internal-gateway-class", + Listeners: []gatewayv1.Listener{ + { + Name: gatewayv1.SectionName("http-8443"), + Protocol: gatewayv1.HTTPProtocolType, + Port: gatewayv1.PortNumber(8443), + }, + }, + }, + Status: gatewayv1.GatewayStatus{ + Addresses: []gatewayv1.GatewayStatusAddress{ + { + Value: "10.11.12.13", + }, + }, + Conditions: []metav1.Condition{ + { + Type: "Programmed", + Status: "Unknown", + }, + }, + }, + }, } k8sClients := common.MustClientsForTest(t, objects...) @@ -117,7 +148,7 @@ func TestGatewayClassesPrinter_PrintTable(t *testing.T) { Writer: buff, Clock: fakeClock, } - Print(gcp, resourceModel, utils.OutputFormatTable) + gcp.PrintTable(resourceModel, false) got := buff.String() want := ` @@ -129,6 +160,23 @@ foo-com-internal-gateway-class foo.com/internal-gateway-class Unknown 24m if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" { t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff) } + buff.Reset() + gcp2 := &GatewayClassesPrinter{ + Writer: buff, + Clock: fakeClock, + } + gcp2.PrintTable(resourceModel, true) + + got2 := buff.String() + want2 := ` +NAME CONTROLLER ACCEPTED AGE GATEWAYS +bar-com-internal-gateway-class bar.baz/internal-gateway-class True 365d 1 +foo-com-external-gateway-class foo.com/external-gateway-class False 100d 0 +foo-com-internal-gateway-class foo.com/internal-gateway-class Unknown 24m 0 +` + if diff := cmp.Diff(common.YamlString(want2), common.YamlString(got2), common.YamlStringTransformer); diff != "" { + t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got2, want2, diff) + } } func TestGatewayClassesPrinter_PrintDescribeView(t *testing.T) { diff --git a/gwctl/pkg/printer/gateways.go b/gwctl/pkg/printer/gateways.go index 7872cbf82f..ad1809315b 100644 --- a/gwctl/pkg/printer/gateways.go +++ b/gwctl/pkg/printer/gateways.go @@ -39,9 +39,15 @@ func (gp *GatewaysPrinter) GetPrintableNodes(resourceModel *resourcediscovery.Re return NodeResources(maps.Values(resourceModel.Gateways)) } -func (gp *GatewaysPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel) { +func (gp *GatewaysPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) { + var columnNames []string + if wide { + columnNames = []string{"NAMESPACE", "NAME", "CLASS", "ADDRESSES", "PORTS", "PROGRAMMED", "AGE", "POLICIES", "HTTPROUTES"} + } else { + columnNames = []string{"NAMESPACE", "NAME", "CLASS", "ADDRESSES", "PORTS", "PROGRAMMED", "AGE"} + } table := &Table{ - ColumnNames: []string{"NAMESPACE", "NAME", "CLASS", "ADDRESSES", "PORTS", "PROGRAMMED", "AGE"}, + ColumnNames: columnNames, UseSeparator: false, } @@ -82,6 +88,11 @@ func (gp *GatewaysPrinter) PrintTable(resourceModel *resourcediscovery.ResourceM programmedStatus, age, } + if wide { + policiesCount := fmt.Sprintf("%d", len(gatewayNode.Policies)) + httpRoutesCount := fmt.Sprintf("%d", len(gatewayNode.HTTPRoutes)) + row = append(row, policiesCount, httpRoutesCount) + } table.Rows = append(table.Rows, row) } diff --git a/gwctl/pkg/printer/gateways_test.go b/gwctl/pkg/printer/gateways_test.go index 3310379bc7..fcdd71f9b9 100644 --- a/gwctl/pkg/printer/gateways_test.go +++ b/gwctl/pkg/printer/gateways_test.go @@ -176,6 +176,90 @@ func TestGatewaysPrinter_PrintTable(t *testing.T) { }, }, }, + &gatewayv1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-httproute", + }, + Spec: gatewayv1.HTTPRouteSpec{ + CommonRouteSpec: gatewayv1.CommonRouteSpec{ + ParentRefs: []gatewayv1.ParentReference{{ + Kind: common.PtrTo(gatewayv1.Kind("Gateway")), + Group: common.PtrTo(gatewayv1.Group("gateway.networking.k8s.io")), + Name: "abc-gateway-12345", + }}, + }, + }, + }, + + &apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "healthcheckpolicies.foo.com", + Labels: map[string]string{ + gatewayv1alpha2.PolicyLabelKey: "inherited", + }, + }, + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Scope: apiextensionsv1.ClusterScoped, + Group: "foo.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}}, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "healthcheckpolicies", + Kind: "HealthCheckPolicy", + }, + }, + }, + &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "foo.com/v1", + "kind": "HealthCheckPolicy", + "metadata": map[string]interface{}{ + "name": "health-check-gatewayclass", + }, + "spec": map[string]interface{}{ + "override": map[string]interface{}{ + "key1": "value-parent-1", + "key3": "value-parent-3", + "key5": "value-parent-5", + }, + "default": map[string]interface{}{ + "key2": "value-parent-2", + "key4": "value-parent-4", + }, + "targetRef": map[string]interface{}{ + "group": "gateway.networking.k8s.io", + "kind": "GatewayClass", + "name": "regional-internal-class", + }, + }, + }, + }, + &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "foo.com/v1", + "kind": "HealthCheckPolicy", + "metadata": map[string]interface{}{ + "name": "health-check-gateway", + }, + "spec": map[string]interface{}{ + "override": map[string]interface{}{ + "key1": "value-child-1", + }, + "default": map[string]interface{}{ + "key2": "value-child-2", + "key5": "value-child-5", + }, + "targetRef": map[string]interface{}{ + "group": "gateway.networking.k8s.io", + "kind": "Gateway", + "name": "random-gateway", + "namespace": "default", + }, + }, + }, + }, } k8sClients := common.MustClientsForTest(t, objects...) @@ -194,7 +278,7 @@ func TestGatewaysPrinter_PrintTable(t *testing.T) { Writer: buff, Clock: fakeClock, } - gp.PrintTable(resourceModel) + gp.PrintTable(resourceModel, false) got := buff.String() want := ` @@ -207,6 +291,24 @@ default random-gateway regional-internal-class 10.11.12.13 if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" { t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff) } + + buff.Reset() + nsp2 := &GatewaysPrinter{ + Writer: buff, + Clock: fakeClock, + } + nsp2.PrintTable(resourceModel, true) + + got2 := buff.String() + want2 := ` +NAMESPACE NAME CLASS ADDRESSES PORTS PROGRAMMED AGE POLICIES HTTPROUTES +default abc-gateway-12345 internal-class 192.168.100.5 443,8080 False 20d 0 1 +default demo-gateway-2 external-class 10.0.0.1,10.0.0.2 + 1 more 80 True 5d 0 0 +default random-gateway regional-internal-class 10.11.12.13 8443 Unknown 3s 1 0 +` + if diff := cmp.Diff(common.YamlString(want2), common.YamlString(got2), common.YamlStringTransformer); diff != "" { + t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got2, want2, diff) + } } func TestGatewaysPrinter_PrintDescribeView(t *testing.T) { diff --git a/gwctl/pkg/printer/httproutes.go b/gwctl/pkg/printer/httproutes.go index 2ff61b113e..84b7dac749 100644 --- a/gwctl/pkg/printer/httproutes.go +++ b/gwctl/pkg/printer/httproutes.go @@ -43,12 +43,18 @@ func (hp *HTTPRoutesPrinter) GetPrintableNodes(resourceModel *resourcediscovery. return NodeResources(maps.Values(resourceModel.HTTPRoutes)) } -func (hp *HTTPRoutesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel) { +func (hp *HTTPRoutesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) { + var columnNames []string + if wide { + columnNames = []string{"NAMESPACE", "NAME", "HOSTNAMES", "PARENT REFS", "AGE", "POLICIES"} + } else { + columnNames = []string{"NAMESPACE", "NAME", "HOSTNAMES", "PARENT REFS", "AGE"} + } + table := &Table{ - ColumnNames: []string{"NAMESPACE", "NAME", "HOSTNAMES", "PARENT REFS", "AGE"}, + ColumnNames: columnNames, UseSeparator: false, } - httpRouteNodes := maps.Values(resourceModel.HTTPRoutes) for _, httpRouteNode := range SortByString(httpRouteNodes) { @@ -76,6 +82,10 @@ func (hp *HTTPRoutesPrinter) PrintTable(resourceModel *resourcediscovery.Resourc parentRefsCount, age, } + if wide { + policiesCount := fmt.Sprintf("%d", len(httpRouteNode.Policies)) + row = append(row, policiesCount) + } table.Rows = append(table.Rows, row) } table.Write(hp, 0) diff --git a/gwctl/pkg/printer/httproutes_test.go b/gwctl/pkg/printer/httproutes_test.go index a2e3f6d766..20e19159ba 100644 --- a/gwctl/pkg/printer/httproutes_test.go +++ b/gwctl/pkg/printer/httproutes_test.go @@ -203,6 +203,41 @@ func TestHTTPRoutesPrinter_PrintTable(t *testing.T) { }, }, }, + &apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "timeoutpolicies.bar.com", + Labels: map[string]string{ + gatewayv1alpha2.PolicyLabelKey: "direct", + }, + }, + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Scope: apiextensionsv1.ClusterScoped, + Group: "bar.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}}, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "timeoutpolicies", + Kind: "TimeoutPolicy", + }, + }, + }, + &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "bar.com/v1", + "kind": "TimeoutPolicy", + "metadata": map[string]interface{}{ + "name": "timeout-policy-httproute", + }, + "spec": map[string]interface{}{ + "condition": "path=/def", + "seconds": int64(60), + "targetRef": map[string]interface{}{ + "group": "gateway.networking.k8s.io", + "kind": "HTTPRoute", + "name": "foo-httproute-1", + }, + }, + }, + }, } k8sClients := common.MustClientsForTest(t, objects...) @@ -222,7 +257,7 @@ func TestHTTPRoutesPrinter_PrintTable(t *testing.T) { Clock: fakeClock, } - hp.PrintTable(resourceModel) + hp.PrintTable(resourceModel, false) got := buff.String() want := ` @@ -235,6 +270,25 @@ ns2 bax-httproute-18777 None 1 if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" { t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff) } + + buff.Reset() + hp2 := &HTTPRoutesPrinter{ + Writer: buff, + Clock: fakeClock, + } + hp2.PrintTable(resourceModel, true) + + got2 := buff.String() + want2 := ` +NAMESPACE NAME HOSTNAMES PARENT REFS AGE POLICIES +default foo-httproute-1 example.com,example2.com + 1 more 1 24h 1 +default qmn-httproute-100 example.com 2 11h 0 +ns1 bar-route-21 foo.com,bar.com + 5 more 1 9h 0 +ns2 bax-httproute-18777 None 1 5m 0 +` + if diff := cmp.Diff(common.YamlString(want2), common.YamlString(got2), common.YamlStringTransformer); diff != "" { + t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got2, want2, diff) + } } func TestHTTPRoutesPrinter_PrintDescribeView(t *testing.T) { diff --git a/gwctl/pkg/printer/namespace.go b/gwctl/pkg/printer/namespace.go index 4d765534d3..b292c701f6 100644 --- a/gwctl/pkg/printer/namespace.go +++ b/gwctl/pkg/printer/namespace.go @@ -38,9 +38,16 @@ func (nsp *NamespacesPrinter) GetPrintableNodes(resourceModel *resourcediscovery return NodeResources(maps.Values(resourceModel.Namespaces)) } -func (nsp *NamespacesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel) { +func (nsp *NamespacesPrinter) PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) { + var columnNames []string + if wide { + columnNames = []string{"NAME", "STATUS", "AGE", "POLICIES"} + } else { + columnNames = []string{"NAME", "STATUS", "AGE"} + } + table := &Table{ - ColumnNames: []string{"NAME", "STATUS", "AGE"}, + ColumnNames: columnNames, UseSeparator: false, } @@ -52,6 +59,10 @@ func (nsp *NamespacesPrinter) PrintTable(resourceModel *resourcediscovery.Resour string(namespaceNode.Namespace.Status.Phase), age, } + if wide { + policiesCount := fmt.Sprintf("%d", len(namespaceNode.Policies)) + row = append(row, policiesCount) + } table.Rows = append(table.Rows, row) } diff --git a/gwctl/pkg/printer/namespace_test.go b/gwctl/pkg/printer/namespace_test.go index 68158573a1..2bc571e93f 100644 --- a/gwctl/pkg/printer/namespace_test.go +++ b/gwctl/pkg/printer/namespace_test.go @@ -73,6 +73,41 @@ func TestNamespacePrinter_PrintTable(t *testing.T) { Phase: corev1.NamespaceTerminating, }, }, + // CRD and definition for TimeoutPolicy attached to default namespace + &apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "timeoutpolicies.bar.com", + Labels: map[string]string{ + gatewayv1alpha2.PolicyLabelKey: "direct", + }, + }, + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Scope: apiextensionsv1.ClusterScoped, + Group: "bar.com", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}}, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "timeoutpolicies", + Kind: "TimeoutPolicy", + }, + }, + }, + &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "bar.com/v1", + "kind": "TimeoutPolicy", + "metadata": map[string]interface{}{ + "name": "timeout-policy-namespace", + }, + "spec": map[string]interface{}{ + "condition": "path=/abc", + "seconds": int64(30), + "targetRef": map[string]interface{}{ + "kind": "Namespace", + "name": "ns1", + }, + }, + }, + }, } k8sClients := common.MustClientsForTest(t, objects...) @@ -91,7 +126,7 @@ func TestNamespacePrinter_PrintTable(t *testing.T) { Writer: buff, Clock: fakeClock, } - nsp.PrintTable(resourceModel) + nsp.PrintTable(resourceModel, false) got := buff.String() want := ` @@ -100,10 +135,27 @@ default Active 46d kube-system Active 46d ns1 Terminating 10m ` - if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" { t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff) } + + buff.Reset() + nsp2 := &NamespacesPrinter{ + Writer: buff, + Clock: fakeClock, + } + nsp2.PrintTable(resourceModel, true) + + got2 := buff.String() + want2 := ` +NAME STATUS AGE POLICIES +default Active 46d 0 +kube-system Active 46d 0 +ns1 Terminating 10m 1 +` + if diff := cmp.Diff(common.YamlString(want2), common.YamlString(got2), common.YamlStringTransformer); diff != "" { + t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got2, want2, diff) + } } func TestNamespacePrinter_PrintDescribeView(t *testing.T) { diff --git a/gwctl/pkg/printer/policies.go b/gwctl/pkg/printer/policies.go index 7089fb1fbe..7d4493fd83 100644 --- a/gwctl/pkg/printer/policies.go +++ b/gwctl/pkg/printer/policies.go @@ -88,7 +88,7 @@ func (pp *PoliciesPrinter) PrintPolicies(policies []policymanager.Policy, format switch format { case utils.OutputFormatJSON, utils.OutputFormatYAML: pp.printClientObjects(clientObjects, format) - case utils.OutputFormatTable: + case utils.OutputFormatTable, utils.OutputFormatWide: pp.printPoliciesTable(sortedPolicies) default: fmt.Fprintf(os.Stderr, "unknown output format '%s' found\n", format) @@ -129,7 +129,7 @@ func (pp *PoliciesPrinter) PrintCRDs(policyCRDs []policymanager.PolicyCRD, forma switch format { case utils.OutputFormatJSON, utils.OutputFormatYAML: pp.printClientObjects(clientObjects, format) - case utils.OutputFormatTable: + case utils.OutputFormatTable, utils.OutputFormatWide: pp.printCRDsTable(sortedPolicyCRDs) default: fmt.Fprintf(os.Stderr, "unknown output format '%s' found\n", format) diff --git a/gwctl/pkg/printer/printer.go b/gwctl/pkg/printer/printer.go index ca7dbef254..9f56c64c57 100644 --- a/gwctl/pkg/printer/printer.go +++ b/gwctl/pkg/printer/printer.go @@ -32,13 +32,15 @@ import ( type Printer interface { io.Writer GetPrintableNodes(resourceModel *resourcediscovery.ResourceModel) []NodeResource - PrintTable(resourceModel *resourcediscovery.ResourceModel) + PrintTable(resourceModel *resourcediscovery.ResourceModel, wide bool) } func Print(p Printer, resourceModel *resourcediscovery.ResourceModel, format utils.OutputFormat) { switch format { case utils.OutputFormatTable: - p.PrintTable(resourceModel) + p.PrintTable(resourceModel, false) + case utils.OutputFormatWide: + p.PrintTable(resourceModel, true) case utils.OutputFormatJSON, utils.OutputFormatYAML: nodes := SortByString(p.GetPrintableNodes(resourceModel)) clientObjects := ClientObjects(nodes) diff --git a/gwctl/pkg/utils/types.go b/gwctl/pkg/utils/types.go index 74423d5ac6..4ca85cc0fb 100644 --- a/gwctl/pkg/utils/types.go +++ b/gwctl/pkg/utils/types.go @@ -100,6 +100,7 @@ func MustPolicyManagerForTest(t *testing.T, fakeClients *common.K8sClients) *pol type OutputFormat string const ( + OutputFormatWide OutputFormat = "wide" OutputFormatJSON OutputFormat = "json" OutputFormatYAML OutputFormat = "yaml" OutputFormatTable OutputFormat = "" @@ -107,6 +108,8 @@ const ( func ValidateAndReturnOutputFormat(format string) (OutputFormat, error) { switch format { + case "wide": + return OutputFormatWide, nil case "json": return OutputFormatJSON, nil case "yaml":