From 87e677edcf1578eabbf821b08d49eb074a55a0cb Mon Sep 17 00:00:00 2001 From: Hitesh Wadekar Date: Sun, 28 Jun 2026 13:34:09 -0700 Subject: [PATCH 1/8] feat(rest-api): expose dpfEnabled on expected-machine endpoints Allow operators to read and set per-host DPF eligibility via the REST API, persisting the flag in the cloud DB and forwarding it to Core through the existing expected-machine workflows and inventory sync. Signed-off-by: Hitesh Wadekar --- .../api/pkg/api/handler/expectedmachine.go | 4 + .../pkg/api/handler/expectedmachine_test.go | 75 +++++++++++++++++++ rest-api/api/pkg/api/model/expectedmachine.go | 7 ++ .../api/pkg/api/model/expectedmachine_test.go | 21 ++++++ rest-api/db/pkg/db/model/expectedmachine.go | 22 ++++++ .../db/pkg/db/model/expectedmachine_test.go | 65 ++++++++++++++++ ...0628120000_expected_machine_dpf_enabled.go | 35 +++++++++ rest-api/docs/index.html | 34 +++++++-- rest-api/flow/internal/nicoapi/gen/fmds.pb.go | 13 ---- .../flow/internal/nicoapi/gen/fmds_grpc.pb.go | 13 ---- .../internal/nicoapi/nicoproto/fmds.proto | 18 +---- rest-api/openapi/spec.yaml | 22 ++++++ rest-api/sdk/standard/client.go | 5 +- .../model_batch_instance_create_request.go | 5 +- .../sdk/standard/model_expected_machine.go | 40 +++++++++- .../model_expected_machine_create_request.go | 51 ++++++++++++- .../model_expected_machine_update_request.go | 51 ++++++++++++- .../standard/model_expected_power_shelf.go | 3 +- ...del_expected_power_shelf_create_request.go | 3 +- ...del_expected_power_shelf_update_request.go | 3 +- rest-api/sdk/standard/model_expected_rack.go | 5 +- .../model_expected_rack_create_request.go | 5 +- .../model_expected_rack_update_request.go | 5 +- .../sdk/standard/model_expected_switch.go | 3 +- .../model_expected_switch_create_request.go | 3 +- .../model_expected_switch_update_request.go | 3 +- .../standard/model_infini_band_partition.go | 5 +- ...el_infini_band_partition_create_request.go | 3 +- ...el_infini_band_partition_update_request.go | 5 +- rest-api/sdk/standard/model_instance.go | 5 +- .../standard/model_instance_create_request.go | 5 +- rest-api/sdk/standard/model_instance_type.go | 3 +- .../model_instance_type_create_request.go | 3 +- .../model_instance_type_update_request.go | 5 +- .../standard/model_instance_update_request.go | 5 +- rest-api/sdk/standard/model_interface.go | 3 +- .../model_interface_create_request.go | 3 +- rest-api/sdk/standard/model_machine.go | 5 +- .../standard/model_machine_update_request.go | 5 +- .../standard/model_network_security_group.go | 3 +- ...l_network_security_group_create_request.go | 5 +- ...l_network_security_group_update_request.go | 5 +- rest-api/sdk/standard/model_vpc.go | 5 +- .../sdk/standard/model_vpc_create_request.go | 5 +- .../sdk/standard/model_vpc_update_request.go | 5 +- .../expectedmachine/expectedmachine.go | 5 +- 46 files changed, 470 insertions(+), 132 deletions(-) create mode 100644 rest-api/db/pkg/migrations/20260628120000_expected_machine_dpf_enabled.go diff --git a/rest-api/api/pkg/api/handler/expectedmachine.go b/rest-api/api/pkg/api/handler/expectedmachine.go index c8725cf0a6..9182d2b107 100644 --- a/rest-api/api/pkg/api/handler/expectedmachine.go +++ b/rest-api/api/pkg/api/handler/expectedmachine.go @@ -226,6 +226,7 @@ func (cemh CreateExpectedMachineHandler) Handle(c echo.Context) error { TrayIdx: apiRequest.TrayIdx, HostID: apiRequest.HostID, Labels: apiRequest.Labels, + DpfEnabled: apiRequest.DpfEnabled, CreatedBy: dbUser.ID, }, ) @@ -703,6 +704,7 @@ func (uemh UpdateExpectedMachineHandler) Handle(c echo.Context) error { TrayIdx: apiRequest.TrayIdx, HostID: apiRequest.HostID, Labels: apiRequest.Labels, + DpfEnabled: apiRequest.DpfEnabled, }, ) if err != nil { @@ -1113,6 +1115,7 @@ func (cemh CreateExpectedMachinesHandler) Handle(c echo.Context) error { TrayIdx: machineReq.TrayIdx, HostID: machineReq.HostID, Labels: machineReq.Labels, + DpfEnabled: machineReq.DpfEnabled, CreatedBy: dbUser.ID, }) } @@ -1548,6 +1551,7 @@ func (uemh UpdateExpectedMachinesHandler) Handle(c echo.Context) error { TrayIdx: machineReq.TrayIdx, HostID: machineReq.HostID, Labels: machineReq.Labels, + DpfEnabled: machineReq.DpfEnabled, }) } diff --git a/rest-api/api/pkg/api/handler/expectedmachine_test.go b/rest-api/api/pkg/api/handler/expectedmachine_test.go index a0056984b4..e8b9130bf5 100644 --- a/rest-api/api/pkg/api/handler/expectedmachine_test.go +++ b/rest-api/api/pkg/api/handler/expectedmachine_test.go @@ -2172,6 +2172,81 @@ func TestCreateExpectedMachineHandler_BmcCredentialsForwardedToWorkflow(t *testi } } +func TestCreateExpectedMachineHandler_DpfEnabledForwardedToWorkflow(t *testing.T) { + e := echo.New() + dbSession := testExpectedMachineInitDB(t) + defer dbSession.Close() + + cfg := common.GetTestConfig() + tcfg, _ := cfg.GetTemporalConfig() + scp := sc.NewClientPool(tcfg) + + org := "test-org" + _, site := testExpectedMachineSetupTestData(t, dbSession, org) + + var capturedRequest *cwssaws.ExpectedMachine + mockTemporalClient := &tmocks.Client{} + mockWorkflowRun := &tmocks.WorkflowRun{} + mockWorkflowRun.On("GetID").Return("test-workflow-id") + mockWorkflowRun.Mock.On("Get", mock.Anything, mock.Anything).Return(nil) + mockTemporalClient.Mock.On("ExecuteWorkflow", mock.Anything, mock.Anything, "CreateExpectedMachine", mock.Anything). + Run(func(args mock.Arguments) { + if req, ok := args.Get(3).(*cwssaws.ExpectedMachine); ok { + capturedRequest = req + } + }). + Return(mockWorkflowRun, nil) + scp.IDClientMap[site.ID.String()] = mockTemporalClient + + handler := NewCreateExpectedMachineHandler(dbSession, scp, cfg) + + rawBody := map[string]interface{}{ + "siteId": site.ID.String(), + "bmcMacAddress": "00:AA:BB:CC:DD:EF", + "chassisSerialNumber": "DPF-TEST-CHASSIS-001", + "dpfEnabled": false, + } + reqBody, err := json.Marshal(rawBody) + assert.Nil(t, err) + + req := httptest.NewRequest(http.MethodPost, "/v2/org/"+org+"/nico/expected-machine", bytes.NewReader(reqBody)) + req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) + req = req.WithContext(context.Background()) + + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + c.Set("user", &cdbm.User{ + StarfleetID: cutil.GetPtr("test-user"), + OrgData: cdbm.OrgData{ + org: cdbm.Org{ + ID: 123, + Name: org, + DisplayName: org, + OrgType: "ENTERPRISE", + Roles: []string{"FORGE_PROVIDER_ADMIN"}, + }, + }, + }) + c.SetParamNames("orgName") + c.SetParamValues(org) + + err = handler.Handle(c) + assert.Nil(t, err) + assert.Equal(t, http.StatusCreated, rec.Code, "Response: %s", rec.Body.String()) + + if assert.NotNil(t, capturedRequest, "workflow should have received a request") { + if assert.NotNil(t, capturedRequest.IsDpfEnabled) { + assert.False(t, *capturedRequest.IsDpfEnabled) + } + assert.False(t, capturedRequest.DpfEnabled) + } + + var apiResponse model.APIExpectedMachine + err = json.Unmarshal(rec.Body.Bytes(), &apiResponse) + assert.Nil(t, err) + assert.False(t, apiResponse.DpfEnabled) +} + // TestUpdateExpectedMachineHandler_BmcCredentialsForwardedToWorkflow is a regression test for the // same spec / JSON struct tag mismatch bug described in // TestCreateExpectedMachineHandler_BmcCredentialsForwardedToWorkflow, but for the PATCH diff --git a/rest-api/api/pkg/api/model/expectedmachine.go b/rest-api/api/pkg/api/model/expectedmachine.go index 6cf50e6941..13dc5f9858 100644 --- a/rest-api/api/pkg/api/model/expectedmachine.go +++ b/rest-api/api/pkg/api/model/expectedmachine.go @@ -57,6 +57,8 @@ type APIExpectedMachineCreateRequest struct { HostID *int32 `json:"hostId"` // Labels is the labels of the expected machine Labels map[string]string `json:"labels"` + // DpfEnabled marks whether this host is eligible for DPF-based provisioning + DpfEnabled *bool `json:"dpfEnabled"` } // Validate ensure the values passed in request are acceptable @@ -140,6 +142,8 @@ type APIExpectedMachineUpdateRequest struct { HostID *int32 `json:"hostId"` // Labels is the labels of the expected machine Labels map[string]string `json:"labels"` + // DpfEnabled marks whether this host is eligible for DPF-based provisioning + DpfEnabled *bool `json:"dpfEnabled"` } // Validate ensure the values passed in request are acceptable @@ -248,6 +252,8 @@ type APIExpectedMachine struct { HostID *int32 `json:"hostId"` // Labels is the labels of the expected machine Labels map[string]string `json:"labels"` + // DpfEnabled indicates whether this host is eligible for DPF-based provisioning + DpfEnabled bool `json:"dpfEnabled"` // Created indicates the ISO datetime string for when the ExpectedMachine was created Created time.Time `json:"created"` // Updated indicates the ISO datetime string for when the ExpectedMachine was last updated @@ -274,6 +280,7 @@ func NewAPIExpectedMachine(dibp *cdbm.ExpectedMachine) *APIExpectedMachine { TrayIdx: dibp.TrayIdx, HostID: dibp.HostID, Labels: dibp.Labels, + DpfEnabled: cdbm.EffectiveDpfEnabled(dibp.DpfEnabled), Created: dibp.Created, Updated: dibp.Updated, } diff --git a/rest-api/api/pkg/api/model/expectedmachine_test.go b/rest-api/api/pkg/api/model/expectedmachine_test.go index e75cc87d3c..b772f377d1 100644 --- a/rest-api/api/pkg/api/model/expectedmachine_test.go +++ b/rest-api/api/pkg/api/model/expectedmachine_test.go @@ -312,6 +312,27 @@ func TestNewAPIExpectedMachine(t *testing.T) { } } +func TestNewAPIExpectedMachine_DpfEnabled(t *testing.T) { + t.Run("nil stored value defaults to true", func(t *testing.T) { + got := NewAPIExpectedMachine(&cdbm.ExpectedMachine{}) + assert.True(t, got.DpfEnabled) + }) + + t.Run("stored false is returned", func(t *testing.T) { + got := NewAPIExpectedMachine(&cdbm.ExpectedMachine{ + DpfEnabled: cutil.GetPtr(false), + }) + assert.False(t, got.DpfEnabled) + }) + + t.Run("stored true is returned", func(t *testing.T) { + got := NewAPIExpectedMachine(&cdbm.ExpectedMachine{ + DpfEnabled: cutil.GetPtr(true), + }) + assert.True(t, got.DpfEnabled) + }) +} + func TestNewAPIExpectedMachineWithNilFields(t *testing.T) { dbEM := &cdbm.ExpectedMachine{ BmcMacAddress: "00:11:22:33:44:55", diff --git a/rest-api/db/pkg/db/model/expectedmachine.go b/rest-api/db/pkg/db/model/expectedmachine.go index ac65973c5b..8c3735a6af 100644 --- a/rest-api/db/pkg/db/model/expectedmachine.go +++ b/rest-api/db/pkg/db/model/expectedmachine.go @@ -67,6 +67,7 @@ type ExpectedMachine struct { TrayIdx *int32 `bun:"tray_idx"` HostID *int32 `bun:"host_id"` Labels Labels `bun:"labels,type:jsonb"` + DpfEnabled *bool `bun:"dpf_enabled"` Created time.Time `bun:"created,nullzero,notnull,default:current_timestamp"` Updated time.Time `bun:"updated,nullzero,notnull,default:current_timestamp"` CreatedBy uuid.UUID `bun:"type:uuid,notnull"` @@ -80,6 +81,15 @@ type ExpectedMachineCredentials struct { Password *string } +// EffectiveDpfEnabled returns the DPF-enabled flag for API display. A nil +// stored value means unset, which Core treats as true on create and read. +func EffectiveDpfEnabled(v *bool) bool { + if v == nil { + return true + } + return *v +} + // ToProto builds the workflow proto for this ExpectedMachine. BMC // credentials are passed in because they aren't persisted on the record; // labels are read from em.Labels. @@ -119,6 +129,10 @@ func (em *ExpectedMachine) ToProto(creds ExpectedMachineCredentials) *cwssaws.Ex if em.HostID != nil { proto.HostId = em.HostID } + if em.DpfEnabled != nil { + proto.IsDpfEnabled = em.DpfEnabled + proto.DpfEnabled = *em.DpfEnabled + } if creds.Username != nil { proto.BmcUsername = *creds.Username @@ -183,6 +197,7 @@ func (em *ExpectedMachine) FromProto(proto *cwssaws.ExpectedMachine, linkedMachi em.TrayIdx = proto.TrayIdx em.HostID = proto.HostId em.Labels.FromProto(proto.Metadata.GetLabels()) + em.DpfEnabled = proto.IsDpfEnabled } // ExpectedMachineCreateInput input parameters for Create method @@ -204,6 +219,7 @@ type ExpectedMachineCreateInput struct { TrayIdx *int32 HostID *int32 Labels map[string]string + DpfEnabled *bool CreatedBy uuid.UUID } @@ -225,6 +241,7 @@ type ExpectedMachineUpdateInput struct { TrayIdx *int32 HostID *int32 Labels map[string]string + DpfEnabled *bool } // ExpectedMachineClearInput input parameters for Clear method @@ -366,6 +383,7 @@ func (emsd ExpectedMachineSQLDAO) CreateMultiple(ctx context.Context, tx *db.Tx, TrayIdx: input.TrayIdx, HostID: input.HostID, Labels: input.Labels, + DpfEnabled: input.DpfEnabled, CreatedBy: input.CreatedBy, } expectedMachines = append(expectedMachines, em) @@ -663,6 +681,10 @@ func (emsd ExpectedMachineSQLDAO) UpdateMultiple(ctx context.Context, tx *db.Tx, em.HostID = input.HostID columnsSet["host_id"] = true } + if input.DpfEnabled != nil { + em.DpfEnabled = input.DpfEnabled + columnsSet["dpf_enabled"] = true + } expectedMachines = append(expectedMachines, em) ids = append(ids, input.ExpectedMachineID) diff --git a/rest-api/db/pkg/db/model/expectedmachine_test.go b/rest-api/db/pkg/db/model/expectedmachine_test.go index 04ff4ee1df..74205b749f 100644 --- a/rest-api/db/pkg/db/model/expectedmachine_test.go +++ b/rest-api/db/pkg/db/model/expectedmachine_test.go @@ -96,6 +96,20 @@ func TestExpectedMachine_FromProto(t *testing.T) { assert.Equal(t, Labels{"env": "prod"}, em.Labels) }) + t.Run("populates dpfEnabled from is_dpf_enabled", func(t *testing.T) { + em := &ExpectedMachine{} + enabled := false + em.FromProto(&cwssaws.ExpectedMachine{ + Id: &cwssaws.UUID{Value: id.String()}, + BmcMacAddress: "aa:bb", + IsDpfEnabled: &enabled, + }, nil) + + if assert.NotNil(t, em.DpfEnabled) { + assert.False(t, *em.DpfEnabled) + } + }) + t.Run("nil linkedMachineID leaves MachineID nil", func(t *testing.T) { em := &ExpectedMachine{} em.FromProto(&cwssaws.ExpectedMachine{ @@ -118,6 +132,57 @@ func TestExpectedMachine_FromProto(t *testing.T) { }) } +func TestExpectedMachine_ToProto(t *testing.T) { + id := uuid.New() + enabled := true + disabled := false + + t.Run("sets is_dpf_enabled when stored", func(t *testing.T) { + em := &ExpectedMachine{ + ID: id, + BmcMacAddress: "aa:bb:cc:dd:ee:ff", + ChassisSerialNumber: "CSN-1", + DpfEnabled: &enabled, + } + proto := em.ToProto(ExpectedMachineCredentials{}) + if assert.NotNil(t, proto.IsDpfEnabled) { + assert.True(t, *proto.IsDpfEnabled) + } + assert.True(t, proto.DpfEnabled) + }) + + t.Run("omits is_dpf_enabled when unset", func(t *testing.T) { + em := &ExpectedMachine{ + ID: id, + BmcMacAddress: "aa:bb:cc:dd:ee:ff", + ChassisSerialNumber: "CSN-1", + } + proto := em.ToProto(ExpectedMachineCredentials{}) + assert.Nil(t, proto.IsDpfEnabled) + assert.False(t, proto.DpfEnabled) + }) + + t.Run("forwards false value", func(t *testing.T) { + em := &ExpectedMachine{ + ID: id, + BmcMacAddress: "aa:bb:cc:dd:ee:ff", + ChassisSerialNumber: "CSN-1", + DpfEnabled: &disabled, + } + proto := em.ToProto(ExpectedMachineCredentials{}) + if assert.NotNil(t, proto.IsDpfEnabled) { + assert.False(t, *proto.IsDpfEnabled) + } + assert.False(t, proto.DpfEnabled) + }) +} + +func TestEffectiveDpfEnabled(t *testing.T) { + assert.True(t, EffectiveDpfEnabled(nil)) + assert.True(t, EffectiveDpfEnabled(cutil.GetPtr(true))) + assert.False(t, EffectiveDpfEnabled(cutil.GetPtr(false))) +} + // reset the tables needed for ExpectedMachine tests func testExpectedMachineSetupSchema(t *testing.T, dbSession *db.Session) { ctx := context.Background() diff --git a/rest-api/db/pkg/migrations/20260628120000_expected_machine_dpf_enabled.go b/rest-api/db/pkg/migrations/20260628120000_expected_machine_dpf_enabled.go new file mode 100644 index 0000000000..0521a671dd --- /dev/null +++ b/rest-api/db/pkg/migrations/20260628120000_expected_machine_dpf_enabled.go @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package migrations + +import ( + "context" + "database/sql" + "fmt" + + "github.com/uptrace/bun" +) + +func init() { + Migrations.MustRegister(func(ctx context.Context, db *bun.DB) error { + tx, terr := db.BeginTx(ctx, &sql.TxOptions{}) + if terr != nil { + handlePanic(terr, "failed to begin transaction") + } + + _, err := tx.Exec("ALTER TABLE expected_machine ADD COLUMN IF NOT EXISTS dpf_enabled BOOLEAN") + handleError(tx, err) + + terr = tx.Commit() + if terr != nil { + handlePanic(terr, "failed to commit transaction") + } + + fmt.Print(" [up migration] Added dpf_enabled column to 'expected_machine'. ") + return nil + }, func(ctx context.Context, db *bun.DB) error { + fmt.Print(" [down migration] No action taken") + return nil + }) +} diff --git a/rest-api/docs/index.html b/rest-api/docs/index.html index 34885e4e18..e207b4bbe3 100644 --- a/rest-api/docs/index.html +++ b/rest-api/docs/index.html @@ -3930,6 +3930,8 @@

Typical API Call Flow for Tenant

" class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean or null

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Omit on create to use the default (true).

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string

Responses

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

Error response when user is not authorized to call an endpoint or retrieve/modify objects

Request samples

Content type
application/json
{
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "defaultBmcUsername": "admin",
  • "defaultBmcPassword": "password123",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "labels": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Retrieve all Expected Machines

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine

Request samples

Content type
application/json
{
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "defaultBmcUsername": "admin",
  • "defaultBmcPassword": "password123",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "labels": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "dpfEnabled": true,
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Retrieve all Expected Machines

Retrieve all Expected Machines.

@@ -4116,6 +4120,8 @@

Typical API Call Flow for Tenant

" class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

Error response when user is not authorized to call an endpoint or retrieve/modify objects

Response samples

Content type
application/json
[
  • {
    }
]

Retrieve Expected Machine

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine

Response samples

Content type
application/json
[
  • {
    }
]

Retrieve Expected Machine

Retrieve a specific Expected Machine by ID.

@@ -4224,6 +4230,8 @@

Typical API Call Flow for Tenant

" class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

Error response when requested object is not found

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Update Expected Machine

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine/{expectedMachineId}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "dpfEnabled": true,
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Update Expected Machine

Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean or null

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Omit on update to preserve the existing value.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string

Responses

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

Error response when requested object is not found

Request samples

Content type
application/json
{
  • "defaultBmcUsername": "newadmin",
  • "defaultBmcPassword": "newpassword123",
  • "chassisSerialNumber": "CHASSIS-54321",
  • "labels": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Delete Expected Machine

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine/{expectedMachineId}

Request samples

Content type
application/json
{
  • "defaultBmcUsername": "newadmin",
  • "defaultBmcPassword": "newpassword123",
  • "chassisSerialNumber": "CHASSIS-54321",
  • "labels": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "siteId": "f97df110-f4de-492e-8849-4a6af68026b0",
  • "bmcMacAddress": "00:1A:2B:3C:4D:5E",
  • "bmcIpAddress": "192.168.1.100",
  • "chassisSerialNumber": "CHASSIS-12345",
  • "fallbackDPUSerialNumbers": [
    ],
  • "skuId": "lenovo.sr650v2.cpu.1",
  • "machineId": "fm100ht4v4mce2qstjnl8970nnj3ie6ecek4mtjn27pea4kre5gsa49jg0g",
  • "rackId": "rack-01",
  • "dpfEnabled": true,
  • "manufacturer": "Lenovo",
  • "labels": {
    },
  • "created": "2019-08-24T14:15:22Z",
  • "updated": "2019-08-24T14:15:22Z"
}

Delete Expected Machine

Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean or null

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Omit on create to use the default (true).

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string

Responses

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

Error response when user is not authorized to call an endpoint or retrieve/modify objects

Request samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Response samples

Content type
application/json
[
  • {
    }
]

Batch Update Expected Machines

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine/batch

Request samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Response samples

Content type
application/json
[
  • {
    }
]

Batch Update Expected Machines

Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Tray index within the rack

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean or null

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Omit on update to preserve the existing value.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string

Responses

hostId
integer or null <int32>

Host ID within the tray

+
dpfEnabled
boolean

When true, this host is eligible for DPF-based provisioning (requires site-level DPF to be enabled). Unset stored values are treated as true.

object (Labels) <= 10 properties

User-defined key-value pairs for organizing and categorizing Expected Machines

property name*
additional property
string
created
string <date-time>
Typical API Call Flow for Tenant " class="sc-iJSMbW sc-cBEgGa sc-ciCrSJ fiNpIH dNfUH dDDioG">

One or more Expected Machines not found

Request samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Response samples

Content type
application/json
[
  • {
    }
]

Expected Power Shelf

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/expected-machine/batch

Request samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Response samples

Content type
application/json
[
  • {
    }
]

Expected Power Shelf

Expected Power Shelf identifies a Power Shelf that is expected to be discovered at a Site. Infrastructure Providers can pre-register Expected Power Shelves using BMC credentials and serial numbers to help with Power Shelf discovery and ingestion.

@@ -14678,7 +14698,7 @@

Typical API Call Flow for Tenant

" class="sc-iJSMbW sc-cBEgGa fiNpIH bAoMjv">

Kubernetes Cluster

https://nico-rest-api.nico.svc.cluster.local/v2/org/{org}/nico/credential/bmc

Request samples

Content type
application/json
{
  • "siteId": "60189e9c-7d12-438c-b9ca-6998d9c364b1",
  • "kind": "SiteWideRoot",
  • "password": "string",
  • "username": "string",
  • "macAddress": "string"
}

Response samples

Content type
application/json
{
  • "siteId": "60189e9c-7d12-438c-b9ca-6998d9c364b1",
  • "kind": "SiteWideRoot",
  • "username": "string",
  • "macAddress": "string"
}