Skip to content

Commit

Permalink
SubmitTestEvent is diffrent for some oem vendors and zt event subscri…
Browse files Browse the repository at this point in the history
…ption
  • Loading branch information
nwaizer committed Jul 7, 2022
1 parent 46c07e7 commit 0abe2dd
Show file tree
Hide file tree
Showing 6 changed files with 591 additions and 30 deletions.
53 changes: 53 additions & 0 deletions oem/dell/dell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package dell

import (
"fmt"
"net/http"

"github.com/stmcginnis/gofish/common"
)

const eventContext string = "root"

var SubmitTestEventTarget = "/redfish/v1/EventService/Actions/EventService.SendTestEvent"

type (
PayloadType struct {
Destination string `json:"Destination"`
EventTypes string `json:"EventTypes"`
Context string `json:"Context"`
Protocol string `json:"Protocol"`
MessageID string `json:"MessageId"`
}
)

// SubmitTestEvent sends event according to msgId and returns error.
func SubmitTestEvent(client common.Client, messageID, eType, protocol string) error {
payload := PayloadType{
Destination: SubmitTestEventTarget,
EventTypes: eType,
Context: eventContext,
Protocol: protocol,
MessageID: messageID,
}
resp, err := client.Post(SubmitTestEventTarget, payload)

if err != nil {
return fmt.Errorf("failed to post submitTestEvent due to: %w", err)
}
defer resp.Body.Close()

valid := map[int]bool{
http.StatusNoContent: true,
http.StatusCreated: true}

if !valid[resp.StatusCode] {
return fmt.Errorf("on send event received response: %v due to: %s", resp.StatusCode, resp.Body)
}

return nil
}
167 changes: 167 additions & 0 deletions oem/dell/test/dell_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package test

import (
"encoding/json"
"log"
"net/http"
"net/http/httptest"
"testing"

"github.com/stmcginnis/gofish"
"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/oem/dell"
"github.com/stmcginnis/gofish/redfish"
)

const serviceRootBody = `{
"@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
"@odata.id": "/redfish/v1",
"@odata.type": "#ServiceRoot.v1_8_0.ServiceRoot",
"AccountService": {
"@odata.id": "/redfish/v1/AccountService"
},
"CertificateService": {
"@odata.id": "/redfish/v1/CertificateService"
},
"Chassis": {
"@odata.id": "/redfish/v1/Chassis"
},
"Description": "Root Service",
"EventService": {
"@odata.id": "/redfish/v1/EventService"
},
"Fabrics": {
"@odata.id": "/redfish/v1/Fabrics"
},
"Id": "RootService",
"JobService": {
"@odata.id": "/redfish/v1/JobService"
},
"JsonSchemas": {
"@odata.id": "/redfish/v1/JsonSchemas"
},
"Links": {
"Sessions": {
"@odata.id": "/redfish/v1/SessionService/Sessions"
}
},
"Managers": {
"@odata.id": "/redfish/v1/Managers"
},
"Name": "Root Service",
"Oem": {
"Dell": {
"@odata.context": "/redfish/v1/$metadata#DellServiceRoot.DellServiceRoot",
"@odata.type": "#DellServiceRoot.v1_0_0.DellServiceRoot",
"IsBranded": 0,
"ManagerMACAddress": "00:00:00:00:00:00",
"ServiceTag": "0000000"
}
},
"Product": "Integrated Dell Remote Access Controller",
"ProtocolFeaturesSupported": {
"DeepOperations": {
"DeepPATCH": false,
"DeepPOST": false
},
"ExcerptQuery": false,
"ExpandQuery": {
"ExpandAll": true,
"Levels": true,
"Links": true,
"MaxLevels": 1,
"NoLinks": true
},
"FilterQuery": true,
"OnlyMemberQuery": true,
"SelectQuery": true
},
"RedfishVersion": "1.11.0",
"Registries": {
"@odata.id": "/redfish/v1/Registries"
},
"SessionService": {
"@odata.id": "/redfish/v1/SessionService"
},
"Systems": {
"@odata.id": "/redfish/v1/Systems"
},
"Tasks": {
"@odata.id": "/redfish/v1/TaskService"
},
"TelemetryService": {
"@odata.id": "/redfish/v1/TelemetryService"
},
"UpdateService": {
"@odata.id": "/redfish/v1/UpdateService"
},
"Vendor": "Dell"
}`

func TestDellSubmitTestEvent(t *testing.T) {
const redfishBaseURL = "/redfish/v1/"
var (
c common.Client
err error
requestCounter int // this counter is used to verify that the received requests, are in the expected order
)

// Start a local HTTP server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodGet &&
req.URL.String() == redfishBaseURL &&
requestCounter == 0 { // ServiceRoot
log.Printf("Mock received login request")
contentType := req.Header.Get("Content-Type")
if contentType != "application/json" {
t.Errorf("gofish connect sent wrong header. Content-Type:"+
" is %v and not expected application/json", contentType)
}

requestCounter++

// Send response to be tested
rw.WriteHeader(http.StatusOK)
rw.Header().Set("Content-Type", "application/json")

rw.Write([]byte(serviceRootBody)) // nolint:errcheck
} else if req.Method == http.MethodPost && // SubmitTestEvent
req.URL.String() == dell.SubmitTestEventTarget &&
requestCounter == 1 {
log.Printf("Mock got SubmitTestEvent POST")

err := json.NewDecoder(req.Body).Decode(&dell.PayloadType{})
if err != nil {
t.Errorf("error in SubmitTestEvent payload for Dell due to: %v", err)
}

requestCounter++

rw.WriteHeader(http.StatusCreated)
} else {
t.Errorf("mock got unexpected %v request to path %v while request counter is %v",
req.Method, req.URL.String(), requestCounter)
}
}))
// Close the server when test finishes
defer server.Close()

c, err = gofish.Connect(gofish.ClientConfig{Endpoint: server.URL, HTTPClient: server.Client()})

if err != nil {
t.Errorf("failed to establish client to mock http server due to: %v", err)
}

err = dell.SubmitTestEvent(
c,
"AMP0300",
"Alert",
string(redfish.RedfishEventDestinationProtocol))
if err != nil {
log.Printf("Got error %v", err)
}
}
60 changes: 60 additions & 0 deletions oem/hpe/events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package events

import (
"fmt"
"net/http"
"time"

"github.com/stmcginnis/gofish/common"
)

var (
submitTestEventTarget = "/redfish/v1/EventService/Actions/EventService.SendTestEvent"
)

type hpePayloadType struct {
EventID string `json:"EventID"`
EventTimestamp string `json:"EventTimestamp"`
EventType string `json:"EventType"`
Message string
MessageArgs []string
MessageID string `json:"MessageId"`
OriginOfCondition string
Severity string
}

// SubmitTestEvent sends event according to msgId and returns error
// more info https://hewlettpackard.github.io/iLOAmpPack-Redfish-API-Docs/#submitting-a-test-event
func SubmitTestEvent(client common.Client, msgID string) error {
payload := hpePayloadType{
EventID: "TestEventId",
EventTimestamp: time.Now().Format(time.RFC3339), // "2019-07-29T15:13:49Z",
EventType: "Alert", // redfish.SupportedEventTypes["Alert"],
Message: "Test Event",
MessageArgs: []string{"NoAMS", "Busy", "Cached"},
MessageID: msgID,
OriginOfCondition: "/redfish/v1/Systems/1/",
Severity: "OK",
}
resp, err := client.Post(submitTestEventTarget, payload)

if err != nil {
return fmt.Errorf("failed to send submitTestEvent due to: %w", err)
}
defer resp.Body.Close()

valid := map[int]bool{
http.StatusOK: true,
http.StatusNoContent: true,
http.StatusCreated: true}

if !valid[resp.StatusCode] {
return fmt.Errorf("on send event received response: %v due to: %s", resp.StatusCode, resp.Body)
}

return nil
}
60 changes: 30 additions & 30 deletions oem/hpe/hpe.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@ import (
"github.com/stmcginnis/gofish/redfish"
)

type Fan struct {
redfish.Fan
Oem FanOem
}

type FanOem struct {
Hpe struct {
OdataContext string `json:"@odata.context"`
OdataType string `json:"@odata.type"`
Location string `json:"Location"`
Redundant bool `json:"Redundant"`
HotPluggable bool `json:"HotPluggable"`
} `json:"Hpe"`
}

type Thermal struct {
redfish.Thermal
Fans []Fan
Oem ThermalOem
}

type ThermalOem struct {
Hpe struct {
OdataContext string `json:"@odata.context"`
OdataType string `json:"@odata.type"`
ThermalConfiguration string `json:"ThermalConfiguration"`
FanPercentMinimum int `json:"FanPercentMinimum"`
} `json:"Hpe"`
}

func FromThermal(thermal *redfish.Thermal) (Thermal, error) {
oem := ThermalOem{}

Expand Down Expand Up @@ -43,33 +73,3 @@ func FromFan(fan *redfish.Fan) (Fan, error) {
Oem: oem,
}, nil
}

type Fan struct {
redfish.Fan
Oem FanOem
}

type FanOem struct {
Hpe struct {
OdataContext string `json:"@odata.context"`
OdataType string `json:"@odata.type"`
Location string `json:"Location"`
Redundant bool `json:"Redundant"`
HotPluggable bool `json:"HotPluggable"`
} `json:"Hpe"`
}

type Thermal struct {
redfish.Thermal
Fans []Fan
Oem ThermalOem
}

type ThermalOem struct {
Hpe struct {
OdataContext string `json:"@odata.context"`
OdataType string `json:"@odata.type"`
ThermalConfiguration string `json:"ThermalConfiguration"`
FanPercentMinimum int `json:"FanPercentMinimum"`
} `json:"Hpe"`
}
Loading

0 comments on commit 0abe2dd

Please sign in to comment.