Skip to content
This repository was archived by the owner on Jun 2, 2026. It is now read-only.
Merged
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
4 changes: 4 additions & 0 deletions api/pkg/api/handler/expectedmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ func (cemh CreateExpectedMachineHandler) Handle(c echo.Context) error {
ExpectedMachineID: uuid.New(),
SiteID: site.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
ChassisSerialNumber: apiRequest.ChassisSerialNumber,
SkuID: apiRequest.SkuID,
FallbackDpuSerialNumbers: apiRequest.FallbackDPUSerialNumbers,
Expand Down Expand Up @@ -681,6 +682,7 @@ func (uemh UpdateExpectedMachineHandler) Handle(c echo.Context) error {
cdbm.ExpectedMachineUpdateInput{
ExpectedMachineID: expectedMachine.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
ChassisSerialNumber: apiRequest.ChassisSerialNumber,
SkuID: apiRequest.SkuID,
FallbackDpuSerialNumbers: apiRequest.FallbackDPUSerialNumbers,
Expand Down Expand Up @@ -1099,6 +1101,7 @@ func (cemh CreateExpectedMachinesHandler) Handle(c echo.Context) error {
ExpectedMachineID: id,
SiteID: site.ID,
BmcMacAddress: machineReq.BmcMacAddress,
BmcIpAddress: machineReq.BmcIpAddress,
ChassisSerialNumber: machineReq.ChassisSerialNumber,
SkuID: machineReq.SkuID,
FallbackDpuSerialNumbers: machineReq.FallbackDPUSerialNumbers,
Expand Down Expand Up @@ -1539,6 +1542,7 @@ func (uemh UpdateExpectedMachinesHandler) Handle(c echo.Context) error {
updateInputs = append(updateInputs, cdbm.ExpectedMachineUpdateInput{
ExpectedMachineID: emID,
BmcMacAddress: machineReq.BmcMacAddress,
BmcIpAddress: machineReq.BmcIpAddress,
ChassisSerialNumber: machineReq.ChassisSerialNumber,
SkuID: machineReq.SkuID,
FallbackDpuSerialNumbers: machineReq.FallbackDPUSerialNumbers,
Expand Down
6 changes: 6 additions & 0 deletions api/pkg/api/handler/expectedmachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ func TestCreateExpectedMachineHandler_Handle(t *testing.T) {
DefaultBmcPassword: cdb.GetStrPtr("password"),
ChassisSerialNumber: "CHASSIS-RACK-001",
RackID: cdb.GetStrPtr("test-rack-001"),
BmcIpAddress: cdb.GetStrPtr("192.168.1.10"),
Labels: map[string]string{"env": "rack-test"},
},
setupContext: func(c echo.Context) {
Expand Down Expand Up @@ -406,6 +407,11 @@ func TestCreateExpectedMachineHandler_Handle(t *testing.T) {
assert.Equal(t, *tt.requestBody.RackID, *response.RackID, "RackID in response should match request")
}
}
if tt.requestBody.BmcIpAddress != nil {
if assert.NotNil(t, response.BmcIpAddress, "BmcIpAddress should not be nil in response") {
assert.Equal(t, *tt.requestBody.BmcIpAddress, *response.BmcIpAddress, "BmcIpAddress in response should match request")
}
}
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions api/pkg/api/handler/expectedpowershelf.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (cepsh CreateExpectedPowerShelfHandler) Handle(c echo.Context) error {
SiteID: site.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
ShelfSerialNumber: apiRequest.ShelfSerialNumber,
IpAddress: apiRequest.IpAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
RackID: apiRequest.RackID,
Name: apiRequest.Name,
Manufacturer: apiRequest.Manufacturer,
Expand Down Expand Up @@ -603,7 +603,7 @@ func (uepsh UpdateExpectedPowerShelfHandler) Handle(c echo.Context) error {
ExpectedPowerShelfID: expectedPowerShelf.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
ShelfSerialNumber: apiRequest.ShelfSerialNumber,
IpAddress: apiRequest.IpAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
RackID: apiRequest.RackID,
Name: apiRequest.Name,
Manufacturer: apiRequest.Manufacturer,
Expand Down
4 changes: 2 additions & 2 deletions api/pkg/api/handler/expectedpowershelf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func TestCreateExpectedPowerShelfHandler_Handle(t *testing.T) {
}
}

validIpAddress := "192.168.1.100"
validBmcIpAddress := "192.168.1.100"

tests := []struct {
name string
Expand All @@ -177,7 +177,7 @@ func TestCreateExpectedPowerShelfHandler_Handle(t *testing.T) {
DefaultBmcUsername: cdb.GetStrPtr("admin"),
DefaultBmcPassword: cdb.GetStrPtr("password"),
ShelfSerialNumber: "SHELF123",
IpAddress: &validIpAddress,
BmcIpAddress: &validBmcIpAddress,
Labels: map[string]string{"env": "test"},
},
setupContext: func(c echo.Context) {
Expand Down
2 changes: 2 additions & 0 deletions api/pkg/api/handler/expectedswitch.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func (cesh CreateExpectedSwitchHandler) Handle(c echo.Context) error {
ExpectedSwitchID: uuid.New(),
SiteID: site.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
SwitchSerialNumber: apiRequest.SwitchSerialNumber,
RackID: apiRequest.RackID,
Name: apiRequest.Name,
Expand Down Expand Up @@ -603,6 +604,7 @@ func (uesh UpdateExpectedSwitchHandler) Handle(c echo.Context) error {
cdbm.ExpectedSwitchUpdateInput{
ExpectedSwitchID: expectedSwitch.ID,
BmcMacAddress: apiRequest.BmcMacAddress,
BmcIpAddress: apiRequest.BmcIpAddress,
SwitchSerialNumber: apiRequest.SwitchSerialNumber,
RackID: apiRequest.RackID,
Name: apiRequest.Name,
Expand Down
37 changes: 34 additions & 3 deletions api/pkg/api/handler/expectedswitch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func TestCreateExpectedSwitchHandler_Handle(t *testing.T) {
SwitchSerialNumber: "SWITCH123",
NvOsUsername: cdb.GetStrPtr("nvos-admin"),
NvOsPassword: cdb.GetStrPtr("nvos-password"),
BmcIpAddress: cdb.GetStrPtr("192.168.1.10"),
Labels: map[string]string{"env": "test"},
},
setupContext: func(c echo.Context) {
Expand Down Expand Up @@ -290,12 +291,19 @@ func TestCreateExpectedSwitchHandler_Handle(t *testing.T) {
t.Errorf("Response: %v", rec.Body.String())
}

if tt.expectedStatus == http.StatusCreated && tt.requestBody.Labels != nil {
if tt.expectedStatus == http.StatusCreated {
var response model.APIExpectedSwitch
err := json.Unmarshal(rec.Body.Bytes(), &response)
assert.Nil(t, err)
assert.NotNil(t, response.Labels, "Labels should not be nil in response")
assert.Equal(t, tt.requestBody.Labels, response.Labels, "Labels in response should match request")
if tt.requestBody.Labels != nil {
assert.NotNil(t, response.Labels, "Labels should not be nil in response")
assert.Equal(t, tt.requestBody.Labels, response.Labels, "Labels in response should match request")
}
if tt.requestBody.BmcIpAddress != nil {
if assert.NotNil(t, response.BmcIpAddress, "BmcIpAddress should not be nil in response") {
assert.Equal(t, *tt.requestBody.BmcIpAddress, *response.BmcIpAddress, "BmcIpAddress in response should match request")
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
})
}
Expand Down Expand Up @@ -735,6 +743,19 @@ func TestUpdateExpectedSwitchHandler_Handle(t *testing.T) {
},
expectedStatus: http.StatusOK,
},
{
name: "successful update with BmcIpAddress",
id: testES.ID.String(),
requestBody: model.APIExpectedSwitchUpdateRequest{
BmcIpAddress: cdb.GetStrPtr("192.168.1.42"),
},
setupContext: func(c echo.Context) {
c.Set("user", createMockUser(org))
c.SetParamNames("orgName", "id")
c.SetParamValues(org, testES.ID.String())
},
expectedStatus: http.StatusOK,
},
{
name: "body ID mismatch with URL should return 400",
id: testES.ID.String(),
Expand Down Expand Up @@ -787,6 +808,16 @@ func TestUpdateExpectedSwitchHandler_Handle(t *testing.T) {
if tt.expectedStatus != rec.Code {
t.Errorf("Response: %v", rec.Body.String())
}

// Verify BmcIpAddress round-trips through the update response when set
if tt.expectedStatus == http.StatusOK && tt.requestBody.BmcIpAddress != nil {
var response model.APIExpectedSwitch
err := json.Unmarshal(rec.Body.Bytes(), &response)
assert.Nil(t, err)
if assert.NotNil(t, response.BmcIpAddress, "BmcIpAddress should not be nil in response") {
assert.Equal(t, *tt.requestBody.BmcIpAddress, *response.BmcIpAddress, "BmcIpAddress in response should match request")
}
}
})
}
}
Expand Down
15 changes: 15 additions & 0 deletions api/pkg/api/model/expectedmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type APIExpectedMachineCreateRequest struct {
SkuID *string `json:"skuId"`
// RackID is the optional rack identifier
RackID *string `json:"rackId"`
// BmcIpAddress is the optional BMC IP address of the expected machine
BmcIpAddress *string `json:"bmcIpAddress"`
// Name is the optional name of the expected machine
Name *string `json:"name"`
// Manufacturer is the optional manufacturer of the expected machine
Expand Down Expand Up @@ -93,6 +95,10 @@ func (emcr *APIExpectedMachineCreateRequest) Validate() error {
validation.NilOrNotEmpty.Error("SkuID cannot be empty")),
validation.Field(&emcr.RackID,
validation.NilOrNotEmpty.Error("RackID cannot be empty")),
validation.Field(&emcr.BmcIpAddress,
validation.NilOrNotEmpty.Error("BmcIpAddress cannot be empty"),
validation.When(emcr.BmcIpAddress != nil && *emcr.BmcIpAddress != "",
validationis.IP.Error("BmcIpAddress must be a valid IPv4 or IPv6 address"))),
validation.Field(&emcr.Name,
validation.NilOrNotEmpty.Error("Name cannot be empty")),
validation.Field(&emcr.Manufacturer,
Expand Down Expand Up @@ -134,6 +140,8 @@ type APIExpectedMachineUpdateRequest struct {
SkuID *string `json:"skuId"`
// RackID is the optional rack identifier
RackID *string `json:"rackId"`
// BmcIpAddress is the optional BMC IP address of the expected machine
BmcIpAddress *string `json:"bmcIpAddress"`
// Name is the optional name of the expected machine
Name *string `json:"name"`
// Manufacturer is the optional manufacturer of the expected machine
Expand Down Expand Up @@ -189,6 +197,10 @@ func (emur *APIExpectedMachineUpdateRequest) Validate() error {
validation.NilOrNotEmpty.Error("SkuID cannot be empty")),
validation.Field(&emur.RackID,
validation.NilOrNotEmpty.Error("RackID cannot be empty")),
validation.Field(&emur.BmcIpAddress,
validation.NilOrNotEmpty.Error("BmcIpAddress cannot be empty"),
validation.When(emur.BmcIpAddress != nil && *emur.BmcIpAddress != "",
validationis.IP.Error("BmcIpAddress must be a valid IPv4 or IPv6 address"))),
validation.Field(&emur.Name,
validation.NilOrNotEmpty.Error("Name cannot be empty")),
validation.Field(&emur.Manufacturer,
Expand Down Expand Up @@ -236,6 +248,8 @@ type APIExpectedMachine struct {
Machine *APIMachineSummary `json:"machine,omitempty"`
// RackID is the optional rack identifier
RackID *string `json:"rackId"`
// BmcIpAddress is the optional BMC IP address of the expected machine
BmcIpAddress *string `json:"bmcIpAddress"`
// Name is the optional name of the expected machine
Name *string `json:"name"`
// Manufacturer is the optional manufacturer of the expected machine
Expand Down Expand Up @@ -271,6 +285,7 @@ func NewAPIExpectedMachine(dibp *cdbm.ExpectedMachine) *APIExpectedMachine {
SkuID: dibp.SkuID,
MachineID: dibp.MachineID,
RackID: dibp.RackID,
BmcIpAddress: dibp.BmcIpAddress,
Name: dibp.Name,
Manufacturer: dibp.Manufacturer,
Model: dibp.Model,
Expand Down
97 changes: 97 additions & 0 deletions api/pkg/api/model/expectedmachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,62 @@ func TestAPIExpectedMachineCreateRequest_Validate(t *testing.T) {
},
expectErr: true,
},
// BmcIpAddress validation tests
{
desc: "valid IPv4 BmcIpAddress",
obj: APIExpectedMachineCreateRequest{
BmcMacAddress: "00:11:22:33:44:55",
DefaultBmcUsername: &validUsername,
DefaultBmcPassword: &validPassword,
ChassisSerialNumber: validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("192.168.1.10"),
},
expectErr: false,
},
{
desc: "valid IPv6 BmcIpAddress",
obj: APIExpectedMachineCreateRequest{
BmcMacAddress: "00:11:22:33:44:55",
DefaultBmcUsername: &validUsername,
DefaultBmcPassword: &validPassword,
ChassisSerialNumber: validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("2001:db8::1"),
},
expectErr: false,
},
{
desc: "invalid BmcIpAddress",
obj: APIExpectedMachineCreateRequest{
BmcMacAddress: "00:11:22:33:44:55",
DefaultBmcUsername: &validUsername,
DefaultBmcPassword: &validPassword,
ChassisSerialNumber: validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("not-an-ip"),
},
expectErr: true,
},
{
desc: "empty BmcIpAddress (pointer set, value empty)",
obj: APIExpectedMachineCreateRequest{
BmcMacAddress: "00:11:22:33:44:55",
DefaultBmcUsername: &validUsername,
DefaultBmcPassword: &validPassword,
ChassisSerialNumber: validChassisSerial,
BmcIpAddress: &emptyString,
},
expectErr: true,
},
{
desc: "nil BmcIpAddress (default)",
obj: APIExpectedMachineCreateRequest{
BmcMacAddress: "00:11:22:33:44:55",
DefaultBmcUsername: &validUsername,
DefaultBmcPassword: &validPassword,
ChassisSerialNumber: validChassisSerial,
BmcIpAddress: nil,
},
expectErr: false,
},
}
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
Expand Down Expand Up @@ -508,6 +564,47 @@ func TestAPIExpectedMachineUpdateRequest_Validate(t *testing.T) {
},
expectErr: true,
},
// BmcIpAddress validation tests
{
desc: "valid IPv4 BmcIpAddress",
obj: APIExpectedMachineUpdateRequest{
ChassisSerialNumber: &validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("192.168.1.10"),
},
expectErr: false,
},
{
desc: "valid IPv6 BmcIpAddress",
obj: APIExpectedMachineUpdateRequest{
ChassisSerialNumber: &validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("2001:db8::1"),
},
expectErr: false,
},
{
desc: "invalid BmcIpAddress",
obj: APIExpectedMachineUpdateRequest{
ChassisSerialNumber: &validChassisSerial,
BmcIpAddress: cdb.GetStrPtr("not-an-ip"),
},
expectErr: true,
},
{
desc: "empty BmcIpAddress (pointer set, value empty)",
obj: APIExpectedMachineUpdateRequest{
ChassisSerialNumber: &validChassisSerial,
BmcIpAddress: &emptyString,
},
expectErr: true,
},
{
desc: "nil BmcIpAddress (default)",
obj: APIExpectedMachineUpdateRequest{
ChassisSerialNumber: &validChassisSerial,
BmcIpAddress: nil,
},
expectErr: false,
},
}

for _, tc := range tests {
Expand Down
Loading
Loading