124 lines
3.0 KiB
Go
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)
|
|
}
|