Skip to content

Commit

Permalink
Merge pull request #161 from Cray-HPE/loving-stormtrooper
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobsalmela authored Nov 28, 2023
2 parents a911201 + d791eb2 commit c93ebee
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 39 deletions.
30 changes: 16 additions & 14 deletions cmd/cabinet/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,39 @@ import (
)

var (
cabinetNumber int
auto bool
accept bool
format string
sortBy string
ProviderAddCabinetCmd = &cobra.Command{}
cabinetNumber int
auto bool
accept bool
format string
sortBy string
ProviderAddCabinetCmd = &cobra.Command{}
ProviderListCabinetCmd = &cobra.Command{}
)

func init() {
var err error

// Add variants to root commands
// Add subcommands to root commands
root.AddCmd.AddCommand(AddCabinetCmd)
root.ListCmd.AddCommand(ListCabinetCmd)
root.RemoveCmd.AddCommand(RemoveCabinetCmd)

// Add a flag to show supported types
// Common 'add cabinet' flags and then merge with provider-specified command
AddCabinetCmd.Flags().BoolP("list-supported-types", "L", false, "List supported hardware types.")

// Cabinets
AddCabinetCmd.Flags().IntVar(&cabinetNumber, "cabinet", 1001, "Cabinet number.")
AddCabinetCmd.Flags().BoolVar(&auto, "auto", false, "Automatically recommend and assign required flags.")
AddCabinetCmd.MarkFlagsMutuallyExclusive("auto")
AddCabinetCmd.Flags().BoolVarP(&accept, "accept", "y", false, "Automatically accept recommended values.")
err = root.MergeProviderCommand(AddCabinetCmd, ProviderAddCabinetCmd)
if err != nil {
log.Error().Msgf("%+v", err)
os.Exit(1)
}

// Common 'list cabinet' flags and then merge with provider-specified command
ListCabinetCmd.Flags().StringVarP(&format, "format", "f", "pretty", "Format out output")
ListCabinetCmd.Flags().StringVarP(&sortBy, "sort", "s", "location", "Sort by a specific key")

// Merge CANI's command with the provider-specified command
// this allows for CANI's operations to remain consistent, while adding provider config on top
err = root.MergeProviderCommand(AddCabinetCmd, ProviderAddCabinetCmd)
err = root.MergeProviderCommand(ListCabinetCmd, ProviderListCabinetCmd)
if err != nil {
log.Error().Msgf("%+v", err)
os.Exit(1)
Expand Down
72 changes: 47 additions & 25 deletions cmd/cabinet/list_cabinet.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ import (
"fmt"
"os"
"sort"
"strings"
"text/tabwriter"

root "github.com/Cray-HPE/cani/cmd"
"github.com/Cray-HPE/cani/internal/inventory"
"github.com/Cray-HPE/cani/internal/provider/csm"
"github.com/Cray-HPE/cani/pkg/hardwaretypes"
"github.com/Cray-HPE/cani/pkg/pointers"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -90,12 +90,26 @@ func listCabinet(cmd *cobra.Command, args []string) error {
w := tabwriter.NewWriter(os.Stdout, minwidth, tabwidth, padding, padchar, tabwriter.AlignRight)
defer w.Flush()

fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\n",
// set the CANI columns
caniColumns := []string{
"UUID",
"Status",
"Type",
"HMN VLAN",
"Location")
"Location",
}
// Get columns set by the provider
providerColumns := root.D.ListCabinetMetadataColumns()

// combine CANI and provider columns
columns := []string{}
for _, col := range [][]string{caniColumns, providerColumns} {
columns = append(columns, col...)
}

fmt.Fprint(
w,
fmt.Sprintf("%v%s", strings.Join(columns, "\t"), "\n"),
)

// make keys slice to sort by values in the map
keys := make([]uuid.UUID, 0, len(filtered))
Expand All @@ -120,28 +134,36 @@ func listCabinet(cmd *cobra.Command, args []string) error {
return filtered[keys[i]].LocationPath.String() < filtered[keys[j]].LocationPath.String()
})

for _, hw := range keys {
// Start with an empty cabinet metadata struct, just in case if this cabinet doesn't have any
// metadata set
cabinetMetadata := csm.CabinetMetadata{}

if _, exists := filtered[hw].ProviderMetadata[inventory.CSMProvider]; exists {
csmMetadata, err := csm.DecodeProviderMetadata(filtered[hw])
if err != nil {
return err
}

if csmMetadata.Cabinet != nil {
cabinetMetadata = *csmMetadata.Cabinet
}
for _, u := range keys {
hw, exists := filtered[u]
if !exists {
return err
}
// get the provider-specific fields
providerValues, err := root.D.ListCabinetMetadataRow(hw)
if err != nil {
return err
}

fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\n",
filtered[hw].ID.String(),
filtered[hw].Status,
filtered[hw].DeviceTypeSlug,
pointers.IntPtrToStr(cabinetMetadata.HMNVlan),
filtered[hw].LocationPath.String())
// Set the fields CANI uses
fields := []string{"%s", "%s", "%s"}
// append any provider-specified ones, using a %+v to display them to avoid any typing issues at the cost of something ugly printing
for _, n := range providerColumns {
log.Debug().Msgf("Using provider-defined column: %+v", n)
fields = append(fields, "%+v")
}
// print the table with CANI and provider columns/rows
fmt.Fprint(
w,
fmt.Sprintf(strings.Join(fields, "\t"),
filtered[u].ID.String(),
filtered[u].Status,
filtered[u].DeviceTypeSlug,
filtered[u].LocationPath.String()),
"\t",
fmt.Sprintf(strings.Join(providerValues, "\t")),
"\n",
)
}

}
Expand Down
13 changes: 13 additions & 0 deletions internal/domain/cabinet.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,16 @@ func (d *Domain) Recommend(cmd *cobra.Command, args []string, auto bool) (recomm
}
return recommendations, nil
}

func (d *Domain) ListCabinetMetadataColumns() (columns []string) {
columns = d.externalInventoryProvider.ListCabinetMetadataColumns()
return columns
}

func (d *Domain) ListCabinetMetadataRow(hw inventory.Hardware) (row []string, err error) {
row, err = d.externalInventoryProvider.ListCabinetMetadataRow(hw)
if err != nil {
return row, err
}
return row, nil
}
18 changes: 18 additions & 0 deletions internal/provider/csm/csm.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ package csm

import (
"fmt"
"strconv"
"strings"

"github.com/Cray-HPE/cani/cmd/taxonomy"
"github.com/Cray-HPE/cani/internal/inventory"
"github.com/Cray-HPE/cani/internal/provider/csm/validate"
"github.com/Cray-HPE/cani/pkg/hardwaretypes"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -198,3 +200,19 @@ func (csm *CSM) setupClients() (err error) {

return nil
}

// ListCabinetMetadataColumns returns a slice of strings, which are columns names of CSM-specific metadata to be shown when listing cabinets
func (csm *CSM) ListCabinetMetadataColumns() (columns []string) {
return []string{"HMN VLAN"}
}

// ListCabinetMetadataRow returns a slice of strings, which are values from the hardware that correlate to the columns they will be shown in
func (csm *CSM) ListCabinetMetadataRow(hw inventory.Hardware) (values []string, err error) {
md, err := DecodeProviderMetadata(hw)
if err != nil {
return values, err
}
vlan := strconv.Itoa(*md.Cabinet.HMNVlan)
values = append(values, vlan)
return values, nil
}
4 changes: 4 additions & 0 deletions internal/provider/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ type InventoryProvider interface {

// Return metadata about each field
GetFieldMetadata() ([]FieldMetadata, error)

// Workflows
ListCabinetMetadataColumns() (columns []string)
ListCabinetMetadataRow(inventory.Hardware) (values []string, err error)
}

type HardwareValidationResult struct {
Expand Down

0 comments on commit c93ebee

Please sign in to comment.