Skip to content

Commit

Permalink
feat: Enabled virtual-circuit subcomands in metal-cli
Browse files Browse the repository at this point in the history
  • Loading branch information
codinja1188 committed Oct 20, 2023
1 parent a64058f commit 1e23c8e
Show file tree
Hide file tree
Showing 4 changed files with 377 additions and 0 deletions.
157 changes: 157 additions & 0 deletions internal/virtualcircuit/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package virtualcircuit

import (
"context"
"fmt"

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

func (c *Client) CreateVirtualCricuit() *cobra.Command {
var (
connectionID string
portID string
name string
description string
projectID string
vnid string
vrf string
subnet string
customerIP string
metalIP string
md5 string
peerAsn int
speed int
nnVlan int
tags []string
)

createVirtualCricuitCmd := &cobra.Command{
Use: `create [-i connection_id] [-p port_id] [-P <project_id> ] --n <name> [-d <description>] [-v <vlanID> ] [-t <tags> ] [-vlan <vlan> ] [-speed <speed> ]`,
Short: "Creates an create-virtual-circuit for specific interconnection.",
Long: "Creates an create-virtual-circuit for specific interconnection",
Example: ` # Creates a new virtual-circuit named "interconnection":
metal virtual-circuit create [-i connection_id] [-p port_id] [-P <project_id> ] --n <name> [-d <description>] [-v <vlanID> ] [-t <tags> ] [-vlan <vlan> ] [-speed <speed> ]
metal virtual-circuit create [-i connection_id] [-p port_id] [-P <project_id> ] -n <name> [-m <metro>] [-r <redundancy>] [-t "shared" ] -T <service_token_type> -v <vrfs>
metal virtual-circuit create [-i connection_id] [-p port_id] [-P <project_id> ] -n <name> [-m <metro>] [-r <redundancy>] [-t "shared" ] -T <service_token_type> -v <vrfs>`,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
var virtualCircuitCreateInput metal.VirtualCircuitCreateInput

if vrf != "" {
vrfVirtualCircuitCreateInput := metal.NewVrfVirtualCircuitCreateInputWithDefaults()

if projectID != "" {
vrfVirtualCircuitCreateInput.SetProjectId(projectID)
}

if description != "" {
vrfVirtualCircuitCreateInput.SetDescription(description)
}

if name != "" {
vrfVirtualCircuitCreateInput.SetName(name)
}

if nnVlan > 2 {
vrfVirtualCircuitCreateInput.SetNniVlan(int32(nnVlan))
}

if speed > 0 {
vrfVirtualCircuitCreateInput.SetSpeed(int32(speed))
}

if len(tags) > 0 {
vrfVirtualCircuitCreateInput.SetTags(tags)
}

if subnet != "" {
vrfVirtualCircuitCreateInput.SetSubnet(subnet)
}

if peerAsn > 0 {
vrfVirtualCircuitCreateInput.SetPeerAsn(int32(peerAsn))
}

if customerIP != "" {
vrfVirtualCircuitCreateInput.SetCustomerIp(customerIP)
}

if metalIP != "" {
vrfVirtualCircuitCreateInput.SetMetalIp(metalIP)
}

if md5 != "" {
vrfVirtualCircuitCreateInput.SetMd5(md5)
}
virtualCircuitCreateInput = metal.VirtualCircuitCreateInput{VrfVirtualCircuitCreateInput: vrfVirtualCircuitCreateInput}

} else {
vlanVirtualCircuitCreateInput := metal.NewVlanVirtualCircuitCreateInput(projectID)

if description != "" {
vlanVirtualCircuitCreateInput.SetDescription(description)
}

if name != "" {
vlanVirtualCircuitCreateInput.SetName(name)
}

if nnVlan > 2 {
vlanVirtualCircuitCreateInput.SetNniVlan(int32(nnVlan))
}

if vnid != "" {
vlanVirtualCircuitCreateInput.SetVnid(vnid)
}

if speed > 0 {
vlanVirtualCircuitCreateInput.SetSpeed(int32(speed))
}

if len(tags) > 0 {
vlanVirtualCircuitCreateInput.SetTags(tags)
}

virtualCircuitCreateInput = metal.VirtualCircuitCreateInput{VlanVirtualCircuitCreateInput: vlanVirtualCircuitCreateInput}
}

vc, _, err := c.Service.CreateInterconnectionPortVirtualCircuit(context.Background(), connectionID, portID).VirtualCircuitCreateInput(virtualCircuitCreateInput).Execute()
if err != nil {
return fmt.Errorf("could not create interconnections: %w", err)
}

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

data[0] = []string{vc.VlanVirtualCircuit.GetId(), vc.VlanVirtualCircuit.GetName(), vc.VlanVirtualCircuit.GetDescription(), vc.VlanVirtualCircuit.GetCreatedAt().String()}
header := []string{"ID", "Name", "Description", "Created"}

return c.Out.Output(vc.VlanVirtualCircuit, header, &data)

},
}

createVirtualCricuitCmd.Flags().StringVarP(&connectionID, "id", "i", "", "The UUID of the interconnection.")
createVirtualCricuitCmd.Flags().StringVarP(&portID, "port", "p", "", "The UUID of the port.")
createVirtualCricuitCmd.Flags().StringVarP(&projectID, "projectId", "P", "", "The UUID of the projectID.")
createVirtualCricuitCmd.Flags().StringVarP(&name, "name", "n", "", "Name of the interconnection")
createVirtualCricuitCmd.Flags().StringVarP(&description, "description", "d", "", "Adds or updates the description for the interconnection.")
createVirtualCricuitCmd.Flags().StringVarP(&vnid, "vnid", "v", "", "The UUID of the VLAN.")
createVirtualCricuitCmd.Flags().IntVarP(&nnVlan, "vlan", "", 0, "Adds or updates vlan Must be between 2 and 3999")
createVirtualCricuitCmd.Flags().IntVarP(&speed, "speed", "s", 0, "bps speed or string (e.g. 52 - '52m' or '100g' or '4 gbps')")
createVirtualCricuitCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, "Return only the specified tags.")

createVirtualCricuitCmd.Flags().StringVarP(&subnet, "subnet", "", "", "adds or updates the Email")
createVirtualCricuitCmd.Flags().StringVarP(&customerIP, "customerIP", "c", "", "An IP address from the subnet that will be used on the Customer side")
createVirtualCricuitCmd.Flags().StringVarP(&metalIP, "metalIP", "m", "", "An IP address from the subnet that will be used on the Metal side. ")
createVirtualCricuitCmd.Flags().IntVarP(&peerAsn, "peerAsn", "a", 0, "The peer ASN that will be used with the VRF on the Virtual Circuit.")
createVirtualCricuitCmd.Flags().StringVarP(&md5, "md5", "m", "", "The plaintext BGP peering password shared by neighbors as an MD5 checksum")

_ = createVirtualCricuitCmd.MarkFlagRequired("id")
_ = createVirtualCricuitCmd.MarkFlagRequired("portId")
_ = createVirtualCricuitCmd.MarkFlagRequired("projectId")
return createVirtualCricuitCmd
}
41 changes: 41 additions & 0 deletions internal/virtualcircuit/retrieve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package virtualcircuit

import (
"context"
"fmt"

"github.com/spf13/cobra"
)

func (c *Client) Retrieve() *cobra.Command {
var vcID string
retrieveVirtualCircuitCmd := &cobra.Command{
Use: "get -i <VcId>",
Aliases: []string{"list"},
Short: "Retrieves virtual circuit for a specific circuit Id.",
Long: "Retrieves virtual circuit for a specific circuit Id.",
Example: ` # Retrieve virtual circuit for a specific circuit::
# Retrieve the details of a specific virtual-circuit:
metal interconnections get -i e9a969b3-8911-4667-9d99-57cd3dd4ef6f`,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

inc := []string{}
header := []string{"ID", "Name", "Port", "Speed", "Created"}
if vcID != "" {
return fmt.Errorf("should provide poroper Virtual-circuit ID")
}
vcUID, _, err := c.Service.GetVirtualCircuit(context.Background(), vcID).Include(c.Servicer.Includes(inc)).Execute()
if err != nil {
return fmt.Errorf("error when calling `InterconnectionsApi.GetVirtualCircuit``: %w", err)
}
data := make([][]string, 1)
data[0] = []string{vcUID.VlanVirtualCircuit.GetId(), vcUID.VlanVirtualCircuit.GetName(), string(vcUID.VlanVirtualCircuit.GetType()), string(vcUID.VlanVirtualCircuit.GetSpeed()), vcUID.VlanVirtualCircuit.GetCreatedAt().String()}
return c.Out.Output(vcUID, header, &data)
},
}
retrieveVirtualCircuitCmd.Flags().StringVarP(&vcID, "vcID", "i", "", "UUID of the virtual-circuit")
return retrieveVirtualCircuitCmd
}
127 changes: 127 additions & 0 deletions internal/virtualcircuit/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package virtualcircuit

import (
"context"
"fmt"

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

func (c *Client) Update() *cobra.Command {
var (
description string
speed string
name string
vnid string
vcID string
subnet string
customerIP string
metalIP string
md5 string
tags []string
peerAsn int
)
// updateConnectionCmd represents the updateConnectionCmd command
updateVirtualCircuitCmd := &cobra.Command{
Use: `update -i <virtualcircuit_id> [--vnid <vn UUID>] [-d <description>] [-n <name>] [-s <speed>] [-t <tags>]`,
Short: "Updates a virtualcircuit.",
Long: "Updates a specified virtualcircuit.",
Example: ` # Updates a specified virtualcircuit.:
metal virtual-circuit update --id 30c15082-a06e-4c43-bfc3-252616b46eba`,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
inc := []string{}
var virtualCircuitUpdateInput metal.VirtualCircuitUpdateInput
header := []string{"ID", "Name", "Type", "Created"}

if vnid != "" {
vlanVirtualCircuitUpdateInput := metal.NewVlanVirtualCircuitUpdateInput()

if speed != "" {
vlanVirtualCircuitUpdateInput.SetSpeed(speed)
}

if description != "" {
vlanVirtualCircuitUpdateInput.SetDescription(description)
}

if name != "" {
vlanVirtualCircuitUpdateInput.SetName(name)
}

if len(tags) > 0 {
vlanVirtualCircuitUpdateInput.SetTags(tags)
}

virtualCircuitUpdateInput = metal.VirtualCircuitUpdateInput{VlanVirtualCircuitUpdateInput: vlanVirtualCircuitUpdateInput}
} else {
vrfVirtualCircuitCreateInput := metal.NewVrfVirtualCircuitUpdateInput()

if speed != "" {
vrfVirtualCircuitCreateInput.SetSpeed(speed)
}

if description != "" {
vrfVirtualCircuitCreateInput.SetDescription(description)
}

if name != "" {
vrfVirtualCircuitCreateInput.SetName(name)
}

if len(tags) > 0 {
vrfVirtualCircuitCreateInput.SetTags(tags)
}
if subnet != "" {
vrfVirtualCircuitCreateInput.SetSubnet(subnet)
}

if peerAsn > 0 {
vrfVirtualCircuitCreateInput.SetPeerAsn(int32(peerAsn))
}

if customerIP != "" {
vrfVirtualCircuitCreateInput.SetCustomerIp(customerIP)
}

if metalIP != "" {
vrfVirtualCircuitCreateInput.SetMetalIp(metalIP)
}

if md5 != "" {
vrfVirtualCircuitCreateInput.SetMd5(md5)
}
virtualCircuitUpdateInput = metal.VirtualCircuitUpdateInput{VrfVirtualCircuitUpdateInput: vrfVirtualCircuitCreateInput}
}
vc, _, err := c.Service.UpdateVirtualCircuit(context.Background(), vcID).VirtualCircuitUpdateInput(virtualCircuitUpdateInput).Include(c.Servicer.Includes(inc)).Execute()
if err != nil {
return fmt.Errorf("could not update virtual-circuit: %w", err)
}

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

data[0] = []string{vc.VlanVirtualCircuit.GetId(), vc.VlanVirtualCircuit.GetName(), string(vc.VlanVirtualCircuit.GetType()), vc.VlanVirtualCircuit.GetCreatedAt().String()}

return c.Out.Output(vc, header, &data)

},
}

updateVirtualCircuitCmd.Flags().StringVarP(&vcID, "id", "i", "", "The UUID of the virtual-circuit.")
updateVirtualCircuitCmd.Flags().StringVarP(&name, "name", "n", "", "The new name of the interconnection.")
updateVirtualCircuitCmd.Flags().StringVarP(&description, "description", "d", "", "Adds or updates the description for the interconnection.")
updateVirtualCircuitCmd.Flags().StringVarP(&speed, "speed", "s", "", "Adds or updates Speed can be changed only if it is an interconnection on a Dedicated Port")

updateVirtualCircuitCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds or updates the tags for the connection --tags="tag1,tag2".`)

updateVirtualCircuitCmd.Flags().StringVarP(&subnet, "subnet", "", "", "adds or updates the Email")
updateVirtualCircuitCmd.Flags().StringVarP(&customerIP, "customerIP", "c", "", "An IP address from the subnet that will be used on the Customer side")
updateVirtualCircuitCmd.Flags().StringVarP(&metalIP, "metalIP", "m", "", "An IP address from the subnet that will be used on the Metal side. ")
updateVirtualCircuitCmd.Flags().IntVarP(&peerAsn, "peerAsn", "a", 0, "The peer ASN that will be used with the VRF on the Virtual Circuit.")
updateVirtualCircuitCmd.Flags().StringVarP(&md5, "md5", "m", "", "The plaintext BGP peering password shared by neighbors as an MD5 checksum")

_ = updateVirtualCircuitCmd.MarkFlagRequired("id")
return updateVirtualCircuitCmd
}
52 changes: 52 additions & 0 deletions internal/virtualcircuit/virtualcircuit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package virtualcircuit

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.InterconnectionsApiService
Out outputs.Outputer
}

func (c *Client) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: `virtual-circuit`,
Aliases: []string{""},
Short: "virtual-circuit operations: get, update, delete",
Long: "For more information on https://deploy.equinix.com/developers/docs/metal/interconnections.",
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).InterconnectionsApi
},
}

cmd.AddCommand(
c.Retrieve(),
c.Update(),
//c.Delete(),
)

return cmd
}

type Servicer interface {
MetalAPI(*cobra.Command) *metal.APIClient
Filters() map[string]string
Includes(defaultIncludes []string) (incl []string)
Excludes(defaultExcludes []string) (excl []string)
}

func NewClient(s Servicer, out outputs.Outputer) *Client {
return &Client{
Servicer: s,
Out: out,
}
}

0 comments on commit 1e23c8e

Please sign in to comment.