Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: VRF support #377

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goimports format sequence we can follow - 1st block go runtime imports, 2nd block 3rd party imports, 3rd block local packages import

Copy link
Member

@displague displague Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words: goimports -l "github.com/equinix-labs/metal-go" -w .

"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.")
displague marked this conversation as resolved.
Show resolved Hide resolved
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{
displague marked this conversation as resolved.
Show resolved Hide resolved
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
Loading