From f7159c9b661796feb6741c2b62e839f0a42dd0dd Mon Sep 17 00:00:00 2001 From: "David J. Allen" Date: Sun, 11 Aug 2024 14:25:21 -0600 Subject: [PATCH] Fixed issue with collect requests and other minor changes --- cmd/collect.go | 18 +++++------ cmd/root.go | 5 ++- config.yaml | 2 +- internal/collect.go | 77 +++++++++++++++++++++------------------------ internal/scan.go | 2 +- 5 files changed, 49 insertions(+), 55 deletions(-) diff --git a/cmd/collect.go b/cmd/collect.go index af4df5e..26ed293 100644 --- a/cmd/collect.go +++ b/cmd/collect.go @@ -7,7 +7,6 @@ import ( magellan "github.com/OpenCHAMI/magellan/internal" "github.com/OpenCHAMI/magellan/internal/cache/sqlite" "github.com/OpenCHAMI/magellan/internal/util" - "github.com/OpenCHAMI/magellan/pkg/client" "github.com/cznic/mathutil" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -51,9 +50,10 @@ var collectCmd = &cobra.Command{ // if concurrency <= 0 { - concurrency = mathutil.Clamp(len(scannedResults), 1, 255) + concurrency = mathutil.Clamp(len(scannedResults), 1, 10000) } err = magellan.CollectInventory(&scannedResults, &magellan.CollectParams{ + URI: host, Username: username, Password: password, Timeout: timeout, @@ -72,14 +72,14 @@ var collectCmd = &cobra.Command{ func init() { currentUser, _ = user.Current() - collectCmd.PersistentFlags().StringVar(&client.Host, "host", "", "set the host:port to the SMD API") - collectCmd.PersistentFlags().StringVar(&username, "username", "", "set the BMC user") - collectCmd.PersistentFlags().StringVar(&password, "password", "", "set the BMC password") - collectCmd.PersistentFlags().StringVar(&scheme, "scheme", "https", "set the scheme used to query") - collectCmd.PersistentFlags().StringVar(&protocol, "protocol", "tcp", "set the protocol used to query") + collectCmd.PersistentFlags().StringVar(&host, "host", "", "Set the URI to the SMD API") + collectCmd.PersistentFlags().StringVar(&username, "username", "", "Set the BMC user") + collectCmd.PersistentFlags().StringVar(&password, "password", "", "Set the BMC password") + collectCmd.PersistentFlags().StringVar(&scheme, "scheme", "https", "Set the scheme used to query") + collectCmd.PersistentFlags().StringVar(&protocol, "protocol", "tcp", "Set the protocol used to query") collectCmd.PersistentFlags().StringVarP(&outputPath, "output", "o", fmt.Sprintf("/tmp/%smagellan/inventory/", currentUser.Username+"/"), "set the path to store collection data") - collectCmd.PersistentFlags().BoolVar(&forceUpdate, "force-update", false, "set flag to force update data sent to SMD") - collectCmd.PersistentFlags().StringVar(&cacertPath, "cacert", "", "path to CA cert. (defaults to system CAs)") + collectCmd.PersistentFlags().BoolVar(&forceUpdate, "force-update", false, "Set flag to force update data sent to SMD") + collectCmd.PersistentFlags().StringVar(&cacertPath, "cacert", "", "Path to CA cert. (defaults to system CAs)") // set flags to only be used together collectCmd.MarkFlagsRequiredTogether("username", "password") diff --git a/cmd/root.go b/cmd/root.go index 55365cd..a761f7d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,7 +21,6 @@ import ( "os/user" magellan "github.com/OpenCHAMI/magellan/internal" - "github.com/OpenCHAMI/magellan/pkg/client" "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -112,14 +111,14 @@ func SetDefaults() { viper.SetDefault("config", "") viper.SetDefault("verbose", false) viper.SetDefault("debug", false) - viper.SetDefault("cache", fmt.Sprintf("/tmp/%s/magellan/magellan.db", currentUser.Username)) + viper.SetDefault("cache", fmt.Sprintf("/tmp/%s/magellan/assets.db", currentUser.Username)) viper.SetDefault("scan.hosts", []string{}) viper.SetDefault("scan.ports", []int{}) viper.SetDefault("scan.subnets", []string{}) viper.SetDefault("scan.subnet-masks", []net.IP{}) viper.SetDefault("scan.disable-probing", false) viper.SetDefault("collect.driver", []string{"redfish"}) - viper.SetDefault("collect.host", client.Host) + viper.SetDefault("collect.host", host) viper.SetDefault("collect.user", "") viper.SetDefault("collect.pass", "") viper.SetDefault("collect.protocol", "tcp") diff --git a/config.yaml b/config.yaml index 11b0c28..7d817ed 100644 --- a/config.yaml +++ b/config.yaml @@ -26,7 +26,7 @@ update: port: 443 username: "admin" password: "password" - transfer-protocol: "HTTPS" + transfer-protocol: "https" firmware: url: version: diff --git a/internal/collect.go b/internal/collect.go index 6f01199..79f873e 100644 --- a/internal/collect.go +++ b/internal/collect.go @@ -21,17 +21,10 @@ import ( "golang.org/x/exp/slices" ) -const ( - IPMI_PORT = 623 - SSH_PORT = 22 - HTTPS_PORT = 443 -) - // CollectParams is a collection of common parameters passed to the CLI // for the 'collect' subcommand. type CollectParams struct { - Host string // set by the 'host' flag - Port int // set by the 'port' flag + URI string // set by the 'host' flag Username string // set the BMC username with the 'username' flag Password string // set the BMC password with the 'password' flag Concurrency int // set the of concurrent jobs with the 'concurrency' flag @@ -48,38 +41,38 @@ type CollectParams struct { // // Requests can be made to several of the nodes using a goroutine by setting the q.Concurrency // property value between 1 and 255. -func CollectInventory(scannedResults *[]RemoteAsset, params *CollectParams) error { +func CollectInventory(assets *[]RemoteAsset, params *CollectParams) error { // check for available probe states - if scannedResults == nil { - return fmt.Errorf("no probe states found") + if assets == nil { + return fmt.Errorf("no assets found") } - if len(*scannedResults) <= 0 { - return fmt.Errorf("no probe states found") + if len(*assets) <= 0 { + return fmt.Errorf("no assets found") } // collect bmc information asynchronously var ( - offset = 0 - wg sync.WaitGroup - found = make([]string, 0, len(*scannedResults)) - done = make(chan struct{}, params.Concurrency+1) - chanScannedResult = make(chan RemoteAsset, params.Concurrency+1) - outputPath = path.Clean(params.OutputPath) - smdClient = client.NewClient[client.SmdClient]( + offset = 0 + wg sync.WaitGroup + found = make([]string, 0, len(*assets)) + done = make(chan struct{}, params.Concurrency+1) + chanAssets = make(chan RemoteAsset, params.Concurrency+1) + outputPath = path.Clean(params.OutputPath) + smdClient = client.NewClient[client.SmdClient]( client.WithSecureTLS[client.SmdClient](params.CaCertPath), ) ) + // set the client's host from the CLI param + smdClient.URI = params.URI wg.Add(params.Concurrency) for i := 0; i < params.Concurrency; i++ { go func() { for { - sr, ok := <-chanScannedResult + sr, ok := <-chanAssets if !ok { wg.Done() return } - params.Host = sr.Host - params.Port = sr.Port // generate custom xnames for bmcs node := xnames.Node{ @@ -142,7 +135,7 @@ func CollectInventory(scannedResults *[]RemoteAsset, params *CollectParams) erro log.Error().Err(err).Msg("failed to make output directory") } else { // write the output to the final path - err = os.WriteFile(path.Clean(fmt.Sprintf("%s/%s/%d.json", params.Host, outputPath, time.Now().Unix())), body, os.ModePerm) + err = os.WriteFile(path.Clean(fmt.Sprintf("%s/%s/%d.json", params.URI, outputPath, time.Now().Unix())), body, os.ModePerm) if err != nil { log.Error().Err(err).Msgf("failed to write data to file") } @@ -151,19 +144,25 @@ func CollectInventory(scannedResults *[]RemoteAsset, params *CollectParams) erro } } - // add all endpoints to smd - err = smdClient.Add(body, headers) - if err != nil { - log.Error().Err(err).Msgf("failed to add Redfish endpoint") + // add all endpoints to SMD ONLY if a host is provided + if smdClient.URI != "" { + err = smdClient.Add(body, headers) + if err != nil { + log.Error().Err(err).Msgf("failed to add Redfish endpoint") - // try updating instead - if params.ForceUpdate { - smdClient.Xname = data["ID"].(string) - err = smdClient.Update(body, headers) - if err != nil { - log.Error().Err(err).Msgf("failed to update Redfish endpoint") + // try updating instead + if params.ForceUpdate { + smdClient.Xname = data["ID"].(string) + err = smdClient.Update(body, headers) + if err != nil { + log.Error().Err(err).Msgf("failed to forcibly update Redfish endpoint") + } } } + } else { + if params.Verbose { + log.Warn().Msg("no request made (host argument is empty)") + } } // got host information, so add to list of already probed hosts @@ -173,13 +172,13 @@ func CollectInventory(scannedResults *[]RemoteAsset, params *CollectParams) erro } // use the found results to query bmc information - for _, ps := range *scannedResults { + for _, ps := range *assets { // skip if found info from host foundHost := slices.Index(found, ps.Host) if !ps.State || foundHost >= 0 { continue } - chanScannedResult <- ps + chanAssets <- ps } // handle goroutine paths @@ -193,13 +192,9 @@ func CollectInventory(scannedResults *[]RemoteAsset, params *CollectParams) erro } }() - close(chanScannedResult) + close(chanAssets) wg.Wait() close(done) return nil } - -func baseRedfishUrl(q *CollectParams) string { - return fmt.Sprintf("%s:%d", q.Host, q.Port) -} diff --git a/internal/scan.go b/internal/scan.go index 3ac6129..bdcc5ef 100644 --- a/internal/scan.go +++ b/internal/scan.go @@ -170,7 +170,7 @@ func GenerateHostsWithSubnet(subnet string, subnetMask *net.IPMask, additionalPo // GetDefaultPorts() returns a list of default ports. The only reason to have // this function is to add/remove ports without affecting usage. func GetDefaultPorts() []int { - return []int{HTTPS_PORT} + return []int{443} } // rawConnect() tries to connect to the host using DialTimeout() and waits