From 3b297351ecb69d6fa1958f067f182c1f4c1df115 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 14:30:03 -0600 Subject: [PATCH 1/6] Fixed panic when setting --cacert from invalid client --- pkg/client/client.go | 12 ++++++++++-- pkg/client/smd.go | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 0005254..06a2632 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -9,6 +9,8 @@ import ( "net/http" "os" "time" + + "github.com/rs/zerolog/log" ) type Option[T Client] func(client T) @@ -18,7 +20,7 @@ type Option[T Client] func(client T) // It also provides functions that work with `collect` data. type Client interface { Name() string - GetClient() *http.Client + GetInternalClient() *http.Client RootEndpoint(endpoint string) string // functions needed to make request @@ -36,11 +38,17 @@ func NewClient[T Client](opts ...func(T)) T { } func WithCertPool[T Client](certPool *x509.CertPool) func(T) { + // make sure we have a valid cert pool if certPool == nil { return func(client T) {} } return func(client T) { - client.GetClient().Transport = &http.Transport{ + // make sure that we can access the internal client + if client.GetInternalClient() == nil { + log.Warn().Msg("internal client is invalid") + return + } + client.GetInternalClient().Transport = &http.Transport{ TLSClientConfig: &tls.Config{ RootCAs: certPool, InsecureSkipVerify: true, diff --git a/pkg/client/smd.go b/pkg/client/smd.go index a118460..443d445 100644 --- a/pkg/client/smd.go +++ b/pkg/client/smd.go @@ -16,6 +16,10 @@ type SmdClient struct { Xname string } +func (c SmdClient) Init() { + c.Client = &http.Client{} +} + func (c SmdClient) Name() string { return "smd" } From abd83454ad144a18f6112959a27c7f8abcc9f8ef Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 14:38:03 -0600 Subject: [PATCH 2/6] Added Init() to Client interface --- pkg/client/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/client/client.go b/pkg/client/client.go index 06a2632..5952523 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -19,6 +19,7 @@ type Option[T Client] func(client T) // that provides an extended API to work with functional options. // It also provides functions that work with `collect` data. type Client interface { + Init() Name() string GetInternalClient() *http.Client RootEndpoint(endpoint string) string From 5d811f31abe64e2f3ec7a15cf1f667b61f4bb2b6 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 14:40:23 -0600 Subject: [PATCH 3/6] Changed interface func from GetClient() to GetInternalClient() --- pkg/client/smd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/client/smd.go b/pkg/client/smd.go index 443d445..520520f 100644 --- a/pkg/client/smd.go +++ b/pkg/client/smd.go @@ -28,7 +28,7 @@ func (c SmdClient) RootEndpoint(endpoint string) string { return fmt.Sprintf("%s/hsm/v2%s", c.URI, endpoint) } -func (c SmdClient) GetClient() *http.Client { +func (c SmdClient) GetInternalClient() *http.Client { return c.Client } From e3ef9d4276af1dd81ce18ca2af0332d5c71c9335 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 15:40:43 -0600 Subject: [PATCH 4/6] Fixed field tag in crawler --- pkg/crawler/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/crawler/main.go b/pkg/crawler/main.go index 78af9f9..e28cb1b 100644 --- a/pkg/crawler/main.go +++ b/pkg/crawler/main.go @@ -45,7 +45,7 @@ type InventoryDetail struct { URI string `json:"uri,omitempty"` // URI of the BMC UUID string `json:"uuid,omitempty"` // UUID of Node Manufacturer string `json:"manufacturer,omitempty"` // Manufacturer of the Node - SystemType string `json:"system_type,omitempty` // System type of the Node + SystemType string `json:"system_type,omitempty"` // System type of the Node Name string `json:"name,omitempty"` // Name of the Node Model string `json:"model,omitempty"` // Model of the Node Serial string `json:"serial,omitempty"` // Serial number of the Node From 9991f02631a493ae91f153c5ee1bdd0100cfe904 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 15:55:16 -0600 Subject: [PATCH 5/6] Updated warning message and changed SMD client to use pointer receivers --- internal/collect.go | 2 +- pkg/client/client.go | 6 +++--- pkg/client/smd.go | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/collect.go b/internal/collect.go index ea7ca69..49cb449 100644 --- a/internal/collect.go +++ b/internal/collect.go @@ -59,7 +59,7 @@ func CollectInventory(assets *[]RemoteAsset, params *CollectParams) error { chanAssets = make(chan RemoteAsset, params.Concurrency+1) outputPath = path.Clean(params.OutputPath) smdClient = client.NewClient( - client.WithSecureTLS[client.SmdClient](params.CaCertPath), + client.WithSecureTLS[*client.SmdClient](params.CaCertPath), ) ) // set the client's host from the CLI param diff --git a/pkg/client/client.go b/pkg/client/client.go index 5952523..eda049b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -13,7 +13,7 @@ import ( "github.com/rs/zerolog/log" ) -type Option[T Client] func(client T) +type Option[T Client] func(client *T) // The 'Client' struct is a wrapper around the default http.Client // that provides an extended API to work with functional options. @@ -21,8 +21,8 @@ type Option[T Client] func(client T) type Client interface { Init() Name() string - GetInternalClient() *http.Client RootEndpoint(endpoint string) string + GetInternalClient() *http.Client // functions needed to make request Add(data HTTPBody, headers HTTPHeader) error @@ -46,7 +46,7 @@ func WithCertPool[T Client](certPool *x509.CertPool) func(T) { return func(client T) { // make sure that we can access the internal client if client.GetInternalClient() == nil { - log.Warn().Msg("internal client is invalid") + log.Warn().Any("client", client.GetInternalClient()).Msg("invalid internal HTTP client ()") return } client.GetInternalClient().Transport = &http.Transport{ diff --git a/pkg/client/smd.go b/pkg/client/smd.go index 520520f..499a72c 100644 --- a/pkg/client/smd.go +++ b/pkg/client/smd.go @@ -16,26 +16,26 @@ type SmdClient struct { Xname string } -func (c SmdClient) Init() { +func (c *SmdClient) Init() { c.Client = &http.Client{} } -func (c SmdClient) Name() string { +func (c *SmdClient) Name() string { return "smd" } -func (c SmdClient) RootEndpoint(endpoint string) string { +func (c *SmdClient) RootEndpoint(endpoint string) string { return fmt.Sprintf("%s/hsm/v2%s", c.URI, endpoint) } -func (c SmdClient) GetInternalClient() *http.Client { +func (c *SmdClient) GetInternalClient() *http.Client { return c.Client } // Add() has a similar function definition to that of the default implementation, // but also allows further customization and data/header manipulation that would // be specific and/or unique to SMD's API. -func (c SmdClient) Add(data HTTPBody, headers HTTPHeader) error { +func (c *SmdClient) Add(data HTTPBody, headers HTTPHeader) error { if data == nil { return fmt.Errorf("failed to add redfish endpoint: no data found") } @@ -57,7 +57,7 @@ func (c SmdClient) Add(data HTTPBody, headers HTTPHeader) error { return err } -func (c SmdClient) Update(data HTTPBody, headers HTTPHeader) error { +func (c *SmdClient) Update(data HTTPBody, headers HTTPHeader) error { if data == nil { return fmt.Errorf("failed to add redfish endpoint: no data found") } From 874d750ddef233367203381ee5359c5e786c0cd2 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 27 Aug 2024 17:17:19 -0600 Subject: [PATCH 6/6] Added temporary solution for creating new clients --- internal/collect.go | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/internal/collect.go b/internal/collect.go index 49cb449..8c03050 100644 --- a/internal/collect.go +++ b/internal/collect.go @@ -2,8 +2,12 @@ package magellan import ( + "crypto/tls" + "crypto/x509" "encoding/json" "fmt" + "net" + "net/http" "os" "path" "sync" @@ -58,12 +62,32 @@ func CollectInventory(assets *[]RemoteAsset, params *CollectParams) error { done = make(chan struct{}, params.Concurrency+1) chanAssets = make(chan RemoteAsset, params.Concurrency+1) outputPath = path.Clean(params.OutputPath) - smdClient = client.NewClient( - client.WithSecureTLS[*client.SmdClient](params.CaCertPath), - ) + smdClient = &client.SmdClient{Client: &http.Client{}} ) - // set the client's host from the CLI param + // set the client's params from CLI + // NOTE: temporary solution until client.NewClient() is fixed smdClient.URI = params.URI + if params.CaCertPath != "" { + cacert, err := os.ReadFile(params.CaCertPath) + if err != nil { + return fmt.Errorf("failed to read CA cert path: %w", err) + } + certPool := x509.NewCertPool() + certPool.AppendCertsFromPEM(cacert) + smdClient.Client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certPool, + InsecureSkipVerify: true, + }, + DisableKeepAlives: true, + Dial: (&net.Dialer{ + Timeout: 120 * time.Second, + KeepAlive: 120 * time.Second, + }).Dial, + TLSHandshakeTimeout: 120 * time.Second, + ResponseHeaderTimeout: 120 * time.Second, + } + } wg.Add(params.Concurrency) for i := 0; i < params.Concurrency; i++ { go func() {