Skip to content

Commit

Permalink
Fixed issue with collect requests and other minor changes
Browse files Browse the repository at this point in the history
  • Loading branch information
davidallendj committed Aug 11, 2024
1 parent a6c95ef commit f7159c9
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 55 deletions.
18 changes: 9 additions & 9 deletions cmd/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand All @@ -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")
Expand Down
5 changes: 2 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ update:
port: 443
username: "admin"
password: "password"
transfer-protocol: "HTTPS"
transfer-protocol: "https"
firmware:
url:
version:
Expand Down
77 changes: 36 additions & 41 deletions internal/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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{
Expand Down Expand Up @@ -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")
}
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
}
2 changes: 1 addition & 1 deletion internal/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit f7159c9

Please sign in to comment.