Skip to content

Commit

Permalink
Merge pull request #167 from equinix/get-capacity-add-filtering-by-me…
Browse files Browse the repository at this point in the history
…tro-and-facility-and-plan

Add parsing of metros, faclities, and plans
  • Loading branch information
displague authored Jan 25, 2022
2 parents e8c5152 + 01e5ac0 commit 08440b7
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 32 deletions.
2 changes: 1 addition & 1 deletion docs/metal_capacity.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ Capacities operations: get, check

* [metal](metal.md) - Command line interface for Equinix Metal
* [metal capacity check](metal_capacity_check.md) - Validates if a deploy can be fulfilled with the given quantity in any of the given locations and plans
* [metal capacity get](metal_capacity_get.md) - Returns a list of facilities or metros and plans with their current capacity.
* [metal capacity get](metal_capacity_get.md) - Returns a list of facilities or metros and plans with their current capacity, with filtering.

22 changes: 12 additions & 10 deletions docs/metal_capacity_get.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
## metal capacity get

Returns a list of facilities or metros and plans with their current capacity.
Returns a list of facilities or metros and plans with their current capacity, with filtering.

### Synopsis

Example:
Retrieve capacities:
metal capacity get { --metro | --facility }
```
metal capacity get [[-m | -f] | [--metros metros,... | --facilities facilities,...]] [-P plans,...] [flags]
```

### Examples

```
metal capacity get [flags]
metal capacity get -m sv,ny,da -P c3.large.arm,c3.medium.x86
```

### Options

```
-f, --facility Facility code (sv15) (default true)
-h, --help help for get
-m, --metro Metro code (sv)
--facilities strings Codes of the facilities (client side filtering)
-f, --facility Report all facilites (default true)
-h, --help help for get
-m, --metro Report all metros
--metros strings Codes of the metros (client side filtering)
-P, --plans strings Names of the plans
```

### Options inherited from parent commands
Expand Down
84 changes: 63 additions & 21 deletions internal/capacity/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,49 +27,91 @@ import (

func (c *Client) Retrieve() *cobra.Command {
var (
checkFacility bool
checkMetro bool
checkFacility, checkMetro bool
metros, facilities, plans, locs []string
)
// retrieveCapacitiesCmd represents the retrieveCapacity command
var retrieveCapacityCmd = &cobra.Command{
Use: "get",
Use: `get [[-m | -f] | [--metros metros,... | --facilities facilities,...]] [-P plans,...]`,
Aliases: []string{"list"},
Short: "Returns a list of facilities or metros and plans with their current capacity.",
Long: `Example:
Retrieve capacities:
metal capacity get { --metro | --facility }
`,
Short: "Returns a list of facilities or metros and plans with their current capacity, with filtering.",
Example: `metal capacity get -m sv,ny,da -P c3.large.arm,c3.medium.x86`,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
var err error
lister := c.Service.List
fieldName := "Facility"
var locationField string
lister := c.Service.List // Default to facilities

fs := cmd.Flags()
if fs.Changed("metros") && fs.Changed("facilities") {
return errors.New("Either facilities or metros, but not both, can be set")
}
if fs.Changed("facility") && fs.Changed("metro") {
return errors.New("Either --facility (-f) or --metro (-m), but not both, can be set")
}
if fs.Changed("facility") && fs.Changed("metros") || fs.Changed("facilities") && fs.Changed("metro") {
return errors.New("Cannot specify both facility and metro filtering")
}
if fs.Changed("metro") && fs.Changed("metros") || fs.Changed("facility") && fs.Changed("facilities") {
return errors.New("Cannot use both --metro (-m) and --metros or --facility (-f) and --facilities")
}

if checkMetro {
fieldName = "Metro"
cmd.SilenceUsage = true

if len(facilities) > 0 {
locationField = "Facility"
locs = append(locs, facilities...)
} else if len(metros) > 0 || checkMetro {
lister = c.Service.ListMetros
locationField = "Metro"
locs = append(locs, metros...)
}

capacities, _, err := lister()
if err != nil {
return errors.Wrap(err, "Could not get Capacity")
}

header := []string{fieldName, "Plan", "Level"}
requiredDataFormat := [][]string{}
header := []string{locationField, "Plan", "Level"}
data := [][]string{}

filtered := map[string]map[string]map[string]string{}

for locCode, capacity := range *capacities {
if len(locs) > 0 && !contains(locs, locCode) {
continue
}
for plan, bm := range capacity {
loc := []string{}
loc = append(loc, locCode, plan, bm.Level)
requiredDataFormat = append(requiredDataFormat, loc)
if len(plans) > 0 && !contains(plans, plan) {
continue
}
loc := []string{locCode, plan, bm.Level}
data = append(data, loc)
if len(filtered[locCode]) == 0 {
filtered[locCode] = map[string]map[string]string{}
}
filtered[locCode][plan] = map[string]string{"levels": bm.Level}
}
}

return c.Out.Output(capacities, header, &requiredDataFormat)
return c.Out.Output(filtered, header, &data)
},
}
retrieveCapacityCmd.Flags().BoolVarP(&checkFacility, "facility", "f", true, "Facility code (sv15)")
retrieveCapacityCmd.Flags().BoolVarP(&checkMetro, "metro", "m", false, "Metro code (sv)")

fs := retrieveCapacityCmd.Flags()
fs.BoolVarP(&checkFacility, "facility", "f", true, "Report all facilites")
fs.BoolVarP(&checkMetro, "metro", "m", false, "Report all metros")
fs.StringSliceVar(&metros, "metros", []string{}, "Codes of the metros (client side filtering)")
fs.StringSliceVar(&facilities, "facilities", []string{}, "Codes of the facilities (client side filtering)")
fs.StringSliceVarP(&plans, "plans", "P", []string{}, "Names of the plans")
return retrieveCapacityCmd
}

func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

0 comments on commit 08440b7

Please sign in to comment.