Skip to content

Commit

Permalink
feat: Enabled VRF routes in metal-cli (#425)
Browse files Browse the repository at this point in the history
## What issues it address?

#414

- Enabled VRF routes in Metal-cli.
- Improved metal gateways to support Vrf gateway inputs.

Co-authored-by: codinja1188 <[email protected]>
  • Loading branch information
codinja1188 and codinja1188 authored Jan 30, 2024
1 parent 9576704 commit 36f4f5e
Show file tree
Hide file tree
Showing 17 changed files with 770 additions and 35 deletions.
4 changes: 4 additions & 0 deletions docs/metal_vrf.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ VRF operations : It defines a collection of customer-managed IP blocks that can

* [metal](metal.md) - Command line interface for Equinix Metal
* [metal vrf create](metal_vrf_create.md) - Creates a Virtual Routing and Forwarding(VRF) for a specified project.
* [metal vrf create-route](metal_vrf_create-route.md) - Create a route in a VRF. Currently only static default routes are supported.
* [metal vrf delete](metal_vrf_delete.md) - Deletes a VRF.
* [metal vrf delete-route](metal_vrf_delete-route.md) - Delete a VRF Route
* [metal vrf get](metal_vrf_get.md) - Lists VRFs.
* [metal vrf get-route](metal_vrf_get-route.md) - Retrieve all routes in the VRF
* [metal vrf ips](metal_vrf_ips.md) - Retrieves the list of VRF IP Reservations for the VRF.
* [metal vrf update-route](metal_vrf_update-route.md) - Requests a VRF Route be redeployed/update across the network.

49 changes: 49 additions & 0 deletions docs/metal_vrf_create-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## metal vrf create-route

Create a route in a VRF. Currently only static default routes are supported.

### Synopsis

Create a route in a VRF. Currently only static default routes are supported.

```
metal vrf create-route [-i <VrfId>] [-p <Prefix>] [-n NextHop] [-t <tags> ] [flags]
```

### Examples

```
# Create a route in a VRF. Currently only static default routes are supported..
metal vrf create-route [-i <VrfID>] [-p <prefix>] [-n nextHop] [-t <tags> ]
```

### Options

```
-h, --help help for create-route
-i, --id string Specify the VRF UUID activate route configurations
-n, --nextHop string The IPv4 address within the VRF of the host that will handle this route
-p, --prefix string The IPv4 prefix for the route, in CIDR-style notation. For a static default route, this will always be '0.0.0.0/0'
-t, --tags strings Adds the tags for the connection --tags="tag1,tag2".
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete

2 changes: 1 addition & 1 deletion docs/metal_vrf_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-
-m, --metro string The UUID (or metro code) for the Metro in which to create this Virtual Routing and Forwarding
-n, --name string Name of the Virtual Routing and Forwarding
-p, --project-id string The project's UUID. This flag is required, unless specified in the config created by metal init or set as METAL_PROJECT_ID environment variable.
-t, --tags strings Adds or updates the tags for the connection --tags="tag1,tag2".
-t, --tags strings Adds the tags for the virtual-circuit --tags "tag1,tag2" OR --tags "tag1" --tags "tag2"
```

### Options inherited from parent commands
Expand Down
51 changes: 51 additions & 0 deletions docs/metal_vrf_delete-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## metal vrf delete-route

Delete a VRF Route

### Synopsis

Delete a VRF Route

```
metal vrf delete-route [-i <VrfRoute-Id>] [flags]
```

### Examples

```
#Delete a VRF Route
metal vrf delete-route -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
>
✔ Are you sure you want to delete device 7ec86e23-8dcf-48ed-bd9b-c25c20958277 [Y/N]: y
# Deletes a VRF, skipping confirmation.
metal vrf delete-route -f -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
```

### Options

```
-f, --force Skips confirmation for the removal of the VRF routes.
-h, --help help for delete-route
-i, --id string Specify the VRF UUID to delete the associated route configurations.
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete

46 changes: 46 additions & 0 deletions docs/metal_vrf_get-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## metal vrf get-route

Retrieve all routes in the VRF

### Synopsis

Retrieve all routes in the VRF

```
metal vrf get-route [-i <VrfRoute-Id>] [flags]
```

### Examples

```
#Retrieve all routes in the VRF
# Retrieve all routes in the VRF
metal vrf get-route -i bb526d47-8536-483c-b436-116a5fb72235
```

### Options

```
-h, --help help for get-route
-i, --id string Specify the VRF UUID to list its associated routes configurations
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete

49 changes: 49 additions & 0 deletions docs/metal_vrf_update-route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## metal vrf update-route

Requests a VRF Route be redeployed/update across the network.

### Synopsis

Requests a VRF Route be redeployed/update across the network.

```
metal vrf update-route [-i <VrfRoute-Id>] [-p <Prefix>] [-n NextHop] [-t <tags> ] [flags]
```

### Examples

```
#Requests a VRF Route be redeployed/update across the network.
metal vrf update-route [-i <VrfID>] [-p <prefix>] [-n nextHop] [-t <tags> ]
```

### Options

```
-h, --help help for update-route
-i, --id string Specify the VRF UUID to update the associated route configurations.
-n, --nextHop string Name of the Virtual Routing and Forwarding
-p, --prefix string The IPv4 prefix for the route, in CIDR-style notation. For a static default route, this will always be '0.0.0.0/0'
-t, --tags strings updates the tags for the Virtual Routing and Forwarding --tags "tag1,tag2" OR --tags "tag1" --tags "tag2" (NOTE: --tags "" will remove all tags from the Virtual Routing and Forwarding
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete

58 changes: 37 additions & 21 deletions internal/gateway/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import (
)

func (c *Client) Create() *cobra.Command {
var projectID, vnID, reservationID string
var netSize int32
var (
projectID string
vnID string
reservationID string
netSize int32
)

// createMetalGatewayCmd represents the createMetalGateway command
createMetalGatewayCmd := &cobra.Command{
Expand All @@ -48,35 +52,49 @@ func (c *Client) Create() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
includes := []string{"virtual_network", "ip_reservation"}

var req metal.CreateMetalGatewayRequest
if reservationID == "" && netSize == 0 {
return errors.New("Invalid input. Provide either 'private-subnet-size' or 'ip-reservation-id'")
}

req := metal.CreateMetalGatewayRequest{
MetalGatewayCreateInput: &metal.MetalGatewayCreateInput{
VirtualNetworkId: vnID,
},
}
if reservationID != "" {
req.MetalGatewayCreateInput.SetIpReservationId(reservationID)
if reservationID != "" && vnID != "" || netSize == 0 {
req = metal.CreateMetalGatewayRequest{
VrfMetalGatewayCreateInput: &metal.VrfMetalGatewayCreateInput{
VirtualNetworkId: vnID,
IpReservationId: reservationID,
},
}
} else {
req.MetalGatewayCreateInput.SetPrivateIpv4SubnetSize(netSize)
req = metal.CreateMetalGatewayRequest{
MetalGatewayCreateInput: &metal.MetalGatewayCreateInput{
VirtualNetworkId: vnID,
},
}
if reservationID != "" {
req.MetalGatewayCreateInput.SetIpReservationId(reservationID)
} else {
req.MetalGatewayCreateInput.SetPrivateIpv4SubnetSize(netSize)
}
}

n, _, err := c.Service.
CreateMetalGateway(context.Background(), projectID).
Include(c.Servicer.Includes(includes)).
Exclude(c.Servicer.Excludes(nil)).
CreateMetalGatewayRequest(req).
Execute()
n, _, err := c.Service.CreateMetalGateway(context.Background(), projectID).CreateMetalGatewayRequest(req).Include(c.Servicer.Includes(includes)).Exclude(c.Servicer.Excludes(nil)).Execute()
if err != nil {
return fmt.Errorf("Could not create Metal Gateway: %w", err)
return fmt.Errorf("could not create Metal Gateway: %w", err)
}

data := make([][]string, 1)
address := ""
header := []string{"ID", "Metro", "VXLAN", "Addresses", "State", "Created"}

if reservationID != "" && vnID != "" || netSize == 0 {
vrfGway := n.VrfMetalGateway
ipReservation := vrfGway.IpReservation
if ipReservation != nil {
address = ipReservation.GetAddress() + "/" + strconv.Itoa(int(ipReservation.GetCidr()))
}
data[0] = []string{vrfGway.GetId(), vrfGway.VirtualNetwork.GetMetroCode(),
strconv.Itoa(int(vrfGway.VirtualNetwork.GetVxlan())), address, string(vrfGway.GetState()), vrfGway.GetCreatedAt().String()}
return c.Out.Output(vrfGway, header, &data)
}
gway := n.MetalGateway
ipReservation := gway.IpReservation
if ipReservation != nil {
Expand All @@ -86,8 +104,6 @@ func (c *Client) Create() *cobra.Command {
data[0] = []string{gway.GetId(), gway.VirtualNetwork.GetMetroCode(),
strconv.Itoa(int(gway.VirtualNetwork.GetVxlan())), address, string(gway.GetState()), gway.GetCreatedAt().String()}

header := []string{"ID", "Metro", "VXLAN", "Addresses", "State", "Created"}

return c.Out.Output(gway, header, &data)
},
}
Expand Down
2 changes: 1 addition & 1 deletion internal/vrf/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (c *Client) Create() *cobra.Command {
}

createVRFCmd.Flags().StringVarP(&projectID, "project-id", "p", "", "The project's UUID. This flag is required, unless specified in the config created by metal init or set as METAL_PROJECT_ID environment variable.")
createVRFCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds or updates the tags for the connection --tags="tag1,tag2".`)
createVRFCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds the tags for the virtual-circuit --tags "tag1,tag2" OR --tags "tag1" --tags "tag2"`)
createVRFCmd.Flags().StringVarP(&name, "name", "n", "", "Name of the Virtual Routing and Forwarding")
createVRFCmd.Flags().StringVarP(&description, "description", "d", "", "Description of the Virtual Routing and Forwarding.")

Expand Down
65 changes: 65 additions & 0 deletions internal/vrf/createroute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package vrf

import (
"context"
"fmt"

"github.com/equinix/equinix-sdk-go/services/metalv1"
"github.com/spf13/cobra"
)

func (c *Client) CreateRoute() *cobra.Command {
var (
vrfID string
prefix string
nextHop string
tags []string
)

// CreateVrfRouteCmd represents the CreateVrfRouteCmd command
createRouteCmd := &cobra.Command{
Use: "create-route [-i <VrfId>] [-p <Prefix>] [-n NextHop] [-t <tags> ]",
Aliases: []string{"route"},
Short: "Create a route in a VRF. Currently only static default routes are supported.",
Long: "Create a route in a VRF. Currently only static default routes are supported.",
Example: ` # Create a route in a VRF. Currently only static default routes are supported..
metal vrf create-route [-i <VrfID>] [-p <prefix>] [-n nextHop] [-t <tags> ]`,
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
inc := []string{}
exc := []string{}

vrfRouteCreateInput := metalv1.VrfRouteCreateInput{
Prefix: prefix,
NextHop: nextHop,
Tags: tags,
}

vrfRoute, _, err := c.Service.CreateVrfRoute(context.Background(), vrfID).VrfRouteCreateInput(vrfRouteCreateInput).Include(c.Servicer.Includes(inc)).Exclude(c.Servicer.Excludes(exc)).Execute()
if err != nil {
return fmt.Errorf("could not create VrfRoute: %w", err)
}

data := make([][]string, 1)

// This output block below is probably incorrect but leaving it for now for testing later.
data[0] = []string{vrfRoute.GetId(), string(vrfRoute.GetType()), vrfRoute.GetPrefix(), vrfRoute.GetNextHop(), vrfRoute.CreatedAt.String()}
header := []string{"ID", "Type", "Prefix", "NextHop", "Created"}

return c.Out.Output(vrfRoute, header, &data)
},
}

createRouteCmd.Flags().StringVarP(&vrfID, "id", "i", "", "Specify the VRF UUID activate route configurations")
createRouteCmd.Flags().StringVarP(&prefix, "prefix", "p", "", "The IPv4 prefix for the route, in CIDR-style notation. For a static default route, this will always be '0.0.0.0/0'")
createRouteCmd.Flags().StringVarP(&nextHop, "nextHop", "n", "", "The IPv4 address within the VRF of the host that will handle this route")
createRouteCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds the tags for the connection --tags="tag1,tag2".`)

// making them all required here
_ = createRouteCmd.MarkFlagRequired("id")
_ = createRouteCmd.MarkFlagRequired("prefix")
_ = createRouteCmd.MarkFlagRequired("nextHop")

return createRouteCmd
}
Loading

0 comments on commit 36f4f5e

Please sign in to comment.