Skip to content

Commit 67a8690

Browse files
irusoeqxdisplague
authored andcommitted
feat: VRF support
1 parent 54a34f3 commit 67a8690

11 files changed

+467
-0
lines changed

cmd/cli.go

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/equinix/metal-cli/internal/twofa"
2929
"github.com/equinix/metal-cli/internal/users"
3030
"github.com/equinix/metal-cli/internal/vlan"
31+
"github.com/equinix/metal-cli/internal/vrf"
3132
)
3233

3334
// Cli struct
@@ -95,5 +96,6 @@ func (cli *Cli) RegisterCommands(client *root.Client) {
9596
gateway.NewClient(client, cli.Outputer).NewCommand(),
9697
ports.NewClient(client, cli.Outputer).NewCommand(),
9798
interconnections.NewClient(client, cli.Outputer).NewCommand(),
99+
vrf.NewClient(client, cli.Outputer).NewCommand(),
98100
)
99101
}

docs/metal.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ Command line interface for Equinix Metal
4747
* [metal ssh-key](metal_ssh-key.md) - SSH key operations: create, get, update, and delete.
4848
* [metal user](metal_user.md) - User operations: get and add.
4949
* [metal virtual-network](metal_virtual-network.md) - Virtual network (VLAN) operations : create, get, delete.
50+
* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete
5051

docs/metal_vrf.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
## metal vrf
2+
3+
VRF operations : create, get, delete
4+
5+
### Synopsis
6+
7+
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
8+
9+
### Options
10+
11+
```
12+
-h, --help help for vrf
13+
```
14+
15+
### Options inherited from parent commands
16+
17+
```
18+
--config string Path to JSON or YAML configuration file
19+
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
20+
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
21+
--http-header strings Headers to add to requests (in format key=value)
22+
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
23+
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
24+
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
25+
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
26+
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
27+
--token string Metal API Token (METAL_AUTH_TOKEN)
28+
```
29+
30+
### SEE ALSO
31+
32+
* [metal](metal.md) - Command line interface for Equinix Metal
33+
* [metal vrf create](metal_vrf_create.md) - Creates a Virtual Routing and Forwarding(VRF) for a specified project.
34+
* [metal vrf delete](metal_vrf_delete.md) - Deletes a VRF.
35+
* [metal vrf get](metal_vrf_get.md) - Lists VRFs.
36+

docs/metal_vrf_create.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## metal vrf create
2+
3+
Creates a Virtual Routing and Forwarding(VRF) for a specified project.
4+
5+
### Synopsis
6+
7+
Creates a Creates a Virtual Routing and Forwarding(VRF) for a specified project.
8+
9+
```
10+
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <IPranges>] [-t <tags> ] [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
# Creates an Creates a Virtual Routing and Forwarding(VRF) for a specified project.
17+
18+
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <ipranges>] [-t <tags> ]
19+
```
20+
21+
### Options
22+
23+
```
24+
-d, --description string Description of the Virtual Routing and Forwarding.
25+
-h, --help help for create
26+
-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.
27+
-a, --local-asn int32 Local ASN for the VRF
28+
-m, --metro string The UUID (or metro code) for the Metro in which to create this Virtual Routing and Forwarding
29+
-n, --name string Name of the Virtual Routing and Forwarding
30+
-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.
31+
-t, --tags strings Adds or updates the tags for the connection --tags="tag1,tag2".
32+
```
33+
34+
### Options inherited from parent commands
35+
36+
```
37+
--config string Path to JSON or YAML configuration file
38+
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
39+
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
40+
--http-header strings Headers to add to requests (in format key=value)
41+
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
42+
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
43+
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
44+
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
45+
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
46+
--token string Metal API Token (METAL_AUTH_TOKEN)
47+
```
48+
49+
### SEE ALSO
50+
51+
* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete
52+

docs/metal_vrf_delete.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## metal vrf delete
2+
3+
Deletes a VRF.
4+
5+
### Synopsis
6+
7+
Deletes the specified VRF with a confirmation prompt. To skip the confirmation, use --force.
8+
9+
```
10+
metal vrf delete vrf -i <metal_vrf_UUID> [-f] [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
# Deletes a VRF, with confirmation.
17+
metal delete vrf -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
18+
>
19+
✔ Are you sure you want to delete device 7ec86e23-8dcf-48ed-bd9b-c25c20958277: y
20+
21+
# Deletes a VRF, skipping confirmation.
22+
metal delete vrf -f -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
23+
```
24+
25+
### Options
26+
27+
```
28+
-f, --force Skips confirmation for the removal of the VRF.
29+
-h, --help help for delete
30+
-i, --id string UUID of the VRF.
31+
```
32+
33+
### Options inherited from parent commands
34+
35+
```
36+
--config string Path to JSON or YAML configuration file
37+
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
38+
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
39+
--http-header strings Headers to add to requests (in format key=value)
40+
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
41+
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
42+
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
43+
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
44+
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
45+
--token string Metal API Token (METAL_AUTH_TOKEN)
46+
```
47+
48+
### SEE ALSO
49+
50+
* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete
51+

docs/metal_vrf_get.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
## metal vrf get
2+
3+
Lists VRFs.
4+
5+
### Synopsis
6+
7+
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.
8+
9+
```
10+
metal vrf get -p <project_Id> [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
# Gets the details of the specified device
17+
metal vrf get -i 3b0795ba-ec9a-4a9e-83a7-043e7e11407c
18+
19+
# Lists VRFs for project 3b0795ba-ec9a-4a9e-83a7-043e7e11407c:
20+
metal vrf list -p 3b0795ba-ec9a-4a9e-83a7-043e7e11407c
21+
```
22+
23+
### Options
24+
25+
```
26+
-h, --help help for get
27+
-m, --metro string Filter by Metro ID (uuid) or Metro Code
28+
-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.
29+
-v, --vrfID string VRF UUID
30+
```
31+
32+
### Options inherited from parent commands
33+
34+
```
35+
--config string Path to JSON or YAML configuration file
36+
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
37+
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
38+
--http-header strings Headers to add to requests (in format key=value)
39+
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
40+
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
41+
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
42+
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
43+
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
44+
--token string Metal API Token (METAL_AUTH_TOKEN)
45+
```
46+
47+
### SEE ALSO
48+
49+
* [metal vrf](metal_vrf.md) - VRF operations : create, get, delete
50+

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
257257
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
258258
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
259259
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
260+
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
261+
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
260262
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
261263
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
262264
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -410,6 +412,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
410412
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
411413
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
412414
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
415+
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
416+
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
413417
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
414418
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
415419
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

internal/vrf/create.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package vrf
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
9+
metal "github.com/equinix-labs/metal-go/metal/v1"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
func (c *Client) Create() *cobra.Command {
14+
var (
15+
projectID string
16+
metro string
17+
name string
18+
description string
19+
ipRanges []string
20+
localASN int32
21+
tags []string
22+
)
23+
24+
// createVRFCmd represents the creatVRF command
25+
createVRFCmd := &cobra.Command{
26+
Use: "create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <IPranges>] [-t <tags> ]",
27+
Short: "Creates a Virtual Routing and Forwarding(VRF) for a specified project.",
28+
Long: "Creates a Creates a Virtual Routing and Forwarding(VRF) for a specified project.",
29+
Example: ` # Creates an Creates a Virtual Routing and Forwarding(VRF) for a specified project.
30+
31+
metal vrf create [-p <project_id] [-d <description>] [-m <metro>] [-n <name>] [-a <localASN>] [-r <ipranges>] [-t <tags> ]`,
32+
RunE: func(cmd *cobra.Command, args []string) error {
33+
cmd.SilenceUsage = true
34+
35+
req := metal.VrfCreateInput{
36+
Metro: metro,
37+
Name: name,
38+
IpRanges: ipRanges,
39+
LocalAsn: &localASN,
40+
Tags: tags,
41+
Description: &description,
42+
}
43+
44+
inc := []string{}
45+
exc := []string{}
46+
vrfRequest, _, err := c.Service.CreateVrf(context.Background(), projectID).VrfCreateInput(req).Exclude(c.Servicer.Excludes(exc)).Include(c.Servicer.Includes(inc)).Execute()
47+
if err != nil {
48+
return fmt.Errorf("could not create VRF: %w", err)
49+
}
50+
51+
data := make([][]string, 1)
52+
53+
// This output block below is probably incorrect but leaving it for now for testing later.
54+
data[0] = []string{vrfRequest.GetName(), vrfRequest.GetDescription(), strconv.Itoa(int(vrfRequest.GetLocalAsn())), strings.Join(vrfRequest.GetIpRanges(), ","), vrfRequest.GetCreatedAt().String()}
55+
header := []string{"ID", "Name", "Description", "LocalASN", "IPranges", "Created"}
56+
57+
return c.Out.Output(vrfRequest, header, &data)
58+
},
59+
}
60+
61+
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.")
62+
createVRFCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds or updates the tags for the connection --tags="tag1,tag2".`)
63+
createVRFCmd.Flags().StringVarP(&name, "name", "n", "", "Name of the Virtual Routing and Forwarding")
64+
createVRFCmd.Flags().StringVarP(&description, "description", "d", "", "Description of the Virtual Routing and Forwarding.")
65+
66+
createVRFCmd.Flags().StringVarP(&metro, "metro", "m", "", "The UUID (or metro code) for the Metro in which to create this Virtual Routing and Forwarding")
67+
createVRFCmd.Flags().Int32VarP(&localASN, "local-asn", "a", 0, "Local ASN for the VRF")
68+
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.")
69+
70+
// making them all required here
71+
_ = createVRFCmd.MarkFlagRequired("name")
72+
_ = createVRFCmd.MarkFlagRequired("metro")
73+
_ = createVRFCmd.MarkFlagRequired("local-asn")
74+
_ = createVRFCmd.MarkFlagRequired("ipranges")
75+
76+
return createVRFCmd
77+
}

internal/vrf/delete.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package vrf
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/manifoldco/promptui"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func (c *Client) Delete() *cobra.Command {
12+
var (
13+
vrfID string
14+
force bool
15+
)
16+
17+
deleteVrf := func(id string) error {
18+
_, err := c.Service.DeleteVrf(context.Background(), id).Execute()
19+
if err != nil {
20+
return err
21+
}
22+
fmt.Println("VRF", id, "successfully deleted.")
23+
fmt.Println("Device deletion initiated. Please check 'metal vrf get -i", vrfID, "' for status")
24+
return nil // No need to return 'err' here; it's always nil.
25+
}
26+
27+
deleteVrfCmd := &cobra.Command{
28+
Use: "delete vrf -i <metal_vrf_UUID> [-f]",
29+
Short: "Deletes a VRF.",
30+
Long: "Deletes the specified VRF with a confirmation prompt. To skip the confirmation, use --force.",
31+
Example: `# Deletes a VRF, with confirmation.
32+
metal delete vrf -i 77e6d57a-d7a4-4816-b451-cf9b043444e2
33+
>
34+
✔ Are you sure you want to delete device 7ec86e23-8dcf-48ed-bd9b-c25c20958277: y
35+
36+
# Deletes a VRF, skipping confirmation.
37+
metal delete vrf -f -i 77e6d57a-d7a4-4816-b451-cf9b043444e2`,
38+
RunE: func(cmd *cobra.Command, args []string) error {
39+
cmd.SilenceUsage = true
40+
41+
if !force {
42+
prompt := promptui.Prompt{
43+
Label: fmt.Sprintf("Are you sure you want to delete VRF %s: ", vrfID),
44+
IsConfirm: true,
45+
}
46+
47+
result, err := prompt.Run()
48+
if err != nil || result != "y" {
49+
return nil
50+
}
51+
}
52+
53+
if err := deleteVrf(vrfID); err != nil {
54+
return fmt.Errorf("could not delete VRF: %w", err)
55+
}
56+
57+
return nil
58+
},
59+
}
60+
61+
deleteVrfCmd.Flags().StringVarP(&vrfID, "id", "i", "", "UUID of the VRF.")
62+
deleteVrfCmd.Flags().BoolVarP(&force, "force", "f", false, "Skips confirmation for the removal of the VRF.")
63+
64+
_ = deleteVrfCmd.MarkFlagRequired("id")
65+
66+
return deleteVrfCmd
67+
}

0 commit comments

Comments
 (0)