Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions redfish/internal/controller/http/v1/handler/routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ func (r *TestComputerSystemRepository) UpdateSerialConsoleServiceEnabled(_ conte
return usecase.ErrSystemNotFound
}

func (r *TestComputerSystemRepository) RequestKVMConsent(_ context.Context, systemID string) error {
if _, exists := r.systems[systemID]; exists {
return nil
}

return usecase.ErrSystemNotFound
}

func (r *TestComputerSystemRepository) SubmitKVMConsentCode(_ context.Context, systemID, _ string) error {
if _, exists := r.systems[systemID]; exists {
return nil
}

return usecase.ErrSystemNotFound
}

func (r *TestComputerSystemRepository) CancelKVMConsent(_ context.Context, systemID string) error {
if _, exists := r.systems[systemID]; exists {
return nil
}

return usecase.ErrSystemNotFound
}

// createTestSystemData creates a test system for the repository
func createTestSystemData(systemID, name, manufacturer, model, serialNumber string) *redfishv1.ComputerSystem {
return &redfishv1.ComputerSystem{
Expand Down
152 changes: 146 additions & 6 deletions redfish/internal/controller/http/v1/handler/systems_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ package v1
import (
"errors"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"time"

"github.com/gin-gonic/gin"
Expand All @@ -23,6 +26,11 @@ const (
nameKey = "Name"
)

var (
sixDigitConsentCodeRe = regexp.MustCompile(`^\d{6}$`)
amtBadRequestRe = regexp.MustCompile(`(?i)\b400\s+bad\s+request\b`)
)

// PostRedfishV1SystemsComputerSystemIdActionsComputerSystemReset handles reset action for a computer system.
// Validates system ID and reset type before executing power state change.
//
Expand Down Expand Up @@ -104,7 +112,6 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsComputerSyste
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemCancelKVMConsent handles canceling KVM consent for a computer system.
// This is a stub implementation.
//
//nolint:revive // Method name is generated from OpenAPI spec and cannot be changed
func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemCancelKVMConsent(c *gin.Context, computerSystemID string) {
Expand All @@ -114,7 +121,32 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu
return
}

MethodNotAllowedError(c)
var req generated.PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemCancelKVMConsentJSONRequestBody

if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) {
MalformedJSONError(c)

return
}

if err := s.ComputerSystemUC.CancelKVMConsent(c.Request.Context(), computerSystemID); err != nil {
var consentErr *usecase.ConsentFailedError

switch {
case errors.Is(err, usecase.ErrSystemNotFound):
NotFoundError(c, "System", computerSystemID)
case errors.As(err, &consentErr):
BadRequestError(c, consentErr.Error())
case isAMTBadRequestError(err):
BadRequestError(c, err.Error())
default:
InternalServerError(c, err)
}

return
}

sendActionSuccessResponse(c)
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemCancelSolConsent handles canceling SOL consent for a computer system.
Expand Down Expand Up @@ -166,7 +198,6 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemRequestKVMConsent handles requesting KVM consent for a computer system.
// This is a stub implementation.
//
//nolint:revive // Method name is generated from OpenAPI spec and cannot be changed
func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemRequestKVMConsent(c *gin.Context, computerSystemID string) {
Expand All @@ -176,7 +207,32 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu
return
}

MethodNotAllowedError(c)
var req generated.PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemRequestKVMConsentJSONRequestBody

if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) {
MalformedJSONError(c)

return
}

if err := s.ComputerSystemUC.RequestKVMConsent(c.Request.Context(), computerSystemID); err != nil {
var consentErr *usecase.ConsentFailedError

switch {
case errors.Is(err, usecase.ErrSystemNotFound):
NotFoundError(c, "System", computerSystemID)
case errors.As(err, &consentErr):
BadRequestError(c, consentErr.Error())
case isAMTBadRequestError(err):
BadRequestError(c, err.Error())
default:
InternalServerError(c, err)
}

return
}

sendActionSuccessResponse(c)
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemRequestSolConsent handles requesting SOL consent for a computer system.
Expand All @@ -194,7 +250,6 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemSubmitKVMConsentCode handles submitting a KVM consent code for a computer system.
// This is a stub implementation.
//
//nolint:revive // Method name is generated from OpenAPI spec and cannot be changed
func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemSubmitKVMConsentCode(c *gin.Context, computerSystemID string) {
Expand All @@ -204,7 +259,45 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu
return
}

MethodNotAllowedError(c)
var req generated.PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemSubmitKVMConsentCodeJSONRequestBody

if err := c.ShouldBindJSON(&req); err != nil {
MalformedJSONError(c)

return
}

consentCode := strings.TrimSpace(req.ConsentCode)
if consentCode == "" {
PropertyMissingError(c, "ConsentCode")

return
}

if !sixDigitConsentCodeRe.MatchString(consentCode) {
BadRequestError(c, "Invalid ConsentCode: must be a six-digit numeric value")

return
}

if err := s.ComputerSystemUC.SubmitKVMConsentCode(c.Request.Context(), computerSystemID, consentCode); err != nil {
var consentErr *usecase.ConsentFailedError

switch {
case errors.Is(err, usecase.ErrSystemNotFound):
NotFoundError(c, "System", computerSystemID)
case errors.As(err, &consentErr):
BadRequestError(c, consentErr.Error())
case isAMTBadRequestError(err):
BadRequestError(c, err.Error())
default:
InternalServerError(c, err)
}

return
}

sendActionSuccessResponse(c)
}

// PostRedfishV1SystemsComputerSystemIdActionsOemIntelComputerSystemSubmitSolConsentCode handles submitting a SOL consent code for a computer system.
Expand All @@ -220,3 +313,50 @@ func (s *RedfishServer) PostRedfishV1SystemsComputerSystemIdActionsOemIntelCompu

MethodNotAllowedError(c)
}

func sendActionSuccessResponse(c *gin.Context) {
sendActionSuccessResponseWithLookup(c, registryMgr.LookupMessage)
}

func sendActionSuccessResponseWithLookup(c *gin.Context, lookupFn func(string, string) (*RegistryMessage, error)) {
SetRedfishHeaders(c)

successMsg, err := lookupFn("Base", "Success")
if err != nil {
InternalServerError(c, err)

return
}

messageID := successMsg.MessageID
message := successMsg.Message
severity := mapSeverityToResourceHealth(successMsg.Severity)
resolution := successMsg.Resolution

c.JSON(http.StatusOK, generated.RedfishError{
Error: struct {
MessageExtendedInfo *[]generated.MessageMessage `json:"@Message.ExtendedInfo,omitempty"`
Code *string `json:"code,omitempty"`
Message *string `json:"message,omitempty"`
}{
Code: &messageID,
Message: &message,
MessageExtendedInfo: &[]generated.MessageMessage{
{
MessageId: &messageID,
Message: &message,
Severity: &severity,
Resolution: &resolution,
},
},
},
})
}

func isAMTBadRequestError(err error) bool {
if err == nil {
return false
}

return amtBadRequestRe.MatchString(err.Error())
}
Loading
Loading