Skip to content

Commit

Permalink
fix: Updated metal-go client for sub-commands Virtual Network (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
cprivitere authored Oct 9, 2023
2 parents 23af0fc + 190cc8a commit 5746b18
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 27 deletions.
27 changes: 15 additions & 12 deletions internal/vlan/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
package vlan

import (
"context"
"fmt"
"strconv"

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

Expand All @@ -45,28 +46,30 @@ func (c *Client) Create() *cobra.Command {

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

req := &packngo.VirtualNetworkCreateRequest{
ProjectID: projectID,
Metro: metro,
Facility: facility,
VXLAN: vxlan,
virtualNetworkCreateInput := metal.NewVirtualNetworkCreateInput()
if metro != "" {
virtualNetworkCreateInput.SetMetro(metro)
}
if facility != "" {
virtualNetworkCreateInput.SetFacility(facility)
}
virtualNetworkCreateInput.SetVxlan(int32(vxlan))

if description != "" {
req.Description = description
virtualNetworkCreateInput.Description = &description
}

n, _, err := c.Service.Create(req)
n, _, err := c.Service.CreateVirtualNetwork(context.Background(), projectID).VirtualNetworkCreateInput(*virtualNetworkCreateInput).Execute()
if err != nil {
return fmt.Errorf("Could not create ProjectVirtualNetwork: %w", err)
return fmt.Errorf("could not create ProjectVirtualNetwork: %w", err)
}

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

// TODO(displague) metro is not in the response
data[0] = []string{n.ID, n.Description, strconv.Itoa(n.VXLAN), n.MetroCode, n.FacilityCode, n.CreatedAt}
data[0] = []string{n.GetId(), n.GetDescription(), strconv.Itoa(int(n.GetVxlan())), n.GetMetroCode(), n.CreatedAt.String()}

header := []string{"ID", "Description", "VXLAN", "Metro", "Facility", "Created"}
header := []string{"ID", "Description", "VXLAN", "Metro", "Created"}

return c.Out.Output(n, header, &data)
},
Expand Down
5 changes: 3 additions & 2 deletions internal/vlan/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package vlan

import (
"context"
"fmt"

"github.com/manifoldco/promptui"
Expand All @@ -34,7 +35,7 @@ func (c *Client) Delete() *cobra.Command {
)

deleteVnet := func(id string) error {
_, err := c.Service.Delete(id)
_, _, err := c.Service.DeleteVirtualNetwork(context.Background(), vnetID).Execute()
if err != nil {
return err
}
Expand Down Expand Up @@ -70,7 +71,7 @@ func (c *Client) Delete() *cobra.Command {
}
}
if err := deleteVnet(vnetID); err != nil {
return fmt.Errorf("Could not delete Virtual Network: %w", err)
return fmt.Errorf("could not delete Virtual Network: %w", err)
}
return nil
},
Expand Down
23 changes: 16 additions & 7 deletions internal/vlan/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,28 @@ func (c *Client) Retrieve() *cobra.Command {

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
vnets, _, err := c.Service.List(projectID, c.Servicer.ListOptions(nil, nil))
request := c.Service.FindVirtualNetworks(cmd.Context(), projectID).Include(c.Servicer.Includes(nil)).Exclude(c.Servicer.Excludes(nil))
filters := c.Servicer.Filters()
if filters["facility"] != "" {
request = request.Facility(filters["facility"])
}

if filters["metro"] != "" {
request = request.Metro(filters["metro"])
}
virtualNetworksList, _, err := request.Execute()
if err != nil {
return fmt.Errorf("Could not list Project Virtual Networks: %w", err)
}
virtualNetworks := virtualNetworksList.GetVirtualNetworks()
data := make([][]string, len(virtualNetworks))

data := make([][]string, len(vnets.VirtualNetworks))

for i, n := range vnets.VirtualNetworks {
data[i] = []string{n.ID, n.Description, strconv.Itoa(n.VXLAN), n.FacilityCode, n.CreatedAt}
for i, n := range virtualNetworks {
data[i] = []string{n.GetId(), n.GetDescription(), strconv.Itoa(int(n.GetVxlan())), n.GetMetroCode(), n.GetCreatedAt().String()}
}
header := []string{"ID", "Description", "VXLAN", "Facility", "Created"}
header := []string{"ID", "Description", "VXLAN", "Metro", "Created"}

return c.Out.Output(vnets, header, &data)
return c.Out.Output(virtualNetworksList, header, &data)
},
}
retrieveVirtualNetworksCmd.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.")
Expand Down
12 changes: 7 additions & 5 deletions internal/vlan/vlan.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
package vlan

import (
metal "github.com/equinix-labs/metal-go/metal/v1"
"github.com/equinix/metal-cli/internal/outputs"
"github.com/packethost/packngo"
"github.com/spf13/cobra"
)

type Client struct {
Servicer Servicer
Service packngo.ProjectVirtualNetworkService
Service metal.VLANsApiService
Out outputs.Outputer
}

Expand All @@ -45,7 +45,7 @@ func (c *Client) NewCommand() *cobra.Command {
root.PersistentPreRun(cmd, args)
}
}
c.Service = c.Servicer.API(cmd).ProjectVirtualNetworks
c.Service = *c.Servicer.MetalAPI(cmd).VLANsApi
},
}

Expand All @@ -58,8 +58,10 @@ func (c *Client) NewCommand() *cobra.Command {
}

type Servicer interface {
API(*cobra.Command) *packngo.Client
ListOptions(defaultIncludes, defaultExcludes []string) *packngo.ListOptions
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 {
Expand Down
80 changes: 80 additions & 0 deletions test/e2e/vlan/vlan_creat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package vlan

import (
"io"
"os"
"strings"
"testing"

root "github.com/equinix/metal-cli/internal/cli"
outputPkg "github.com/equinix/metal-cli/internal/outputs"
"github.com/equinix/metal-cli/internal/vlan"
"github.com/equinix/metal-cli/test/helper"
"github.com/spf13/cobra"
)

func TestCli_Vlan_Create(t *testing.T) {
var projectId string
var err error
subCommand := "vlan"
consumerToken := ""
apiURL := ""
Version := "metal"
rootClient := root.NewClient(consumerToken, apiURL, Version)
type fields struct {
MainCmd *cobra.Command
Outputer outputPkg.Outputer
}
tests := []struct {
name string
fields fields
want *cobra.Command
cmdFunc func(*testing.T, *cobra.Command)
}{
{
name: "create_virtual_network",
fields: fields{
MainCmd: vlan.NewClient(rootClient, outputPkg.Outputer(&outputPkg.Standard{})).NewCommand(),
Outputer: outputPkg.Outputer(&outputPkg.Standard{}),
},
want: &cobra.Command{},
cmdFunc: func(t *testing.T, c *cobra.Command) {
root := c.Root()
projectId, err = helper.CreateTestProject("metal-cli-vlan-create-pro")
if err != nil {
t.Error(err)
}
if len(projectId) != 0 {
root.SetArgs([]string{subCommand, "create", "-p", projectId, "-m", "da", "--vxlan", "2023", "-d", "metal-cli-vlan-test"})
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
if err := root.Execute(); err != nil {
t.Error(err)
}
w.Close()
out, _ := io.ReadAll(r)
os.Stdout = rescueStdout
if !strings.Contains(string(out[:]), "metal-cli-vlan-test") &&
!strings.Contains(string(out[:]), "da") &&
!strings.Contains(string(out[:]), "2023") {
t.Error("expected output should include metal-cli-vlan-test, da and 2023 strings in the out string")
}

err = helper.CleanTestProject(projectId)
if err != nil {
t.Error(err)
}
}
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rootCmd := rootClient.NewCommand()
rootCmd.AddCommand(tt.fields.MainCmd)
tt.cmdFunc(t, tt.fields.MainCmd)
})
}
}
78 changes: 78 additions & 0 deletions test/e2e/vlan/vlan_delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package vlan

import (
"io"
"os"
"strings"
"testing"

root "github.com/equinix/metal-cli/internal/cli"
outputPkg "github.com/equinix/metal-cli/internal/outputs"
"github.com/equinix/metal-cli/internal/vlan"
"github.com/equinix/metal-cli/test/helper"
"github.com/spf13/cobra"
)

func TestCli_Vlan_Clean(t *testing.T) {
var projectId, vlanId string
var err error
subCommand := "vlan"
consumerToken := ""
apiURL := ""
Version := "metal"
rootClient := root.NewClient(consumerToken, apiURL, Version)
type fields struct {
MainCmd *cobra.Command
Outputer outputPkg.Outputer
}
tests := []struct {
name string
fields fields
want *cobra.Command
cmdFunc func(*testing.T, *cobra.Command)
}{
{
name: "delete_virtual_network",
fields: fields{
MainCmd: vlan.NewClient(rootClient, outputPkg.Outputer(&outputPkg.Standard{})).NewCommand(),
Outputer: outputPkg.Outputer(&outputPkg.Standard{}),
},
want: &cobra.Command{},
cmdFunc: func(t *testing.T, c *cobra.Command) {
root := c.Root()
projectId, err = helper.CreateTestProject("metal-cli-vlan-get-pro")
if err != nil {
t.Error(err)
}
vlanId, err = helper.CreateTestVlan(projectId, 2023, "metal-cli-vlan-get-test")
if len(projectId) != 0 && len(vlanId) != 0 {
root.SetArgs([]string{subCommand, "delete", "-f", "-i", vlanId})
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
if err := root.Execute(); err != nil {
t.Error(err)
}
w.Close()
out, _ := io.ReadAll(r)
os.Stdout = rescueStdout
if !strings.Contains(string(out[:]), "Virtual Network "+vlanId+" successfully deleted.") {
t.Error("expected output should include Virtual Network " + vlanId + "successfully deleted." + "in the out string")
}
err = helper.CleanTestProject(projectId)
if err != nil {
t.Error(err)
}
}
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rootCmd := rootClient.NewCommand()
rootCmd.AddCommand(tt.fields.MainCmd)
tt.cmdFunc(t, tt.fields.MainCmd)
})
}
}
Loading

0 comments on commit 5746b18

Please sign in to comment.