Skip to content

Commit

Permalink
Implement gwctl get gateways
Browse files Browse the repository at this point in the history
Signed-off-by: Jongwoo Han <jongwooo.han@gmail.com>
  • Loading branch information
jongwooo committed Feb 20, 2024
1 parent 1bd3124 commit e6b9101
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 7 deletions.
22 changes: 17 additions & 5 deletions gwctl/pkg/cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewGetCommand(params *utils.CmdParams) *cobra.Command {
flags := &getFlags{}

cmd := &cobra.Command{
Use: "get {policies|policycrds|httproutes}",
Use: "get {gateways|policies|policycrds|httproutes}",
Short: "Display one or many resources",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -56,10 +56,26 @@ func runGet(args []string, params *utils.CmdParams, flags *getFlags) {
ns = ""
}

discoverer := resourcediscovery.Discoverer{
K8sClients: params.K8sClients,
PolicyManager: params.PolicyManager,
}
gwPrinter := &printer.GatewaysPrinter{Out: params.Out}
policiesPrinter := &printer.PoliciesPrinter{Out: params.Out}
httpRoutesPrinter := &printer.HTTPRoutesPrinter{Out: params.Out}

switch kind {
case "gateway", "gateways":
filter := resourcediscovery.Filter{Namespace: ns}
if len(args) > 1 {
filter.Name = args[1]
}
resourceModel, err := discoverer.DiscoverResourcesForGateway(filter)
if err != nil {
panic(err)
}
gwPrinter.Print(resourceModel)

case "policy", "policies":
list := params.PolicyManager.GetPolicies()
policiesPrinter.Print(list)
Expand All @@ -69,10 +85,6 @@ func runGet(args []string, params *utils.CmdParams, flags *getFlags) {
policiesPrinter.PrintCRDs(list)

case "httproute", "httproutes":
discoverer := resourcediscovery.Discoverer{
K8sClients: params.K8sClients,
PolicyManager: params.PolicyManager,
}
filter := resourcediscovery.Filter{Namespace: ns}
if len(args) > 1 {
filter.Name = args[1]
Expand Down
50 changes: 50 additions & 0 deletions gwctl/pkg/printer/gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ package printer
import (
"fmt"
"io"
"strconv"
"strings"
"text/tabwriter"
"time"

"sigs.k8s.io/yaml"

"sigs.k8s.io/gateway-api/gwctl/pkg/policymanager"
"sigs.k8s.io/gateway-api/gwctl/pkg/resourcediscovery"

"k8s.io/apimachinery/pkg/util/duration"
)

type GatewaysPrinter struct {
Expand All @@ -40,6 +46,50 @@ type gatewayDescribeView struct {
EffectivePolicies map[policymanager.PolicyCrdID]policymanager.Policy `json:",omitempty"`
}

func (gp *GatewaysPrinter) Print(resourceModel *resourcediscovery.ResourceModel) {
tw := tabwriter.NewWriter(gp.Out, 0, 0, 2, ' ', 0)
row := []string{"NAME", "CLASS", "ADDRESSES", "PORTS", "PROGRAMMED", "AGE"}
tw.Write([]byte(strings.Join(row, "\t") + "\n"))

for _, gatewayNode := range resourceModel.Gateways {
var addresses []string
for _, address := range gatewayNode.Gateway.Status.Addresses {
addresses = append(addresses, address.Value)
}
addressesOutput := strings.Join(addresses, ",")
if cnt := len(addresses); cnt > 2 {
addressesOutput = fmt.Sprintf("%v + %v more", strings.Join(addresses[:2], ","), cnt-2)
}

var ports []string
for _, listener := range gatewayNode.Gateway.Spec.Listeners {
ports = append(ports, strconv.Itoa(int(listener.Port)))
}
portsOutput := strings.Join(ports, ",")

programmedStatus := "Unknown"
for _, condition := range gatewayNode.Gateway.Status.Conditions {
if condition.Type == "Programmed" {
programmedStatus = string(condition.Status)
break
}
}

age := duration.HumanDuration(time.Since(gatewayNode.Gateway.GetCreationTimestamp().Time))

row := []string{
gatewayNode.Gateway.GetName(),
string(gatewayNode.Gateway.Spec.GatewayClassName),
addressesOutput,
portsOutput,
programmedStatus,
age,
}
tw.Write([]byte(strings.Join(row, "\t") + "\n"))
}
tw.Flush()
}

func (gp *GatewaysPrinter) PrintDescribeView(resourceModel *resourcediscovery.ResourceModel) {
index := 0
for _, gatewayNode := range resourceModel.Gateways {
Expand Down
77 changes: 75 additions & 2 deletions gwctl/pkg/printer/gateways_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,93 @@ package printer
import (
"bytes"
"testing"
"time"

gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"

"github.com/google/go-cmp/cmp"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"

"sigs.k8s.io/gateway-api/gwctl/pkg/cmd/utils"
"sigs.k8s.io/gateway-api/gwctl/pkg/common"
"sigs.k8s.io/gateway-api/gwctl/pkg/resourcediscovery"
)

func TestGatewaysPrinter_Print(t *testing.T) {
objects := []runtime.Object{
&gatewayv1.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: "foo-gatewayclass",
},
Spec: gatewayv1.GatewayClassSpec{
ControllerName: "example.net/gateway-controller",
Description: common.PtrTo("random"),
},
},

&gatewayv1.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "foo-gateway",
CreationTimestamp: metav1.Time{
Time: time.Now().Add(-time.Second),
},
},
Spec: gatewayv1.GatewaySpec{
GatewayClassName: "foo-gatewayclass",
Listeners: []gatewayv1.Listener{
{
Name: gatewayv1.SectionName("http-1"),
Protocol: gatewayv1.HTTPProtocolType,
Port: gatewayv1.PortNumber(80),
},
},
},
Status: gatewayv1.GatewayStatus{
Addresses: []gatewayv1.GatewayStatusAddress{
{
Value: "10.0.0.1",
},
},
Conditions: []metav1.Condition{
{
Type: "Programmed",
Status: metav1.ConditionTrue,
},
},
},
},
}

params := utils.MustParamsForTest(t, common.MustClientsForTest(t, objects...))
discoverer := resourcediscovery.Discoverer{
K8sClients: params.K8sClients,
PolicyManager: params.PolicyManager,
}
resourceModel, err := discoverer.DiscoverResourcesForGateway(resourcediscovery.Filter{})
if err != nil {
t.Fatalf("Failed to construct resourceModel: %v", resourceModel)
}

gp := &GatewaysPrinter{
Out: params.Out,
}
gp.Print(resourceModel)

got := params.Out.(*bytes.Buffer).String()
want := `
NAME CLASS ADDRESSES PORTS PROGRAMMED AGE
foo-gateway foo-gatewayclass 10.0.0.1 80 True 1s
`

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)
}
}

func TestGatewaysPrinter_PrintDescribeView(t *testing.T) {
objects := []runtime.Object{
&gatewayv1.GatewayClass{
Expand Down

0 comments on commit e6b9101

Please sign in to comment.