From b5c0d9ce2af65c4d09b168b8c82087aec3af9c60 Mon Sep 17 00:00:00 2001 From: "David J. Allen" Date: Mon, 6 May 2024 14:01:29 -0600 Subject: [PATCH] Changed cert flags and added cert for gofish --- cmd/collect.go | 25 +++++++-------- cmd/root.go | 3 +- cmd/update.go | 18 +++++------ internal/collect.go | 77 +++++++++++++++++++++++++++++++-------------- 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/cmd/collect.go b/cmd/collect.go index cb7f230..1855cbb 100644 --- a/cmd/collect.go +++ b/cmd/collect.go @@ -41,17 +41,17 @@ var collectCmd = &cobra.Command{ threads = mathutil.Clamp(len(probeStates), 1, 255) } q := &magellan.QueryParams{ - User: user, - Pass: pass, - Protocol: protocol, - Drivers: drivers, - Preferred: preferredDriver, - Timeout: timeout, - Threads: threads, - Verbose: verbose, - WithSecureTLS: withSecureTLS, - OutputPath: outputPath, - ForceUpdate: forceUpdate, + User: user, + Pass: pass, + Protocol: protocol, + Drivers: drivers, + Preferred: preferredDriver, + Timeout: timeout, + Threads: threads, + Verbose: verbose, + CaCertPath: cacertPath, + OutputPath: outputPath, + ForceUpdate: forceUpdate, } magellan.CollectAll(&probeStates, l, q) @@ -74,7 +74,6 @@ func init() { collectCmd.PersistentFlags().BoolVar(&forceUpdate, "force-update", false, "set flag to force update data sent to SMD ") collectCmd.PersistentFlags().StringVar(&preferredDriver, "preferred-driver", "ipmi", "set the preferred driver to use") collectCmd.PersistentFlags().StringVar(&ipmitoolPath, "ipmitool.path", "/usr/bin/ipmitool", "set the path for ipmitool") - collectCmd.PersistentFlags().BoolVar(&withSecureTLS, "secure-tls", false, "enable secure TLS") - collectCmd.PersistentFlags().StringVar(&certPoolFile, "cert-pool", "", "path to CA cert. (defaults to system CAs; used with --secure-tls=true)") + collectCmd.PersistentFlags().StringVar(&cacertPath, "ca-cert", "", "path to CA cert. (defaults to system CAs; used with --secure-tls=true)") rootCmd.AddCommand(collectCmd) } diff --git a/cmd/root.go b/cmd/root.go index e0e31de..dc5bb2d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,8 +14,7 @@ var ( ports []int hosts []string protocol string - withSecureTLS bool - certPoolFile string + cacertPath string user string pass string dbpath string diff --git a/cmd/update.go b/cmd/update.go index 94ccd71..f0ca82e 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -28,15 +28,14 @@ var updateCmd = &cobra.Command{ Component: component, TransferProtocol: transferProtocol, QueryParams: magellan.QueryParams{ - Drivers: []string{"redfish"}, - Preferred: "redfish", - Protocol: protocol, - Host: host, - User: user, - Pass: pass, - Timeout: timeout, - Port: port, - WithSecureTLS: withSecureTLS, + Drivers: []string{"redfish"}, + Preferred: "redfish", + Protocol: protocol, + Host: host, + User: user, + Pass: pass, + Timeout: timeout, + Port: port, }, } @@ -76,7 +75,6 @@ func init() { updateCmd.Flags().StringVar(&firmwareUrl, "firmware-url", "", "set the path to the firmware") updateCmd.Flags().StringVar(&firmwareVersion, "firmware-version", "", "set the version of firmware to be installed") updateCmd.Flags().StringVar(&component, "component", "", "set the component to upgrade") - updateCmd.Flags().BoolVar(&withSecureTLS, "secure-tls", false, "enable secure TLS") updateCmd.Flags().BoolVar(&status, "status", false, "get the status of the update") rootCmd.AddCommand(updateCmd) } diff --git a/internal/collect.go b/internal/collect.go index 5686066..4a2189a 100644 --- a/internal/collect.go +++ b/internal/collect.go @@ -35,25 +35,25 @@ const ( // NOTE: ...params were getting too long... type QueryParams struct { - Host string - Port int - Protocol string - User string - Pass string - Drivers []string - Threads int - Preferred string - Timeout int - WithSecureTLS bool - CertPoolFile string - Verbose bool - IpmitoolPath string - OutputPath string - ForceUpdate bool - AccessToken string + Host string + Port int + Protocol string + User string + Pass string + Drivers []string + Threads int + Preferred string + Timeout int + CaCertPath string + Verbose bool + IpmitoolPath string + OutputPath string + ForceUpdate bool + AccessToken string } func NewClient(l *log.Logger, q *QueryParams) (*bmclib.Client, error) { + tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } @@ -75,9 +75,9 @@ func NewClient(l *log.Logger, q *QueryParams) (*bmclib.Client, error) { } // only work if valid cert is provided - if q.WithSecureTLS && q.CertPoolFile != "" { + if q.CaCertPath != "" { pool := x509.NewCertPool() - data, err := os.ReadFile(q.CertPoolFile) + data, err := os.ReadFile(q.CaCertPath) if err != nil { return nil, fmt.Errorf("could not read cert pool file: %v", err) } @@ -557,10 +557,12 @@ func CollectProcessors(q *QueryParams) ([]byte, error) { } func connectGofish(q *QueryParams) (*gofish.APIClient, error) { - config := makeGofishConfig(q) + config, err := makeGofishConfig(q) + if err != nil { + return nil, fmt.Errorf("failed to make gofish config: %v", err) + } c, err := gofish.Connect(config) if err != nil { - return nil, fmt.Errorf("could not connect to redfish endpoint: %v", err) } if c != nil { @@ -574,15 +576,42 @@ func connectGofish(q *QueryParams) (*gofish.APIClient, error) { return c, err } -func makeGofishConfig(q *QueryParams) gofish.ClientConfig { - url := baseRedfishUrl(q) +func makeGofishConfig(q *QueryParams) (gofish.ClientConfig, error) { + var ( + client = &http.Client{} + url = baseRedfishUrl(q) + config = gofish.ClientConfig{ + Endpoint: url, + Username: q.User, + Password: q.Pass, + Insecure: q.CaCertPath == "", + TLSHandshakeTimeout: q.Timeout, + HTTPClient: client, + // MaxConcurrentRequests: int64(q.Threads), // NOTE: this was added in latest gofish + } + ) + if q.CaCertPath != "" { + cacert, err := os.ReadFile(q.CaCertPath) + if err != nil { + return config, fmt.Errorf("failed to read CA cert file: %v", err) + } + certPool := x509.NewCertPool() + certPool.AppendCertsFromPEM(cacert) + client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certPool, + }, + } + } return gofish.ClientConfig{ Endpoint: url, Username: q.User, Password: q.Pass, - Insecure: !q.WithSecureTLS, + Insecure: q.CaCertPath == "", TLSHandshakeTimeout: q.Timeout, - } + HTTPClient: client, + // MaxConcurrentRequests: int64(q.Threads), // NOTE: this was added in latest gofish + }, nil } func makeRequest[T any](client *bmclib.Client, fn func(context.Context) (T, error), timeout int) ([]byte, error) {