diff --git a/internal/gateway/retrieve.go b/internal/gateway/retrieve.go index 6a9a0bdf..8d9e775f 100644 --- a/internal/gateway/retrieve.go +++ b/internal/gateway/retrieve.go @@ -24,12 +24,67 @@ import ( "context" "fmt" "strconv" + "time" metal "github.com/equinix/equinix-sdk-go/services/metalv1" "github.com/spf13/cobra" ) +type ipreservationIsh interface { + GetAddress() string + GetCidr() int32 +} + +var ( + _ ipreservationIsh = (*metal.VrfIpReservation)(nil) + _ ipreservationIsh = (*metal.IPReservation)(nil) +) + +type gatewayIsh interface { + GetId() string + GetCreatedAt() time.Time + GetState() metal.MetalGatewayState + GetVirtualNetwork() metal.VirtualNetwork + GetIpReservation() ipreservationIsh + GatewayType() string +} + +var ( + _ gatewayIsh = (*metalGatewayWrapper)(nil) // todo: this doesn't work, the GetIpReservation in each type returns a concrete type, not the ipreservationIsh interface + _ gatewayIsh = (*vrfMetalGatewayWrapper)(nil) +) + +type metalGatewayWrapper struct { + *metal.MetalGateway +} + +func (m metalGatewayWrapper) GetIpReservation() ipreservationIsh { + if m.MetalGateway.IpReservation == nil { + return nil + } + return m.MetalGateway.IpReservation +} + +func (m metalGatewayWrapper) GatewayType() string { + return "MetalGateway" +} + +type vrfMetalGatewayWrapper struct { + *metal.VrfMetalGateway +} + +func (v vrfMetalGatewayWrapper) GetIpReservation() ipreservationIsh { + if v.VrfMetalGateway.IpReservation == nil { + return nil + } + return v.VrfMetalGateway.IpReservation +} + +func (v vrfMetalGatewayWrapper) GatewayType() string { + return "VrfMetalGateway" +} + func (c *Client) Retrieve() *cobra.Command { var projectID string @@ -58,26 +113,45 @@ func (c *Client) Retrieve() *cobra.Command { gways := gwayList.GetMetalGateways() - data := make([][]string, len(gways)) - metalGways := make([]*metal.MetalGateway, len(gways)) + data := make([][]string, 0, len(gways)) + var gateways []gatewayIsh + + for _, gwaysInner := range gways { + var gway gatewayIsh + if gwaysInner.MetalGateway != nil { + gway = metalGatewayWrapper{gwaysInner.MetalGateway} + } else if gwaysInner.VrfMetalGateway != nil { + gway = vrfMetalGatewayWrapper{gwaysInner.VrfMetalGateway} + } else { + continue // Skip if neither type is present + } - for i, n := range gways { - gway := n.MetalGateway - metalGways = append(metalGways, gway) + gateways = append(gateways, gway) address := "" - - ipReservation := gway.IpReservation + ipReservation := gway.GetIpReservation() if ipReservation != nil { address = ipReservation.GetAddress() + "/" + strconv.Itoa(int(ipReservation.GetCidr())) } - data[i] = []string{gway.GetId(), gway.VirtualNetwork.GetMetroCode(), strconv.Itoa(int(gway.VirtualNetwork.GetVxlan())), - address, string(gway.GetState()), gway.GetCreatedAt().String()} + vnet := gway.GetVirtualNetwork() + metroCode := vnet.GetMetroCode() + vxlan := strconv.Itoa(int(vnet.GetVxlan())) + + data = append(data, []string{ + gway.GetId(), + metroCode, + vxlan, + address, + string(gway.GetState()), + gway.GetCreatedAt().String(), + gway.GatewayType(), + }) } - header := []string{"ID", "Metro", "VXLAN", "Addresses", "State", "Created"} - return c.Out.Output(metalGways, header, &data) + header := []string{"ID", "Metro", "VXLAN", "Addresses", "State", "Created", "Type"} + + return c.Out.Output(gateways, header, &data) }, }