Files
ubiquiti-clients/cmd/cmd/get_devices.go
2026-01-17 17:06:32 -05:00

124 lines
3.0 KiB
Go

package cmd
import (
"context"
"fmt"
"os"
"sync"
"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/cmd/internal/config"
"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/cmd/internal/util"
"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/edgeos"
"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/toughswitch"
"github.com/spf13/cobra"
)
var devicesCmd = &cobra.Command{
Use: "devices",
Short: "Get information from all configured devices",
Long: `Get information from all configured devices in parallel.`,
RunE: runGetDevices,
}
func init() {
getCmd.AddCommand(devicesCmd)
}
// DeviceResult holds the result of fetching a single device.
type DeviceResult struct {
Name string `yaml:"name"`
Type string `yaml:"type"`
Host string `yaml:"host"`
Data any `yaml:"data,omitempty"`
Error string `yaml:"error,omitempty"`
Failed bool `yaml:"failed,omitempty"`
}
func runGetDevices(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
conf := util.ConfigFromContext(ctx)
logger := util.LoggerFromContext(ctx)
pretty, _ := cmd.Flags().GetBool(util.FLAG_PRETTY)
colorize, _ := cmd.Flags().GetBool(util.FLAG_COLOR)
if len(conf.Clients) == 0 {
return fmt.Errorf("no devices configured")
}
logger.Debug().Int("count", len(conf.Clients)).Msg("fetching all devices")
results := make([]DeviceResult, len(conf.Clients))
var wg sync.WaitGroup
var mu sync.Mutex
for i, clientConf := range conf.Clients {
wg.Add(1)
go func(idx int, cc config.ClientConfig) {
defer wg.Done()
result := DeviceResult{
Name: cc.Name,
Type: string(cc.Type),
Host: cc.Host,
}
var data any
var err error
switch cc.Type {
case config.TypeToughSwitch:
data, err = fetchToughSwitch(ctx, &cc)
case config.TypeEdgeOS:
data, err = fetchEdgeOS(ctx, &cc)
default:
err = fmt.Errorf("unknown device type: %s", cc.Type)
}
if err != nil {
result.Error = err.Error()
result.Failed = true
logger.Error().Err(err).Str("device", cc.Name).Msg("failed to fetch device")
} else {
result.Data = data
}
mu.Lock()
results[idx] = result
mu.Unlock()
}(i, clientConf)
}
wg.Wait()
return util.YAMLOutput(os.Stdout, results, pretty, colorize)
}
func fetchToughSwitch(ctx context.Context, clientConf *config.ClientConfig) (any, error) {
cfg := toughswitch.Config{
Host: clientConf.Host,
Scheme: clientConf.Scheme,
Insecure: clientConf.Insecure,
Username: clientConf.User,
Password: clientConf.Pass,
Timeout: clientConf.Timeout,
}
client := toughswitch.MustNew(ctx, []toughswitch.Config{cfg})
return client.GetDevice(ctx, clientConf.Host)
}
func fetchEdgeOS(ctx context.Context, clientConf *config.ClientConfig) (any, error) {
cfg := edgeos.Config{
Host: clientConf.Host,
Scheme: clientConf.Scheme,
Insecure: clientConf.Insecure,
Username: clientConf.User,
Password: clientConf.Pass,
Timeout: clientConf.Timeout,
}
client := edgeos.MustNew(ctx, []edgeos.Config{cfg})
return client.GetConfig(ctx, clientConf.Host)
}