Skip to content

Commit

Permalink
fix: Updated metal-go client for sub-command facilicites
Browse files Browse the repository at this point in the history
  • Loading branch information
codinja1188 committed Jan 31, 2024
1 parent bf56e76 commit 7dc694f
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 53 deletions.
4 changes: 3 additions & 1 deletion docs/metal_facilities_get.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ metal facilities get [flags]
### Options

```
-h, --help help for get
-h, --help help for get
-O, --organization-id string UUID of the organization
-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.
```

### Options inherited from parent commands
Expand Down
32 changes: 7 additions & 25 deletions internal/facilities/facility.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
// Copyright © 2018 Jasmin Gacic <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package facilities

import (
metal "github.com/equinix/equinix-sdk-go/services/metalv1"
"github.com/equinix/metal-cli/internal/outputs"
"github.com/packethost/packngo"
"github.com/spf13/cobra"
)

type Client struct {
Servicer Servicer
Service packngo.FacilityService
Service *metal.FacilitiesApiService
Out outputs.Outputer
}

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

Expand All @@ -55,8 +35,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
74 changes: 47 additions & 27 deletions internal/facilities/retrieve.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
// Copyright © 2018 Jasmin Gacic <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package facilities

import (
"context"
"fmt"
"strings"

"github.com/equinix/equinix-sdk-go/services/metalv1"
"github.com/spf13/cobra"
)

func (c *Client) Retrieve() *cobra.Command {
return &cobra.Command{
var (
projectID string
organizationID string
)

retrieveFacilitesCmd := &cobra.Command{
Use: `get`,
Aliases: []string{"list"},
Short: "Retrieves a list of facilities.",
Expand All @@ -37,23 +24,56 @@ func (c *Client) Retrieve() *cobra.Command {
metal facilities get`,

RunE: func(cmd *cobra.Command, args []string) error {
var (
facilityList *metalv1.FacilityList
err error
)
cmd.SilenceUsage = true
facilities, _, err := c.Service.List(c.Servicer.ListOptions(nil, nil))
if err != nil {
return fmt.Errorf("Could not list Facilities: %w", err)
includes := []string{}
excludes := []string{}
if projectID != "" {
facilityList, _, err = c.Service.FindFacilitiesByProject(context.Background(), projectID).Include(c.Servicer.Includes(includes)).Exclude(c.Servicer.Excludes(excludes)).Execute()
if err != nil {
return fmt.Errorf("could not list Project Metal Facilities: %w", err)
}
} else if organizationID != "" {
facilityList, _, err = c.Service.FindFacilitiesByOrganization(context.Background(), organizationID).Include(c.Servicer.Includes(includes)).Exclude(c.Servicer.Excludes(excludes)).Execute()
if err != nil {
return fmt.Errorf("could not list Organization Metal Facilities: %w", err)
}

} else {
inc := []metalv1.FindFacilitiesIncludeParameterInner{}
exc := []metalv1.FindFacilitiesIncludeParameterInner{}
facilityList, _, err = c.Service.FindFacilities(context.Background()).Include(inc).Exclude(exc).Execute()
if err != nil {
return fmt.Errorf("could not list All Metal Facilities: %w", err)
}
}
facilities := facilityList.GetFacilities()
data := make([][]string, len(facilities))

for i, facility := range facilities {
var metro string
if facility.Metro != nil {
metro = facility.Metro.Code
metro = facility.Metro.GetCode()
}
data[i] = []string{facility.Name, facility.Code, metro, strings.Join(facility.Features, ",")}

facilityFeatures := facility.GetFeatures()
var stringFeatures []string
for _, feature := range facilityFeatures {
stringFeatures = append(stringFeatures, string(feature))
}
data[i] = []string{facility.GetName(), facility.GetCode(), metro, strings.Join(([]string)(stringFeatures), ",")}
}
header := []string{"Name", "Code", "Metro", "Features"}

return c.Out.Output(facilities, header, &data)
},
}

retrieveFacilitesCmd.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.")
retrieveFacilitesCmd.Flags().StringVarP(&organizationID, "organization-id", "O", "", "UUID of the organization")
_ = retrieveFacilitesCmd.MarkFlagRequired("project-id")

return retrieveFacilitesCmd
}
87 changes: 87 additions & 0 deletions test/e2e/facilitiestest/facilites_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package facilitiestest

import (
"strings"
"testing"

root "github.com/equinix/metal-cli/internal/cli"
"github.com/equinix/metal-cli/internal/facilities"
outputPkg "github.com/equinix/metal-cli/internal/outputs"
"github.com/spf13/cobra"

"github.com/equinix/metal-cli/test/helper"
)

func TestFacilities_Retrieve(t *testing.T) {
subCommand := "facilities"
rootClient := root.NewClient(helper.ConsumerToken, helper.URL, helper.Version)
randName := helper.GenerateRandomString(5)

tests := []struct {
name string
cmd *cobra.Command
want *cobra.Command
cmdFunc func(*testing.T, *cobra.Command)
}{
{
name: "retrieve facilities by projectId",
cmd: facilities.NewClient(rootClient, outputPkg.Outputer(&outputPkg.Standard{})).NewCommand(),
want: &cobra.Command{},
cmdFunc: func(t *testing.T, c *cobra.Command) {
root := c.Root()

projName := "metal-cli-" + randName + "-facilities-get-project-test"
projectId := helper.CreateTestProject(t, projName)

if projectId.GetId() != "" {

root.SetArgs([]string{subCommand, "get", "-p", projectId.GetId()})

out := helper.ExecuteAndCaptureOutput(t, root)

if !strings.Contains(string(out[:]), "NAME") &&
!strings.Contains(string(out[:]), "CODE") &&
!strings.Contains(string(out[:]), "METRO") &&
!strings.Contains(string(out[:]), "baremetal,backend_transfer,layer_2,global_ipv4,ibx") &&
!strings.Contains(string(out[:]), "Singapore") {
t.Error("expected output should include NAME CODE METRO Singapore and baremetal,backend_transfer,layer_2,global_ipv4,ibx, in the out string ")
}
}
},
},
{
name: "retrieve All facilities",
cmd: facilities.NewClient(rootClient, outputPkg.Outputer(&outputPkg.Standard{})).NewCommand(),
want: &cobra.Command{},
cmdFunc: func(t *testing.T, c *cobra.Command) {
root := c.Root()

projName := "metal-cli-" + randName + "-facilities-get-all-test"
projectId := helper.CreateTestProject(t, projName)

if projectId.GetId() != "" {

root.SetArgs([]string{subCommand, "get"})

out := helper.ExecuteAndCaptureOutput(t, root)

if !strings.Contains(string(out[:]), "NAME") &&
!strings.Contains(string(out[:]), "CODE") &&
!strings.Contains(string(out[:]), "METRO") &&
!strings.Contains(string(out[:]), "baremetal,backend_transfer,layer_2,global_ipv4,ibx") &&
!strings.Contains(string(out[:]), "Singapore") {
t.Error("expected output should include NAME CODE METRO Singapore and baremetal,backend_transfer,layer_2,global_ipv4,ibx, in the out string ")
}
}
},
},
}

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

0 comments on commit 7dc694f

Please sign in to comment.