mirror of
https://github.com/davidallendj/magellan.git
synced 2025-12-20 03:27:03 -07:00
Fixed issue with collect requests and other minor changes
This commit is contained in:
parent
a6c95ef646
commit
f7159c9b66
5 changed files with 49 additions and 55 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ update:
|
|||
port: 443
|
||||
username: "admin"
|
||||
password: "password"
|
||||
transfer-protocol: "HTTPS"
|
||||
transfer-protocol: "https"
|
||||
firmware:
|
||||
url:
|
||||
version:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue