Skip to content

Commit

Permalink
feat: VRF support (#377)
Browse files Browse the repository at this point in the history
Fixes #268
  • Loading branch information
displague authored Nov 16, 2023
2 parents 54a34f3 + 4c7779e commit 3a48a02
Show file tree
Hide file tree
Showing 11 changed files with 467 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/equinix/metal-cli/internal/twofa"
"github.com/equinix/metal-cli/internal/users"
"github.com/equinix/metal-cli/internal/vlan"
"github.com/equinix/metal-cli/internal/vrf"
)

// Cli struct
Expand Down Expand Up @@ -95,5 +96,6 @@ func (cli *Cli) RegisterCommands(client *root.Client) {
gateway.NewClient(client, cli.Outputer).NewCommand(),
ports.NewClient(client, cli.Outputer).NewCommand(),
interconnections.NewClient(client, cli.Outputer).NewCommand(),
vrf.NewClient(client, cli.Outputer).NewCommand(),
)
}
1 change: 1 addition & 0 deletions docs/metal.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ Command line interface for Equinix Metal
* [metal ssh-key](metal_ssh-key.md) - SSH key operations: create, get, update, and delete.
* [metal user](metal_user.md) - User operations: get and add.
* [metal virtual-network](metal_virtual-network.md) - Virtual network (VLAN) operations : create, get, delete.
* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete

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

VRF operations : create, get, delete

### Synopsis

VRF operations : It defines a collection of customer-managed IP blocks that can be used in BGP peering on one or more virtual networks and basic operations

### Options

```
-h, --help help for vrf
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file
--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](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 delete](metal_vrf_delete.md) - Deletes a VRF.
* [metal vrf get](metal_vrf_get.md) - Lists VRFs.

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

Creates a Virtual Routing and Forwarding(VRF) for a specified project.

### Synopsis

Creates a Creates a Virtual Routing and Forwarding(VRF) for a specified project.

```
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <IPranges>] [-t <tags> ] [flags]
```

### Examples

```
# Creates an Creates a Virtual Routing and Forwarding(VRF) for a specified project.
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <ipranges>] [-t <tags> ]
```

### Options

```
-d, --description string Description of the Virtual Routing and Forwarding.
-h, --help help for create
-r, --ipranges strings A list of CIDR network addresses. Like [10.0.0.0/16, 2001:d78::/56]. IPv4 blocks must be between /8 and /29 in size. IPv6 blocks must be between /56 and /64.
-a, --local-asn int32 Local ASN for the VRF
-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".
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file
--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

51 changes: 51 additions & 0 deletions docs/metal_vrf_delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## metal vrf delete

Deletes a VRF.

### Synopsis

Deletes the specified VRF with a confirmation prompt. To skip the confirmation, use --force.

```
metal vrf delete vrf -i <metal_vrf_UUID> [-f] [flags]
```

### Examples

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

### Options

```
-f, --force Skips confirmation for the removal of the VRF.
-h, --help help for delete
-i, --id string UUID of the VRF.
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file
--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

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

Lists VRFs.

### Synopsis

Retrieves a list of all VRFs for the specified project or the details of the specified VRF ID. Either a project ID or a VRF ID is required.

```
metal vrf get -p <project_Id> [flags]
```

### Examples

```
# Gets the details of the specified device
metal vrf get -i 3b0795ba-ec9a-4a9e-83a7-043e7e11407c
# Lists VRFs for project 3b0795ba-ec9a-4a9e-83a7-043e7e11407c:
metal vrf list -p 3b0795ba-ec9a-4a9e-83a7-043e7e11407c
```

### Options

```
-h, --help help for get
-m, --metro string Filter by Metro ID (uuid) or Metro Code
-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.
-v, --vrfID string VRF UUID
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file
--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

4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -410,6 +412,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
77 changes: 77 additions & 0 deletions internal/vrf/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package vrf

import (
"context"
"fmt"
"strconv"
"strings"

metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/spf13/cobra"
)

func (c *Client) Create() *cobra.Command {
var (
projectID string
metro string
name string
description string
ipRanges []string
localASN int32
tags []string
)

// createVRFCmd represents the creatVRF command
createVRFCmd := &cobra.Command{
Use: "create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <IPranges>] [-t <tags> ]",
Short: "Creates a Virtual Routing and Forwarding(VRF) for a specified project.",
Long: "Creates a Creates a Virtual Routing and Forwarding(VRF) for a specified project.",
Example: ` # Creates an Creates a Virtual Routing and Forwarding(VRF) for a specified project.
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <ipranges>] [-t <tags> ]`,
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

req := metal.VrfCreateInput{
Metro: metro,
Name: name,
IpRanges: ipRanges,
LocalAsn: &localASN,
Tags: tags,
Description: &description,
}

inc := []string{}
exc := []string{}
vrfRequest, _, err := c.Service.CreateVrf(context.Background(), projectID).VrfCreateInput(req).Exclude(c.Servicer.Excludes(exc)).Include(c.Servicer.Includes(inc)).Execute()
if err != nil {
return fmt.Errorf("could not create VRF: %w", err)
}

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

// This output block below is probably incorrect but leaving it for now for testing later.
data[0] = []string{vrfRequest.GetName(), vrfRequest.GetDescription(), strconv.Itoa(int(vrfRequest.GetLocalAsn())), strings.Join(vrfRequest.GetIpRanges(), ","), vrfRequest.GetCreatedAt().String()}
header := []string{"ID", "Name", "Description", "LocalASN", "IPranges", "Created"}

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

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().StringVarP(&name, "name", "n", "", "Name of the Virtual Routing and Forwarding")
createVRFCmd.Flags().StringVarP(&description, "description", "d", "", "Description of the Virtual Routing and Forwarding.")

createVRFCmd.Flags().StringVarP(&metro, "metro", "m", "", "The UUID (or metro code) for the Metro in which to create this Virtual Routing and Forwarding")
createVRFCmd.Flags().Int32VarP(&localASN, "local-asn", "a", 0, "Local ASN for the VRF")
createVRFCmd.Flags().StringSliceVarP(&ipRanges, "ipranges", "r", []string{}, "A list of CIDR network addresses. Like [10.0.0.0/16, 2001:d78::/56]. IPv4 blocks must be between /8 and /29 in size. IPv6 blocks must be between /56 and /64.")

// making them all required here
_ = createVRFCmd.MarkFlagRequired("name")
_ = createVRFCmd.MarkFlagRequired("metro")
_ = createVRFCmd.MarkFlagRequired("local-asn")
_ = createVRFCmd.MarkFlagRequired("ipranges")

return createVRFCmd
}
67 changes: 67 additions & 0 deletions internal/vrf/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package vrf

import (
"context"
"fmt"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

func (c *Client) Delete() *cobra.Command {
var (
vrfID string
force bool
)

deleteVrf := func(id string) error {
_, err := c.Service.DeleteVrf(context.Background(), id).Execute()
if err != nil {
return err
}
fmt.Println("VRF", id, "successfully deleted.")
fmt.Println("VRF deletion initiated. Please check 'metal vrf get -i", vrfID, "' for status")
return nil // No need to return 'err' here; it's always nil.
}

deleteVrfCmd := &cobra.Command{
Use: "delete vrf -i <metal_vrf_UUID> [-f]",
Short: "Deletes a VRF.",
Long: "Deletes the specified VRF with a confirmation prompt. To skip the confirmation, use --force.",
Example: `# Deletes a VRF, with confirmation.
metal delete vrf -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
>
✔ Are you sure you want to delete device 7ec86e23-8dcf-48ed-bd9b-c25c20958277: y
# Deletes a VRF, skipping confirmation.
metal delete vrf -f -i 77e6d57a-d7a4-4816-b451-cf9b043444e2`,
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

if !force {
prompt := promptui.Prompt{
Label: fmt.Sprintf("Are you sure you want to delete VRF %s: ", vrfID),
IsConfirm: true,
}

result, err := prompt.Run()
if err != nil || result != "y" {
return nil
}
}

if err := deleteVrf(vrfID); err != nil {
return fmt.Errorf("could not delete VRF: %w", err)
}

return nil
},
}

deleteVrfCmd.Flags().StringVarP(&vrfID, "id", "i", "", "UUID of the VRF.")
deleteVrfCmd.Flags().BoolVarP(&force, "force", "f", false, "Skips confirmation for the removal of the VRF.")

_ = deleteVrfCmd.MarkFlagRequired("id")

return deleteVrfCmd
}
Loading

0 comments on commit 3a48a02

Please sign in to comment.