Added initial round of comments for API documentation

This commit is contained in:
David Allen 2024-07-18 18:18:03 -06:00
parent 796a67d5ab
commit 1ab5c8a7df
No known key found for this signature in database
GPG key ID: 717C593FF60A2ACC
5 changed files with 114 additions and 13 deletions

View file

@ -1,3 +1,4 @@
// Package magellan implements the core routines for the tools.
package magellan
import (
@ -50,6 +51,11 @@ type QueryParams struct {
AccessToken string
}
// This is the main function used to collect information from the BMC nodes via Redfish.
// The function expects a list of hosts found using the `ScanForAssets()` function.
//
// Requests can be made to several of the nodes using a goroutine by setting the q.Concurrency
// property value between 1 and 255.
func CollectAll(probeStates *[]ScannedResult, l *log.Logger, q *QueryParams) error {
// check for available probe states
if probeStates == nil {
@ -102,6 +108,7 @@ func CollectAll(probeStates *[]ScannedResult, l *log.Logger, q *QueryParams) err
if err != nil {
l.Log.Errorf("failed to connect to BMC (%v:%v): %v", q.Host, q.Port, err)
}
defer gofishClient.Logout()
// data to be sent to smd
data := map[string]any{
@ -218,6 +225,7 @@ func CollectAll(probeStates *[]ScannedResult, l *log.Logger, q *QueryParams) err
return nil
}
// TODO: DELETE ME!!!
func CollectMetadata(client *bmclib.Client, q *QueryParams) ([]byte, error) {
// open BMC session and update driver registry
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout))
@ -275,6 +283,7 @@ func CollectInventory(client *bmclib.Client, q *QueryParams) ([]byte, error) {
return b, nil
}
// TODO: DELETE ME!!!
func CollectPowerState(client *bmclib.Client, q *QueryParams) ([]byte, error) {
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout))
client.Registry.FilterForCompatible(ctx)
@ -303,6 +312,7 @@ func CollectPowerState(client *bmclib.Client, q *QueryParams) ([]byte, error) {
}
// TODO: DELETE ME!!!
func CollectUsers(client *bmclib.Client, q *QueryParams) ([]byte, error) {
// open BMC session and update driver registry
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout))
@ -333,11 +343,18 @@ func CollectUsers(client *bmclib.Client, q *QueryParams) ([]byte, error) {
return b, nil
}
// TODO: DELETE ME!!!q
func CollectBios(client *bmclib.Client, q *QueryParams) ([]byte, error) {
b, err := makeRequest(client, client.GetBiosConfiguration, q.Timeout)
return b, err
}
// CollectEthernetInterfaces() collects all of the ethernet interfaces found
// from all systems from under the "/redfish/v1/Systems" endpoint.
//
// TODO: This function needs to be refactored entirely...if not deleted
// in favor of using crawler.CrawlBM() instead.
func CollectEthernetInterfaces(c *gofish.APIClient, q *QueryParams, systemID string) ([]byte, error) {
// TODO: add more endpoints to test for ethernet interfaces
// /redfish/v1/Chassis/{ChassisID}/NetworkAdapters/{NetworkAdapterId}/NetworkDeviceFunctions/{NetworkDeviceFunctionId}/EthernetInterfaces/{EthernetInterfaceId}
@ -380,6 +397,7 @@ func CollectEthernetInterfaces(c *gofish.APIClient, q *QueryParams, systemID str
return b, nil
}
// TODO: DELETE ME!!!
func CollectChassis(c *gofish.APIClient, q *QueryParams) ([]map[string]any, error) {
rfChassis, err := c.Service.Chassis()
if err != nil {
@ -402,6 +420,7 @@ func CollectChassis(c *gofish.APIClient, q *QueryParams) ([]map[string]any, erro
return chassis, nil
}
// TODO: DELETE ME!!!
func CollectStorage(c *gofish.APIClient, q *QueryParams) ([]byte, error) {
systems, err := c.Service.StorageSystems()
if err != nil {
@ -427,19 +446,23 @@ func CollectStorage(c *gofish.APIClient, q *QueryParams) ([]byte, error) {
return b, nil
}
// CollectSystems pulls system information from each BMC node via Redfish using the
// `gofish` library.
//
// The process of collecting this info is as follows:
// 1. check if system has ethernet interfaces
// 1.a. if yes, create system data and ethernet interfaces JSON
// 1.b. if no, try to get data using manager instead
// 2. check if manager has "ManagerForServices" and "EthernetInterfaces" properties
// 2.a. if yes, query both properties to use in next step
// 2.b. for each service, query its data and add the ethernet interfaces
// 2.c. add the system to list of systems to marshal and return
func CollectSystems(c *gofish.APIClient, q *QueryParams) ([]map[string]any, error) {
rfSystems, err := c.Service.Systems()
if err != nil {
return nil, fmt.Errorf("failed to get systems (%v:%v): %v", q.Host, q.Port, err)
}
// 1. check if system has ethernet interfaces
// 1.a. if yes, create system data and ethernet interfaces JSON
// 1.b. if no, try to get data using manager instead
// 2. check if manager has "ManagerForServices" and "EthernetInterfaces" properties
// 2.a. if yes, query both properties to use in next step
// 2.b. for each service, query its data and add the ethernet interfaces
// 2.c. add the system to list of systems to marshal and return
var systems []map[string]any
for _, system := range rfSystems {
@ -605,6 +628,7 @@ func CollectSystems(c *gofish.APIClient, q *QueryParams) ([]map[string]any, erro
return systems, nil
}
// TODO: DELETE ME!!!
func CollectRegisteries(c *gofish.APIClient, q *QueryParams) ([]byte, error) {
registries, err := c.Service.Registries()
if err != nil {
@ -620,6 +644,7 @@ func CollectRegisteries(c *gofish.APIClient, q *QueryParams) ([]byte, error) {
return b, nil
}
// TODO: MAYBE DELETE???
func CollectProcessors(q *QueryParams) ([]byte, error) {
url := baseRedfishUrl(q) + "/Systems"
res, body, err := util.MakeRequest(nil, url, "GET", nil, nil)

View file

@ -13,6 +13,11 @@ import (
"time"
)
// PathExists() is a wrapper function that simplifies checking
// if a file or directory already exists at the provided path.
//
// Returns whether the path exists and no error if successful,
// otherwise, it returns false with an error.
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
@ -24,6 +29,8 @@ func PathExists(path string) (bool, error) {
return false, err
}
// GetNextIP() returns the next IP address, but does not account
// for net masks.
func GetNextIP(ip *net.IP, inc uint) *net.IP {
if ip == nil {
return &net.IP{}
@ -40,7 +47,14 @@ func GetNextIP(ip *net.IP, inc uint) *net.IP {
return &r
}
// Generic convenience function used to make HTTP requests.
// MakeRequest() is a wrapper function that condenses simple HTTP
// requests done to a single call. It expects an optional HTTP client,
// URL, HTTP method, request body, and request headers. This function
// is useful when making many requests where only these few arguments
// are changing.
//
// Returns a HTTP response object, response body as byte array, and any
// error that may have occurred with making the request.
func MakeRequest(client *http.Client, url string, httpMethod string, body []byte, headers map[string]string) (*http.Response, []byte, error) {
// use defaults if no client provided
if client == nil {
@ -69,6 +83,12 @@ func MakeRequest(client *http.Client, url string, httpMethod string, body []byte
return res, b, err
}
// MakeOutputDirectory() creates a new directory at the path argument if
// the path does not exist
//
// TODO: Refactor this function for hive partitioning or possibly move into
// the logging package.
// TODO: Add an option to force overwriting the path.
func MakeOutputDirectory(path string) (string, error) {
// get the current data + time using Go's stupid formatting
t := time.Now()
@ -93,12 +113,27 @@ func MakeOutputDirectory(path string) (string, error) {
return final, nil
}
// SplitPathForViper() is an utility function to split a path into 3 parts:
// - directory
// - filename
// - extension
// The intent was to break a path into a format that's more easily consumable
// by spf13/viper's API. See the "LoadConfig()" function in internal/config.go
// for more details.
//
// TODO: Rename function to something more generalized.
func SplitPathForViper(path string) (string, string, string) {
filename := filepath.Base(path)
ext := filepath.Ext(filename)
return filepath.Dir(path), strings.TrimSuffix(filename, ext), strings.TrimPrefix(ext, ".")
}
// FormatErrorList() is a wrapper function that unifies error list formatting
// and makes printing error lists consistent.
//
// NOTE: The error returned IS NOT an error in itself and may be a bit misleading.
// Instead, it is a single condensed error composed of all of the errors included
// in the errList argument.
func FormatErrorList(errList []error) error {
var err error
for i, e := range errList {
@ -108,6 +143,9 @@ func FormatErrorList(errList []error) error {
return err
}
// HasErrors() is a simple wrapper function to check if an error list contains
// errors. Having a function that clearly states its purpose helps to improve
// readibility although it may seem pointless.
func HasErrors(errList []error) bool {
return len(errList) > 0
}