Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support redfish #734

Merged
merged 14 commits into from
Jul 18, 2023
2 changes: 1 addition & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ var (
// redfish cred file path
redfishCredFilePath string
redfishProbeIntervalInSeconds = getConfig("REDFISH_PROBE_INTERVAL_IN_SECONDS", "60")
redfishSkipSSLVerify = getBoolConfig("REDFISH_SKIP_SSL_VERIFY", false)
redfishSkipSSLVerify = getBoolConfig("REDFISH_SKIP_SSL_VERIFY", true)

rootfs marked this conversation as resolved.
Show resolved Hide resolved
////////////////////////////////////
ModelServerEnable = getBoolConfig("MODEL_SERVER_ENABLE", false)
Expand Down
2 changes: 1 addition & 1 deletion pkg/power/platform/source/redfish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestRedFishClient_IsPowerSupported(t *testing.T) {
if err := json.NewEncoder(w).Encode(system); err != nil {
fmt.Println(err)
}
} else if r.URL.Path == "/redfish/v1/Chassis/1/Power#/PowerControl" || r.URL.Path == "/redfish/v1/Chassis/2/Power#/PowerControl" {
} else if r.URL.Path == "/redfish/v1/Chassis/1/Power" || r.URL.Path == "/redfish/v1/Chassis/2/Power" {
power := RedfishPowerModel{
Name: "Test Power",
PowerControl: []PowerControl{
Expand Down
36 changes: 31 additions & 5 deletions pkg/power/platform/source/redfish_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
rootfs marked this conversation as resolved.
Show resolved Hide resolved

"github.com/sustainable-computing-io/kepler/pkg/config"
"k8s.io/klog/v2"
)

func getRedfishModel(access RedfishAccessInfo, endpoint string, model interface{}) error {
Expand All @@ -49,6 +51,15 @@ func getRedfishModel(access RedfishAccessInfo, endpoint string, model interface{
defer cancel()
req = req.WithContext(ctx)

// add additional header: 'OData-Version': '4.0'
req.Header.Add("OData-Version", "4.0")
// add accept header: 'application/json'
req.Header.Add("Accept", "application/json")
// set User-Agent header
req.Header.Set("User-Agent", "kepler")
// set keep-alive header
req.Header.Set("Connection", "keep-alive")
// set basic auth
req.SetBasicAuth(username, password)

// Send the request and check the response
Expand All @@ -63,19 +74,33 @@ func getRedfishModel(access RedfishAccessInfo, endpoint string, model interface{
return fmt.Errorf("server returned status: %v", resp.Status)
}

dec := json.NewDecoder(resp.Body)
dec.DisallowUnknownFields()

var returnErr error
// Decode the response body into the provided model struct
err = json.NewDecoder(resp.Body).Decode(model)
if err != nil {
return err
decErr := dec.Decode(model)

// process the error and only return significant ones
if decErr != nil {
if strings.HasPrefix(decErr.Error(), "json: unknown field ") {
// ignore unknown field error
fieldName := strings.TrimPrefix(decErr.Error(), "json: unknown field ")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dell returns some fields that are not defined in the power model, ignore them here

klog.V(6).Infof("Request body contains unknown field %s", fieldName)
} else {
returnErr = decErr
klog.V(5).Infof("Failed to decode response: %v", decErr)
}
}

return nil
return returnErr
}

func getRedfishSystem(access RedfishAccessInfo) (*RedfishSystemModel, error) {
var system RedfishSystemModel
err := getRedfishModel(access, "/redfish/v1/Systems", &system)
if err != nil {
klog.V(1).Infof("Failed to get system: %v", err)
return nil, err
}

Expand All @@ -84,8 +109,9 @@ func getRedfishSystem(access RedfishAccessInfo) (*RedfishSystemModel, error) {

func getRedfishPower(access RedfishAccessInfo, system string) (*RedfishPowerModel, error) {
var power RedfishPowerModel
err := getRedfishModel(access, "/redfish/v1/Chassis/"+system+"/Power%23/PowerControl", &power)
err := getRedfishModel(access, "/redfish/v1/Chassis/"+system+"/Power#/PowerControl", &power)
if err != nil {
klog.V(1).Infof("Failed to get power: %v", err)
return nil, err
}

Expand Down