-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
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 vrf <my_vrf> [-m <metro_code>] [-AS int] [-I str] [-d <description>]`, | ||
Short: "Creates a virtual network.", | ||
Long: "Creates a VRF", | ||
Example: `# Creates a VRF, metal vrf create `, | ||
|
||
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, | ||
} | ||
// Retreived these params from packetngo based on the VRF function there, assuming vrfs need these to work | ||
// From Packetngo >>>> | ||
// IPRanges is a list of all IPv4 and IPv6 Ranges that will be available to | ||
// BGP Peers. IPv4 addresses must be /8 or smaller with a minimum size of | ||
// /29. IPv6 must be /56 or smaller with a minimum size of /64. Ranges must | ||
// not overlap other ranges within the VRF. | ||
// >>>>>>>>>>>>>>>>>>> | ||
// Not quite sure if a CIDR can be specified here using a "/" or how it works exactly in tandem with VRFs | ||
// may also need some logic for processing errors on local asn, also not sure about this | ||
request := c.Service.CreateVrf(context.Background(), projectID).VrfCreateInput(req).Exclude(nil).Include(nil) | ||
n, _, err := request.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{n.GetName(), *n.GetMetro().Code, n.GetDescription(), strconv.Itoa(int(n.GetLocalAsn())), strings.Join(n.GetIpRanges(), ","), n.GetCreatedAt().String()} | ||
header := []string{"Name", "Metro", "Description", "LocalASN", "IPrange", "Created"} | ||
|
||
return c.Out.Output(n, 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{}, `Tag or list of tags for the VRF: --tags="tag1,tag2".`) | ||
createVRFCmd.Flags().StringVarP(&name, "name", "n", "", "Name of the VRF") | ||
createVRFCmd.Flags().StringVarP(&description, "description", "d", "", "Description of the VRF.") | ||
|
||
createVRFCmd.Flags().StringVarP(&metro, "metro", "m", "", "Code of the metro where the VRF will be created") | ||
createVRFCmd.Flags().Int32VarP(&localASN, "local-asn", "a", 0, "Local ASN for the VRF") | ||
createVRFCmd.Flags().StringSliceVarP(&ipRanges, "ip-ranges", "r", []string{}, "IP range or list of IP ranges for the VRF") | ||
|
||
// making them all required here | ||
_ = createVRFCmd.MarkFlagRequired("name") | ||
_ = createVRFCmd.MarkFlagRequired("metro") | ||
_ = createVRFCmd.MarkFlagRequired("local-asn") | ||
_ = createVRFCmd.MarkFlagRequired("IPrange") | ||
|
||
return createVRFCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package main // or your appropriate package name | ||
|
||
import ( | ||
"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.Delete(id) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println("VRF", id, "successfully deleted.") | ||
return nil // No need to return 'err' here; it's always nil. | ||
} | ||
|
||
deleteMetalVrfCmd := &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 | ||
# 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" { | ||
fmt.Println("VRF deletion aborted.") | ||
return nil | ||
} | ||
} | ||
|
||
if err := deleteVrf(vrfID); err != nil { | ||
return fmt.Errorf("Could not delete VRF: %w", err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
deleteMetalVrfCmd.Flags().StringVarP(&vrfID, "id", "i", "", "UUID of the VRF.") | ||
_ = deleteMetalVrfCmd.MarkFlagRequired("id") | ||
deleteMetalVrfCmd.Flags().BoolVarP(&force, "force", "f", false, "Skips confirmation for the removal of the VRF.") | ||
|
||
return deleteMetalVrfCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package vrf | ||
|
||
import ( | ||
metal "github.com/equinix-labs/metal-go/metal/v1" | ||
"github.com/equinix/metal-cli/internal/outputs" | ||
"github.com/spf13/cobra" | ||
"fmt" | ||
) | ||
|
||
type Client struct { | ||
Servicer Servicer | ||
Service metal.VRFsApiService | ||
Out outputs.Outputer | ||
} | ||
|
||
|
||
func (c *Client) Retrieve() *cobra.Command { | ||
var projectID string | ||
|
||
// retrieveVrfsCmd represents the retrieveMetalGateways command | ||
retrieveVrfsCmd := &cobra.Command{ | ||
Use: `get -p <project_UUID>`, | ||
Aliases: []string{"list"}, | ||
Short: "Lists VRFs.", | ||
Long: "Retrieves a list of all VRFs for the specified project.", | ||
Example: ` | ||
# Lists VRFs for project 3b0795ba-ec9a-4a9e-83a7-043e7e11407c: | ||
metal vrf list -p 3b0795ba-ec9a-4a9e-83a7-043e7e11407c`, | ||
|
||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cmd.SilenceUsage = true | ||
vrfs, _, err := c.Service.Get(ProjectID, c.Servicer.GetOptions(nil, nil)) // <- Not sure about the correct service to call Im assuming its this? https://github.com/packethost/packngo/blob/master/vrf.go | ||
if err != nil { | ||
return fmt.Errorf("Could not list VRFs: %w", err) | ||
} | ||
|
||
data := make([][]string, len(vrfs.VirtualRoutingFunctions)) | ||
|
||
for i, n := range vnets.VirtualRoutingFunctions { | ||
data[i] = []string{n.ID, n.Description, n.IPranges, n.LocalASN n.Metro, n.CreatedAt} //Data should contain all info about VRF not sure where the formatting comes from, going with this. | ||
} | ||
header := []string{"ID", "Description", "VXLAN", "Facility", "Created"} | ||
|
||
return c.Out.Output(vrfs, header, &data) | ||
}, | ||
} | ||
retrieveVrfsCmd.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.") | ||
_ = retrieveVrfsCmd.MarkFlagRequired("project-id") | ||
|
||
return retrieveVrfsCmd | ||
} | ||
|
||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package vrf | ||
|
||
import ( | ||
metal "github.com/equinix-labs/metal-go/metal/v1" | ||
"github.com/equinix/metal-cli/internal/outputs" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type Client struct { | ||
Servicer Servicer | ||
Service metal.VRFsApiService | ||
Out outputs.Outputer | ||
} | ||
|
||
func (c *Client) NewCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: `vrf`, | ||
Aliases: []string{"vrf"}, | ||
Short: "VRF operations : create, TODO: make other commands.", | ||
Long: "Experimental VRF function", | ||
|
||
PersistentPreRun: func(cmd *cobra.Command, args []string) { | ||
if root := cmd.Root(); root != nil { | ||
if root.PersistentPreRun != nil { | ||
root.PersistentPreRun(cmd, args) | ||
} | ||
} | ||
c.Service = *c.Servicer.MetalAPI(cmd).VRFsApi | ||
}, | ||
} | ||
|
||
cmd.AddCommand( | ||
c.Create(), | ||
) | ||
return cmd | ||
} | ||
|
||
type Servicer interface { | ||
MetalAPI(*cobra.Command) *metal.APIClient | ||
} | ||
|
||
func NewClient(s Servicer, out outputs.Outputer) *Client { | ||
return &Client{ | ||
Servicer: s, | ||
Out: out, | ||
} | ||
} |