diff --git a/rest-api/flow/internal/converter/protobuf/converter.go b/rest-api/flow/internal/converter/protobuf/converter.go index a139f52c4e..a37db7aecc 100644 --- a/rest-api/flow/internal/converter/protobuf/converter.go +++ b/rest-api/flow/internal/converter/protobuf/converter.go @@ -1046,9 +1046,24 @@ func TargetSpecFrom(ts *pb.OperationTargetSpec) (operation.TargetSpec, error) { } spec.Components = append(spec.Components, ct) } + case *pb.OperationTargetSpec_NvlDomains: + if len(targets.NvlDomains.GetTargets()) == 0 { + return operation.TargetSpec{}, fmt.Errorf( + "nvl_domains.targets must have at least one entry", + ) + } + for _, pbDomain := range targets.NvlDomains.GetTargets() { + dt, err := NVLDomainTargetFrom(pbDomain) + if err != nil { + return operation.TargetSpec{}, fmt.Errorf( + "convert NVLink domain target: %w", err, + ) + } + spec.NVLDomains = append(spec.NVLDomains, dt) + } default: return operation.TargetSpec{}, fmt.Errorf( - "target_spec must have either racks or components set", + "target_spec must have one of racks, nvl_domains, or components set", ) } @@ -1056,17 +1071,21 @@ func TargetSpecFrom(ts *pb.OperationTargetSpec) (operation.TargetSpec, error) { } // TargetSpecTo converts an internal operation.TargetSpec to its proto form. -// It returns an error when both or neither of Racks and Components are populated, -// matching the mutual-exclusion rule enforced by TargetSpecFrom on the inbound path. +// It returns an error unless exactly one target kind is populated, matching the +// mutual-exclusion rule enforced by TargetSpecFrom on the inbound path. func TargetSpecTo(ts operation.TargetSpec) (*pb.OperationTargetSpec, error) { hasRacks := len(ts.Racks) > 0 + hasNVLDomains := len(ts.NVLDomains) > 0 hasComponents := len(ts.Components) > 0 - if hasRacks && hasComponents { - return nil, fmt.Errorf("target_spec cannot have both racks and components set") + targetKinds := 0 + for _, present := range []bool{hasRacks, hasNVLDomains, hasComponents} { + if present { + targetKinds++ + } } - if !hasRacks && !hasComponents { - return nil, fmt.Errorf("target_spec must have either racks or components set") + if targetKinds != 1 { + return nil, fmt.Errorf("target_spec must have exactly one of racks, nvl_domains, or components set") } // Rack targets, converted to proto RackTargets. @@ -1087,12 +1106,13 @@ func TargetSpecTo(ts operation.TargetSpec) (*pb.OperationTargetSpec, error) { } for _, ct := range r.ComponentTypes { - if ct == devicetypes.ComponentTypeUnknown { + protoType := ComponentTypeTo(ct) + if protoType == pb.ComponentType_COMPONENT_TYPE_UNKNOWN { return nil, fmt.Errorf( "invalid rack target: unknown component type filter", ) } - rt.ComponentTypes = append(rt.ComponentTypes, ComponentTypeTo(ct)) + rt.ComponentTypes = append(rt.ComponentTypes, protoType) } racks = append(racks, rt) @@ -1107,6 +1127,47 @@ func TargetSpecTo(ts operation.TargetSpec) (*pb.OperationTargetSpec, error) { }, nil } + if hasNVLDomains { + domains := make([]*pb.NVLDomainTarget, 0, len(ts.NVLDomains)) + for _, domain := range ts.NVLDomains { + target := &pb.NVLDomainTarget{} + if domain.Identifier.ID != uuid.Nil { + target.Identifier = &pb.NVLDomainTarget_Id{ + Id: UUIDTo(domain.Identifier.ID), + } + } else if domain.Identifier.Name != "" { + target.Identifier = &pb.NVLDomainTarget_Name{ + Name: domain.Identifier.Name, + } + } else { + return nil, fmt.Errorf("invalid NVLink domain target: neither id nor name is set") + } + + for _, componentType := range domain.ComponentTypes { + protoType := ComponentTypeTo(componentType) + if protoType == pb.ComponentType_COMPONENT_TYPE_UNKNOWN { + return nil, fmt.Errorf( + "invalid NVLink domain target: unknown component type filter", + ) + } + target.ComponentTypes = append( + target.ComponentTypes, + protoType, + ) + } + + domains = append(domains, target) + } + + return &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{ + Targets: domains, + }, + }, + }, nil + } + // Component targets, converted to proto ComponentTargets. comps := make([]*pb.ComponentTarget, 0, len(ts.Components)) for _, c := range ts.Components { @@ -1138,6 +1199,46 @@ func TargetSpecTo(ts operation.TargetSpec) (*pb.OperationTargetSpec, error) { }, nil } +// NVLDomainTargetFrom converts a proto NVLink domain target to an internal target. +func NVLDomainTargetFrom(dt *pb.NVLDomainTarget) (operation.NVLDomainTarget, error) { + if dt == nil { + return operation.NVLDomainTarget{}, fmt.Errorf("NVLink domain target is nil") + } + + var target operation.NVLDomainTarget + switch id := dt.GetIdentifier().(type) { + case *pb.NVLDomainTarget_Id: + parsed, err := uuid.Parse(id.Id.GetId()) + if err != nil { + return operation.NVLDomainTarget{}, fmt.Errorf( + "invalid NVLink domain id %q: %w", id.Id.GetId(), err, + ) + } + target.Identifier.ID = parsed + case *pb.NVLDomainTarget_Name: + if id.Name == "" { + return operation.NVLDomainTarget{}, fmt.Errorf("NVLink domain target name must not be empty") + } + target.Identifier.Name = id.Name + default: + return operation.NVLDomainTarget{}, fmt.Errorf( + "NVLink domain target must have either id or name set", + ) + } + + for _, pbType := range dt.GetComponentTypes() { + componentType := ComponentTypeFrom(pbType) + if componentType == devicetypes.ComponentTypeUnknown { + return operation.NVLDomainTarget{}, fmt.Errorf( + "unknown component type %v in NVLink domain target filter", pbType, + ) + } + target.ComponentTypes = append(target.ComponentTypes, componentType) + } + + return target, nil +} + // RackTargetFrom converts a proto RackTarget to an internal operation.RackTarget. func RackTargetFrom(rt *pb.RackTarget) (operation.RackTarget, error) { if rt == nil { @@ -1212,7 +1313,7 @@ func ComponentTargetFrom(ct *pb.ComponentTarget) (operation.ComponentTarget, err // ScheduledOperationFrom converts a proto ScheduledOperation oneof to the // internal Operation, TargetSpec, and request-level scheduling options. All // values are always valid together: the Operation carries the task-type and -// parameters, the TargetSpec identifies the racks or components the task will +// parameters, the TargetSpec identifies the racks, NVLink domains, or components the task will // run against, and the returned QueueOptions / rule UUID carry the caller's // conflict-handling and rule-override preferences for use at fire time. func ScheduledOperationFrom( diff --git a/rest-api/flow/internal/converter/protobuf/converter_test.go b/rest-api/flow/internal/converter/protobuf/converter_test.go index 17d4869789..b8393d4cac 100644 --- a/rest-api/flow/internal/converter/protobuf/converter_test.go +++ b/rest-api/flow/internal/converter/protobuf/converter_test.go @@ -917,6 +917,72 @@ func TestComponentTargetFrom(t *testing.T) { } } +func TestNVLDomainTargetFrom(t *testing.T) { + domainID := uuid.New() + testCases := map[string]struct { + input *pb.NVLDomainTarget + want operation.NVLDomainTarget + wantErr string + }{ + "nil input": { + wantErr: "NVLink domain target is nil", + }, + "no identifier": { + input: &pb.NVLDomainTarget{}, + wantErr: "must have either id or name set", + }, + "ID with filter": { + input: &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Id{Id: &pb.UUID{Id: domainID.String()}}, + ComponentTypes: []pb.ComponentType{ + pb.ComponentType_COMPONENT_TYPE_COMPUTE, + }, + }, + want: operation.NVLDomainTarget{ + Identifier: identifier.Identifier{ID: domainID}, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentTypeCompute, + }, + }, + }, + "name": { + input: &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Name{Name: "domain-1"}, + }, + want: operation.NVLDomainTarget{ + Identifier: identifier.Identifier{Name: "domain-1"}, + }, + }, + "invalid ID": { + input: &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Id{Id: &pb.UUID{Id: "invalid"}}, + }, + wantErr: "invalid NVLink domain id", + }, + "unknown component type": { + input: &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Name{Name: "domain-1"}, + ComponentTypes: []pb.ComponentType{ + pb.ComponentType_COMPONENT_TYPE_UNKNOWN, + }, + }, + wantErr: "unknown component type", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + got, err := NVLDomainTargetFrom(testCase.input) + if testCase.wantErr != "" { + assert.ErrorContains(t, err, testCase.wantErr) + return + } + assert.NoError(t, err) + assert.Equal(t, testCase.want, got) + }) + } +} + func TestTargetSpecTo(t *testing.T) { rackID := uuid.New() compID := uuid.New() @@ -925,16 +991,16 @@ func TestTargetSpecTo(t *testing.T) { input operation.TargetSpec wantErr string }{ - "both racks and components set": { + "multiple target kinds set": { input: operation.TargetSpec{ Racks: []operation.RackTarget{{Identifier: identifier.Identifier{Name: "rack-1"}}}, Components: []operation.ComponentTarget{{UUID: compID}}, }, - wantErr: "cannot have both racks and components", + wantErr: "must have exactly one of racks, nvl_domains, or components", }, - "neither racks nor components set": { + "no target kind set": { input: operation.TargetSpec{}, - wantErr: "must have either racks or components", + wantErr: "must have exactly one of racks, nvl_domains, or components", }, "rack target by name": { input: operation.TargetSpec{ @@ -955,6 +1021,31 @@ func TestTargetSpecTo(t *testing.T) { Components: []operation.ComponentTarget{{UUID: compID}}, }, }, + "NVLink domain target by UUID": { + input: operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: rackID}, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentTypeCompute, + }, + }, + }, + }, + }, + "NVLink domain target with unmapped component type": { + input: operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: rackID}, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentType(999), + }, + }, + }, + }, + wantErr: "unknown component type filter", + }, "component target with no UUID and no external": { input: operation.TargetSpec{ Components: []operation.ComponentTarget{{}}, @@ -985,6 +1076,60 @@ func TestTargetSpecTo(t *testing.T) { } } +func TestTargetSpecFromNVLDomains(t *testing.T) { + domainID := uuid.New() + testCases := map[string]struct { + input *pb.OperationTargetSpec + want operation.TargetSpec + wantErr string + }{ + "empty targets": { + input: &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{}, + }, + }, + wantErr: "nvl_domains.targets must have at least one entry", + }, + "ID and name targets": { + input: &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{ + Targets: []*pb.NVLDomainTarget{ + { + Identifier: &pb.NVLDomainTarget_Id{ + Id: &pb.UUID{Id: domainID.String()}, + }, + }, + { + Identifier: &pb.NVLDomainTarget_Name{Name: "domain-2"}, + }, + }, + }, + }, + }, + want: operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + {Identifier: identifier.Identifier{ID: domainID}}, + {Identifier: identifier.Identifier{Name: "domain-2"}}, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + got, err := TargetSpecFrom(testCase.input) + if testCase.wantErr != "" { + assert.ErrorContains(t, err, testCase.wantErr) + return + } + assert.NoError(t, err) + assert.Equal(t, testCase.want, got) + }) + } +} + func TestScheduledOperationFrom(t *testing.T) { rackTargetProto := &pb.OperationTargetSpec{ Targets: &pb.OperationTargetSpec_Racks{ diff --git a/rest-api/flow/internal/converter/protobuf/operationrun_converter_test.go b/rest-api/flow/internal/converter/protobuf/operationrun_converter_test.go index 0fdb93dcfd..37970fea9e 100644 --- a/rest-api/flow/internal/converter/protobuf/operationrun_converter_test.go +++ b/rest-api/flow/internal/converter/protobuf/operationrun_converter_test.go @@ -138,6 +138,45 @@ func TestOperationRunToRebuildsConfigurationFromInternalJSON(t *testing.T) { ) } +func TestOperationRunNVLDomainTargetRoundTrip(t *testing.T) { + domainID := uuid.New() + req := validCreateRequest() + req.Configuration.Operation.GetUpgradeFirmware().TargetSpec = &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{ + Targets: []*pb.NVLDomainTarget{ + { + Identifier: &pb.NVLDomainTarget_Id{ + Id: &pb.UUID{Id: domainID.String()}, + }, + ComponentTypes: []pb.ComponentType{ + pb.ComponentType_COMPONENT_TYPE_COMPUTE, + }, + }, + }, + }, + }, + } + + run, err := OperationRunFrom(req) + require.NoError(t, err) + operation := mustUnmarshalOperation(t, run.OperationTemplate) + require.NotNil(t, operation.TargetSpec) + require.Len(t, operation.TargetSpec.NVLDomains, 1) + require.Equal(t, domainID, operation.TargetSpec.NVLDomains[0].Identifier.ID) + + got, err := OperationRunTo(run) + require.NoError(t, err) + targets := got.GetConfiguration().GetOperation().GetUpgradeFirmware().GetTargetSpec().GetNvlDomains() + require.Len(t, targets.GetTargets(), 1) + require.Equal(t, domainID.String(), targets.GetTargets()[0].GetId().GetId()) + require.Equal( + t, + []pb.ComponentType{pb.ComponentType_COMPONENT_TYPE_COMPUTE}, + targets.GetTargets()[0].GetComponentTypes(), + ) +} + func TestOperationRunStatusConversionIncludesCompletedWithFailures(t *testing.T) { require.Equal( t, diff --git a/rest-api/flow/internal/inventory/resolver/nvl_domain.go b/rest-api/flow/internal/inventory/resolver/nvl_domain.go new file mode 100644 index 0000000000..808286f183 --- /dev/null +++ b/rest-api/flow/internal/inventory/resolver/nvl_domain.go @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package resolver + +import ( + "context" + "fmt" + + "github.com/google/uuid" + + "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" + identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" + "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/inventoryobjects/rack" +) + +// NVLDomainRackReader provides the inventory lookup needed to expand NVLink +// domain targets into rack targets. +type NVLDomainRackReader interface { + GetRacksForNVLDomain(context.Context, identifier.Identifier) ([]*rack.Rack, error) +} + +// ResolveNVLDomainRackTargets expands NVLink domain targets into rack targets +// while validating that every returned rack has a canonical Flow ID. +func ResolveNVLDomainRackTargets( + ctx context.Context, + inventory NVLDomainRackReader, + domains []operation.NVLDomainTarget, +) ([]operation.RackTarget, error) { + rackTargets := make([]operation.RackTarget, 0) + for domainIndex, domain := range domains { + domainRacks, err := inventory.GetRacksForNVLDomain(ctx, domain.Identifier) + if err != nil { + return nil, fmt.Errorf( + "NVLink domain target %d: %w", + domainIndex, + err, + ) + } + + for rackIndex, domainRack := range domainRacks { + if domainRack == nil || domainRack.Info.ID == uuid.Nil { + return nil, fmt.Errorf( + "NVLink domain target %d rack %d has no ID", + domainIndex, + rackIndex, + ) + } + + rackTargets = append(rackTargets, operation.RackTarget{ + Identifier: identifier.Identifier{ID: domainRack.Info.ID}, + ComponentTypes: domain.ComponentTypes, + }) + } + } + + return rackTargets, nil +} diff --git a/rest-api/flow/internal/inventory/resolver/nvl_domain_test.go b/rest-api/flow/internal/inventory/resolver/nvl_domain_test.go new file mode 100644 index 0000000000..8877321860 --- /dev/null +++ b/rest-api/flow/internal/inventory/resolver/nvl_domain_test.go @@ -0,0 +1,125 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package resolver + +import ( + "context" + "errors" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" + identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" + "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/deviceinfo" + "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/devicetypes" + "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/inventoryobjects/rack" +) + +func TestResolveNVLDomainRackTargets(t *testing.T) { + domainOneID := uuid.New() + domainTwoID := uuid.New() + rackOneID := uuid.New() + rackTwoID := uuid.New() + lookupErr := errors.New("lookup failed") + + tests := []struct { + name string + domains []operation.NVLDomainTarget + inventory *fakeNVLDomainRackReader + want []operation.RackTarget + wantErr string + wantLookups []identifier.Identifier + }{ + { + name: "expands domains and preserves component filters", + domains: []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: domainOneID}, + ComponentTypes: []devicetypes.ComponentType{devicetypes.ComponentTypeCompute}, + }, + {Identifier: identifier.Identifier{ID: domainTwoID}}, + }, + inventory: &fakeNVLDomainRackReader{ + racksByDomain: map[identifier.Identifier][]*rack.Rack{ + {ID: domainOneID}: {{Info: deviceinfo.DeviceInfo{ID: rackOneID}}}, + {ID: domainTwoID}: {{Info: deviceinfo.DeviceInfo{ID: rackTwoID}}}, + }, + }, + want: []operation.RackTarget{ + { + Identifier: identifier.Identifier{ID: rackOneID}, + ComponentTypes: []devicetypes.ComponentType{devicetypes.ComponentTypeCompute}, + }, + {Identifier: identifier.Identifier{ID: rackTwoID}}, + }, + wantLookups: []identifier.Identifier{{ID: domainOneID}, {ID: domainTwoID}}, + }, + { + name: "reports lookup failure with domain index", + domains: []operation.NVLDomainTarget{ + {Identifier: identifier.Identifier{ID: domainOneID}}, + {Identifier: identifier.Identifier{ID: domainTwoID}}, + }, + inventory: &fakeNVLDomainRackReader{ + racksByDomain: map[identifier.Identifier][]*rack.Rack{ + {ID: domainOneID}: {{Info: deviceinfo.DeviceInfo{ID: rackOneID}}}, + }, + errorsByDomain: map[identifier.Identifier]error{{ID: domainTwoID}: lookupErr}, + }, + wantErr: "NVLink domain target 1: lookup failed", + wantLookups: []identifier.Identifier{{ID: domainOneID}, {ID: domainTwoID}}, + }, + { + name: "rejects nil rack", + domains: []operation.NVLDomainTarget{{Identifier: identifier.Identifier{ID: domainOneID}}}, + inventory: &fakeNVLDomainRackReader{ + racksByDomain: map[identifier.Identifier][]*rack.Rack{{ID: domainOneID}: {nil}}, + }, + wantErr: "NVLink domain target 0 rack 0 has no ID", + wantLookups: []identifier.Identifier{{ID: domainOneID}}, + }, + { + name: "rejects rack without ID", + domains: []operation.NVLDomainTarget{{Identifier: identifier.Identifier{ID: domainOneID}}}, + inventory: &fakeNVLDomainRackReader{ + racksByDomain: map[identifier.Identifier][]*rack.Rack{{ID: domainOneID}: {{}}}, + }, + wantErr: "NVLink domain target 0 rack 0 has no ID", + wantLookups: []identifier.Identifier{{ID: domainOneID}}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := ResolveNVLDomainRackTargets( + context.Background(), + test.inventory, + test.domains, + ) + if test.wantErr != "" { + require.EqualError(t, err, test.wantErr) + } else { + require.NoError(t, err) + require.Equal(t, test.want, got) + } + require.Equal(t, test.wantLookups, test.inventory.lookups) + }) + } +} + +type fakeNVLDomainRackReader struct { + racksByDomain map[identifier.Identifier][]*rack.Rack + errorsByDomain map[identifier.Identifier]error + lookups []identifier.Identifier +} + +func (f *fakeNVLDomainRackReader) GetRacksForNVLDomain( + _ context.Context, + domain identifier.Identifier, +) ([]*rack.Rack, error) { + f.lookups = append(f.lookups, domain) + return f.racksByDomain[domain], f.errorsByDomain[domain] +} diff --git a/rest-api/flow/internal/operation/request.go b/rest-api/flow/internal/operation/request.go index 097c1e87c0..d4287a6e12 100644 --- a/rest-api/flow/internal/operation/request.go +++ b/rest-api/flow/internal/operation/request.go @@ -35,7 +35,7 @@ const ( // Task per rack. type Request struct { Operation Wrapper - TargetSpec TargetSpec // Either racks or components, not both + TargetSpec TargetSpec // Exactly one of racks, NVLink domains, or components Description string // ConflictStrategy controls how the task behaves when a conflict is diff --git a/rest-api/flow/internal/operation/target.go b/rest-api/flow/internal/operation/target.go index 6e4bec4979..e61d49581b 100644 --- a/rest-api/flow/internal/operation/target.go +++ b/rest-api/flow/internal/operation/target.go @@ -20,11 +20,12 @@ import ( // contain names, external component IDs, or type filters that still need to be // resolved against inventory before an operation can execute. -// TargetSpec contains either rack targets or component targets, but not both. -// This enforces single-type targeting at the type level. +// TargetSpec contains exactly one kind of target: racks, NVLink domains, or +// components. type TargetSpec struct { - Racks []RackTarget // Set if targeting racks (mutually exclusive with Components) - Components []ComponentTarget // Set if targeting components (mutually exclusive with Racks) + Racks []RackTarget + NVLDomains []NVLDomainTarget + Components []ComponentTarget } // IsRackTargeting returns true if this spec targets racks. @@ -37,27 +38,48 @@ func (ts *TargetSpec) IsComponentTargeting() bool { return len(ts.Components) > 0 } +// IsNVLDomainTargeting returns true if this spec targets NVLink domains. +func (ts *TargetSpec) IsNVLDomainTargeting() bool { + return len(ts.NVLDomains) > 0 +} + // Validate validates the target specification. func (ts *TargetSpec) Validate() error { if ts == nil { return fmt.Errorf("target spec is nil") } + targetKinds := 0 if ts.IsRackTargeting() { - if ts.IsComponentTargeting() { - return fmt.Errorf("target_spec cannot have both racks and components set") - } + targetKinds++ + } + if ts.IsNVLDomainTargeting() { + targetKinds++ + } + if ts.IsComponentTargeting() { + targetKinds++ + } + if targetKinds != 1 { + return fmt.Errorf("target_spec must have exactly one of racks, nvl_domains, or components set") + } + if ts.IsRackTargeting() { for _, rt := range ts.Racks { if err := rt.Validate(); err != nil { return fmt.Errorf("invalid rack target: %w", err) } } - } else { - if !ts.IsComponentTargeting() { - return fmt.Errorf("target_spec must have either racks or components set") + } + + if ts.IsNVLDomainTargeting() { + for _, dt := range ts.NVLDomains { + if err := dt.Validate(); err != nil { + return fmt.Errorf("invalid NVLink domain target: %w", err) + } } + } + if ts.IsComponentTargeting() { for _, ct := range ts.Components { if err := ct.Validate(); err != nil { return fmt.Errorf("invalid component target: %w", err) @@ -68,6 +90,31 @@ func (ts *TargetSpec) Validate() error { return nil } +// NVLDomainTarget identifies an NVLink domain with optional component type +// filtering. The domain is resolved to its member racks before execution. +type NVLDomainTarget struct { + Identifier identifier.Identifier + ComponentTypes []devicetypes.ComponentType +} + +func (dt *NVLDomainTarget) Validate() error { + if dt == nil { + return fmt.Errorf("NVLink domain target is nil") + } + + if !dt.Identifier.ValidateAtLeastOne() { + return fmt.Errorf("NVLink domain target must have either id or name set") + } + + for _, ctype := range dt.ComponentTypes { + if ctype == devicetypes.ComponentTypeUnknown { + return fmt.Errorf("unknown component type") + } + } + + return nil +} + // RackTarget identifies a rack with optional component type filtering. // To target specific components, use the component-level APIs instead. type RackTarget struct { diff --git a/rest-api/flow/internal/operation/target_test.go b/rest-api/flow/internal/operation/target_test.go new file mode 100644 index 0000000000..2232c790fa --- /dev/null +++ b/rest-api/flow/internal/operation/target_test.go @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package operation + +import ( + "testing" + + "github.com/stretchr/testify/require" + + identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" +) + +func TestTargetSpecValidateTargetKinds(t *testing.T) { + testCases := map[string]struct { + targetSpec *TargetSpec + wantErr string + }{ + "nil": { + wantErr: "target spec is nil", + }, + "empty": { + targetSpec: &TargetSpec{}, + wantErr: "must have exactly one", + }, + "rack": { + targetSpec: &TargetSpec{ + Racks: []RackTarget{{Identifier: identifier.Identifier{Name: "rack-1"}}}, + }, + }, + "NVLink domain": { + targetSpec: &TargetSpec{ + NVLDomains: []NVLDomainTarget{ + {Identifier: identifier.Identifier{Name: "domain-1"}}, + }, + }, + }, + "multiple target kinds": { + targetSpec: &TargetSpec{ + Racks: []RackTarget{{Identifier: identifier.Identifier{Name: "rack-1"}}}, + NVLDomains: []NVLDomainTarget{ + {Identifier: identifier.Identifier{Name: "domain-1"}}, + }, + }, + wantErr: "must have exactly one", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + err := testCase.targetSpec.Validate() + if testCase.wantErr != "" { + require.ErrorContains(t, err, testCase.wantErr) + return + } + require.NoError(t, err) + }) + } +} diff --git a/rest-api/flow/internal/operationrun/configuration_test.go b/rest-api/flow/internal/operationrun/configuration_test.go index 5d45bbe2a3..67248fb0e7 100644 --- a/rest-api/flow/internal/operationrun/configuration_test.go +++ b/rest-api/flow/internal/operationrun/configuration_test.go @@ -34,7 +34,7 @@ func TestOperationValidateRejectsInvalidTargetSpec(t *testing.T) { op.TargetSpec = &operation.TargetSpec{} err := op.Validate() - require.ErrorContains(t, err, "target_spec: target_spec must have either racks or components set") + require.ErrorContains(t, err, "target_spec: target_spec must have exactly one of racks, nvl_domains, or components set") } func TestOperationValidateRejectsDefaultScopeFilterWithTargetSpec(t *testing.T) { diff --git a/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup.go b/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup.go index f1a1da25be..06402e2727 100644 --- a/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup.go +++ b/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup.go @@ -11,6 +11,7 @@ import ( "github.com/google/uuid" dbquery "github.com/NVIDIA/infra-controller/rest-api/flow/internal/db/query" + inventoryresolver "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/resolver" "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" operationrun "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operationrun" identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" @@ -24,6 +25,7 @@ import ( // this interface. type InventoryTargetSource interface { GetRackByIdentifier(ctx context.Context, identifier identifier.Identifier, withComponents bool) (*rack.Rack, error) + GetRacksForNVLDomain(ctx context.Context, domainIdentifier identifier.Identifier) ([]*rack.Rack, error) GetListOfRacks(ctx context.Context, info dbquery.StringQueryInfo, manufacturerFilter *dbquery.StringQueryInfo, modelFilter *dbquery.StringQueryInfo, pagination *dbquery.Pagination, orderBy *dbquery.OrderBy, withComponents bool) ([]*rack.Rack, int32, error) GetComponentByID(ctx context.Context, id uuid.UUID) (*inventorycomponent.Component, error) GetComponentsByExternalIDs(ctx context.Context, externalIDs []string) ([]*inventorycomponent.Component, error) @@ -132,6 +134,8 @@ func (l *InventoryTargetLookup) TargetsFromSpec( var err error if spec.IsRackTargeting() { targets, err = l.targetsFromRackSpec(ctx, spec.Racks) + } else if spec.IsNVLDomainTargeting() { + targets, err = l.targetsFromNVLDomainSpec(ctx, spec.NVLDomains) } else { targets, err = l.targetsFromComponentSpec(ctx, spec.Components) } @@ -197,6 +201,47 @@ func (l *InventoryTargetLookup) requireInventory() error { return nil } +func (l *InventoryTargetLookup) targetsFromNVLDomainSpec( + ctx context.Context, + domainTargets []operation.NVLDomainTarget, +) ([]operation.RackExecutionTarget, error) { + rackTargets, err := inventoryresolver.ResolveNVLDomainRackTargets( + ctx, + l.inventory, + domainTargets, + ) + if err != nil { + return nil, err + } + + targets := make([]operation.RackExecutionTarget, 0) + for rackIndex, rackTarget := range rackTargets { + r, err := l.inventory.GetRackByIdentifier( + ctx, + rackTarget.Identifier, + true, + ) + if err != nil { + return nil, fmt.Errorf("NVLink domain rack target %d: %w", rackIndex, err) + } + + target, ok := executionTargetFromRack( + r, + componentFilterFromTypes(rackTarget.ComponentTypes), + ) + if ok { + targets = append(targets, target) + } + } + + normalized, err := executionTargets(targets).normalize() + if err != nil { + return nil, fmt.Errorf("normalize NVLink domain targets: %w", err) + } + + return []operation.RackExecutionTarget(normalized), nil +} + func (l *InventoryTargetLookup) targetsFromRackSpec( ctx context.Context, rackTargets []operation.RackTarget, diff --git a/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup_test.go b/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup_test.go index 3d80d03fb5..1d90f06f17 100644 --- a/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup_test.go +++ b/rest-api/flow/internal/operationrun/manager/planner/inventory_target_lookup_test.go @@ -138,6 +138,120 @@ func TestInventoryTargetLookupTargetsFromComponentSpec(t *testing.T) { ) } +func TestInventoryTargetLookupTargetsFromNVLDomainSpec(t *testing.T) { + t.Run("filters component types across domain racks", func(t *testing.T) { + domainID := uuid.New() + rackOneID := uuid.New() + rackTwoID := uuid.New() + computeOneID := uuid.New() + computeTwoID := uuid.New() + inventory := &fakeInventoryTargetSource{ + domainRacks: map[uuid.UUID][]*rack.Rack{ + domainID: { + rackWithComponents(rackOneID), + rackWithComponents(rackTwoID), + }, + }, + racksByID: map[uuid.UUID]*rack.Rack{ + rackOneID: rackWithComponents( + rackOneID, + componentWithRack( + computeOneID, + rackOneID, + devicetypes.ComponentTypeCompute, + "", + ), + ), + rackTwoID: rackWithComponents( + rackTwoID, + componentWithRack( + computeTwoID, + rackTwoID, + devicetypes.ComponentTypeCompute, + "", + ), + ), + }, + } + + targets, err := NewInventoryTargetLookup(inventory, nil).TargetsFromSpec( + context.Background(), + &operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: domainID}, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentTypeCompute, + }, + }, + }, + }, + TargetLookupOptions{}, + ) + require.NoError(t, err) + require.Equal(t, []operation.RackExecutionTarget{ + { + RackID: rackOneID, + ComponentsByType: operation.ComponentsByType{ + devicetypes.ComponentTypeCompute: {computeOneID}, + }, + }, + { + RackID: rackTwoID, + ComponentsByType: operation.ComponentsByType{ + devicetypes.ComponentTypeCompute: {computeTwoID}, + }, + }, + }, targets) + }) + + t.Run("merges repeated racks before enforcing limit", func(t *testing.T) { + domainID := uuid.New() + rackID := uuid.New() + computeID := uuid.New() + nvSwitchID := uuid.New() + inventory := &fakeInventoryTargetSource{ + domainRacks: map[uuid.UUID][]*rack.Rack{ + domainID: {rackWithComponents(rackID)}, + }, + racksByID: map[uuid.UUID]*rack.Rack{ + rackID: rackWithComponents( + rackID, + componentWithRack(computeID, rackID, devicetypes.ComponentTypeCompute, ""), + componentWithRack(nvSwitchID, rackID, devicetypes.ComponentTypeNVSwitch, ""), + ), + }, + } + + targets, err := NewInventoryTargetLookup(inventory, nil).TargetsFromSpec( + context.Background(), + &operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: domainID}, + ComponentTypes: []devicetypes.ComponentType{devicetypes.ComponentTypeCompute}, + }, + { + Identifier: identifier.Identifier{ID: domainID}, + ComponentTypes: []devicetypes.ComponentType{devicetypes.ComponentTypeNVSwitch}, + }, + }, + }, + TargetLookupOptions{MaxTargets: 1}, + ) + require.NoError(t, err) + require.Equal(t, []operation.RackExecutionTarget{ + { + RackID: rackID, + ComponentsByType: operation.ComponentsByType{ + devicetypes.ComponentTypeCompute: {computeID}, + devicetypes.ComponentTypeNVSwitch: {nvSwitchID}, + }, + }, + }, targets) + }) +} + func TestInventoryTargetLookupTargetsFromDefaultScopeAppliesComponentFilter(t *testing.T) { rackID := uuid.New() computeID := uuid.New() @@ -344,12 +458,20 @@ func TestInventoryTargetLookupTargetsFromRunsReadsAllMaterializedTargets(t *test type fakeInventoryTargetSource struct { racks []*rack.Rack racksByID map[uuid.UUID]*rack.Rack + domainRacks map[uuid.UUID][]*rack.Rack componentsByID map[uuid.UUID]*inventorycomponent.Component externalComponents []*inventorycomponent.Component total int32 paginations []dbquery.Pagination } +func (s *fakeInventoryTargetSource) GetRacksForNVLDomain( + _ context.Context, + id identifier.Identifier, +) ([]*rack.Rack, error) { + return s.domainRacks[id.ID], nil +} + func (s *fakeInventoryTargetSource) GetRackByIdentifier( _ context.Context, id identifier.Identifier, diff --git a/rest-api/flow/internal/service/component_api_test.go b/rest-api/flow/internal/service/component_api_test.go index ad4437b1e7..b404e7bd57 100644 --- a/rest-api/flow/internal/service/component_api_test.go +++ b/rest-api/flow/internal/service/component_api_test.go @@ -14,6 +14,7 @@ import ( inventorymanager "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/manager" inventorystore "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/store" + identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/deviceinfo" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/devicetypes" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/inventoryobjects/bmc" @@ -27,18 +28,35 @@ import ( type mockManager struct { inventorymanager.Manager // embed to satisfy the interface; unimplemented methods will panic - components map[uuid.UUID]*component.Component - racks map[uuid.UUID]*rack.Rack - drifts []inventorystore.ComponentDrift + components map[uuid.UUID]*component.Component + racks map[uuid.UUID]*rack.Rack + domainRacks map[uuid.UUID][]*rack.Rack + drifts []inventorystore.ComponentDrift } func newMockManager() *mockManager { return &mockManager{ - components: make(map[uuid.UUID]*component.Component), - racks: make(map[uuid.UUID]*rack.Rack), + components: make(map[uuid.UUID]*component.Component), + racks: make(map[uuid.UUID]*rack.Rack), + domainRacks: make(map[uuid.UUID][]*rack.Rack), } } +func (m *mockManager) GetRackByIdentifier( + _ context.Context, + id identifier.Identifier, + _ bool, +) (*rack.Rack, error) { + return m.GetRackByID(context.Background(), id.ID, true) +} + +func (m *mockManager) GetRacksForNVLDomain( + _ context.Context, + id identifier.Identifier, +) ([]*rack.Rack, error) { + return m.domainRacks[id.ID], nil +} + func (m *mockManager) GetDriftsByComponentIDs(_ context.Context, componentIDs []uuid.UUID) ([]inventorystore.ComponentDrift, error) { idSet := make(map[uuid.UUID]bool, len(componentIDs)) for _, id := range componentIDs { @@ -500,6 +518,46 @@ func TestGetComponents_TargetSpecWithPagination(t *testing.T) { assert.Equal(t, 2, len(resp.Components)) } +func TestGetComponents_NVLinkDomainTarget(t *testing.T) { + mgr := newMockManager() + rackID, _ := setupValidateTestData(mgr) + domainID := uuid.New() + mgr.domainRacks[domainID] = []*rack.Rack{mgr.racks[rackID]} + server := &FlowServerImpl{inventoryManager: mgr} + + resp, err := server.GetComponents(context.Background(), &pb.GetComponentsRequest{ + TargetSpec: &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{ + Targets: []*pb.NVLDomainTarget{ + { + Identifier: &pb.NVLDomainTarget_Id{ + Id: &pb.UUID{Id: domainID.String()}, + }, + ComponentTypes: []pb.ComponentType{ + pb.ComponentType_COMPONENT_TYPE_COMPUTE, + }, + }, + { + Identifier: &pb.NVLDomainTarget_Id{ + Id: &pb.UUID{Id: domainID.String()}, + }, + ComponentTypes: []pb.ComponentType{ + pb.ComponentType_COMPONENT_TYPE_COMPUTE, + }, + }, + }, + }, + }, + }, + }) + + require.NoError(t, err) + require.NotNil(t, resp) + assert.Equal(t, int32(2), resp.Total) + assert.Len(t, resp.Components, 2) +} + // --- ValidateComponents Tests --- // helper to build a rack with components for validate tests diff --git a/rest-api/flow/internal/service/server_impl.go b/rest-api/flow/internal/service/server_impl.go index 4aa7cb44e6..deb18fe42a 100644 --- a/rest-api/flow/internal/service/server_impl.go +++ b/rest-api/flow/internal/service/server_impl.go @@ -24,7 +24,7 @@ import ( "github.com/NVIDIA/infra-controller/rest-api/flow/internal/converter/protobuf" dbquery "github.com/NVIDIA/infra-controller/rest-api/flow/internal/db/query" inventorymanager "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/manager" - + inventoryresolver "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/resolver" "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" operationrunmanager "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operationrun/manager" taskschedule "github.com/NVIDIA/infra-controller/rest-api/flow/internal/scheduler/taskschedule" @@ -1366,7 +1366,7 @@ func (rs *FlowServerImpl) UpgradeFirmware( } // GetComponents retrieves components from local database with filtering, pagination, and ordering support. -// If target_spec is provided, it extracts components from the specified racks or components first, +// If target_spec is provided, it extracts components from the specified racks, NVLink domains, or components first, // then applies additional filters (name, manufacturer, model, component_types), pagination, and ordering. // If target_spec is not provided, it queries all components matching the filters. func (rs *FlowServerImpl) GetComponents( @@ -1443,7 +1443,7 @@ func (rs *FlowServerImpl) GetComponents( // If target_spec is provided, extract components from it first, then apply filters if req.GetTargetSpec() != nil { - // Extract components from target_spec (racks or components) + // Extract components from target_spec. targetComponents, err := rs.extractComponentsFromTargetSpec(ctx, req.GetTargetSpec()) if err != nil { return nil, fmt.Errorf("failed to extract components from target_spec: %w", err) @@ -1899,7 +1899,7 @@ func extractComponentsByTypes(r *rack.Rack, compTypes []devicetypes.ComponentTyp // extractComponentsFromTargetSpec parses and validates targetSpec via // protobuf.TargetSpecFrom (the same converter used by the submission path), -// then resolves each rack or component target against the inventory. +// then resolves each rack, NVLink domain, or component target against the inventory. // Validation errors (malformed UUIDs, empty names, unknown types) are // surfaced identically to the submission path rather than deferring to an // inventory-lookup failure. @@ -1922,6 +1922,22 @@ func (rs *FlowServerImpl) extractComponentsFromTargetSpec( components = append(components, resolved...) } + domainRackTargets, err := inventoryresolver.ResolveNVLDomainRackTargets( + ctx, + rs.inventoryManager, + spec.NVLDomains, + ) + if err != nil { + return nil, fmt.Errorf("failed to resolve NVLink domain targets: %w", err) + } + for _, rackTarget := range domainRackTargets { + resolved, err := rs.resolveRackTarget(ctx, rackTarget) + if err != nil { + return nil, err + } + components = append(components, resolved...) + } + for _, ct := range spec.Components { resolved, err := rs.fetchComponentTarget(ctx, ct) if err != nil { @@ -1930,7 +1946,18 @@ func (rs *FlowServerImpl) extractComponentsFromTargetSpec( components = append(components, resolved...) } - return components, nil + uniqueComponents := make([]*component.Component, 0, len(components)) + seenComponentIDs := make(map[uuid.UUID]struct{}, len(components)) + for _, comp := range components { + _, exists := seenComponentIDs[comp.Info.ID] + if exists { + continue + } + seenComponentIDs[comp.Info.ID] = struct{}{} + uniqueComponents = append(uniqueComponents, comp) + } + + return uniqueComponents, nil } // resolveRackTarget fetches the rack from inventory and returns its components, diff --git a/rest-api/flow/internal/service/server_impl_task_schedule.go b/rest-api/flow/internal/service/server_impl_task_schedule.go index 862e68355d..7a961e9aa8 100644 --- a/rest-api/flow/internal/service/server_impl_task_schedule.go +++ b/rest-api/flow/internal/service/server_impl_task_schedule.go @@ -23,6 +23,7 @@ import ( "github.com/NVIDIA/infra-controller/rest-api/flow/internal/converter/protobuf" dbmodel "github.com/NVIDIA/infra-controller/rest-api/flow/internal/db/model" dbquery "github.com/NVIDIA/infra-controller/rest-api/flow/internal/db/query" + inventoryresolver "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/resolver" "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" taskschedule "github.com/NVIDIA/infra-controller/rest-api/flow/internal/scheduler/taskschedule" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/devicetypes" @@ -886,10 +887,10 @@ func (rs *FlowServerImpl) buildUpdateFields( } // resolveScope converts an internal TargetSpec into DB scope rows ready for -// insertion (ScheduleID is not yet set). Supports both rack-level targeting -// (with optional component-type filter) and component-level targeting (specific -// components by UUID or external ref). For component-level targets the server -// resolves rack membership and groups components into per-rack scope entries. +// insertion (ScheduleID is not yet set). Rack and NVLink domain targets may +// include a component-type filter; component targets identify specific +// components. Domain membership is materialized to rack scopes when this method +// runs, so later membership changes do not silently change an existing schedule. func (rs *FlowServerImpl) resolveScope( ctx context.Context, ts operation.TargetSpec, @@ -897,10 +898,29 @@ func (rs *FlowServerImpl) resolveScope( if ts.IsRackTargeting() { return rs.resolveRackScope(ctx, ts.Racks) } + if ts.IsNVLDomainTargeting() { + return rs.resolveNVLDomainScope(ctx, ts.NVLDomains) + } return rs.resolveComponentScope(ctx, ts.Components) } +func (rs *FlowServerImpl) resolveNVLDomainScope( + ctx context.Context, + domains []operation.NVLDomainTarget, +) ([]*dbmodel.TaskScheduleScope, error) { + rackTargets, err := inventoryresolver.ResolveNVLDomainRackTargets( + ctx, + rs.inventoryManager, + domains, + ) + if err != nil { + return nil, fmt.Errorf("target_spec.nvl_domains: %w", err) + } + + return rs.resolveRackScope(ctx, rackTargets) +} + // resolveScheduleScope is the shared prologue for AddTaskScheduleScope and // UpdateTaskScheduleScope. It verifies the schedule exists and resolves the // target spec into scope rows with ScheduleID stamped. diff --git a/rest-api/flow/internal/service/server_impl_task_schedule_test.go b/rest-api/flow/internal/service/server_impl_task_schedule_test.go index 75092f854b..b43ded1ed4 100644 --- a/rest-api/flow/internal/service/server_impl_task_schedule_test.go +++ b/rest-api/flow/internal/service/server_impl_task_schedule_test.go @@ -18,9 +18,11 @@ import ( "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" taskschedule "github.com/NVIDIA/infra-controller/rest-api/flow/internal/scheduler/taskschedule" taskcommon "github.com/NVIDIA/infra-controller/rest-api/flow/internal/task/common" + identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/deviceinfo" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/devicetypes" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/inventoryobjects/component" + "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/inventoryobjects/rack" pb "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/proto/v1" ) @@ -1041,3 +1043,37 @@ func TestResolveComponentTarget_ExternalID(t *testing.T) { }) } } + +func TestResolveNVLDomainScopeMaterializesRackMembership(t *testing.T) { + mgr := newMockManager() + domainID := uuid.New() + rackIDs := []uuid.UUID{uuid.New(), uuid.New()} + for _, rackID := range rackIDs { + mgr.racks[rackID] = &rack.Rack{ + Info: deviceinfo.DeviceInfo{ID: rackID}, + } + mgr.domainRacks[domainID] = append(mgr.domainRacks[domainID], mgr.racks[rackID]) + } + + scopes, err := (&FlowServerImpl{inventoryManager: mgr}).resolveNVLDomainScope( + context.Background(), + []operation.NVLDomainTarget{ + { + Identifier: identifier.Identifier{ID: domainID}, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentTypeCompute, + }, + }, + }, + ) + require.NoError(t, err) + require.Len(t, scopes, 2) + for index, scope := range scopes { + assert.Equal(t, rackIDs[index], scope.RackID) + filter, err := dbmodel.UnmarshalComponentFilter(scope.ComponentFilter) + require.NoError(t, err) + require.NotNil(t, filter) + assert.Equal(t, dbmodel.ComponentFilterKindTypes, filter.Kind) + assert.Equal(t, []string{"Compute"}, filter.Types) + } +} diff --git a/rest-api/flow/internal/task/manager/resolver.go b/rest-api/flow/internal/task/manager/resolver.go index 6bf9df7d1c..6c82d40673 100644 --- a/rest-api/flow/internal/task/manager/resolver.go +++ b/rest-api/flow/internal/task/manager/resolver.go @@ -9,6 +9,7 @@ import ( "github.com/google/uuid" + inventoryresolver "github.com/NVIDIA/infra-controller/rest-api/flow/internal/inventory/resolver" "github.com/NVIDIA/infra-controller/rest-api/flow/internal/operation" identifier "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/Identifier" "github.com/NVIDIA/infra-controller/rest-api/flow/pkg/common/devicetypes" @@ -19,6 +20,7 @@ import ( // TargetFetcher provides the methods needed to fetch racks and components for target resolution. type TargetFetcher interface { GetRackByIdentifier(ctx context.Context, identifier identifier.Identifier, withComponents bool) (*rack.Rack, error) + GetRacksForNVLDomain(ctx context.Context, domainIdentifier identifier.Identifier) ([]*rack.Rack, error) GetComponentByID(ctx context.Context, id uuid.UUID) (*component.Component, error) GetComponentsByExternalIDs(ctx context.Context, externalIDs []string) ([]*component.Component, error) } @@ -38,13 +40,34 @@ func resolveTargetSpecToRacks( return resolveRackTargetSpec(ctx, fetcher, targetSpec.Racks) } + if targetSpec.IsNVLDomainTargeting() { + return resolveNVLDomainTargetSpec(ctx, fetcher, targetSpec.NVLDomains) + } + if targetSpec.IsComponentTargeting() { return resolveComponentTargetSpec(ctx, fetcher, targetSpec.Components) } // This should be detected by Validate() and should never be here, but // just in case, handle it anyway. - return nil, fmt.Errorf("target spec must have either racks or components set") + return nil, fmt.Errorf("target spec must have one of racks, NVLink domains, or components set") +} + +func resolveNVLDomainTargetSpec( + ctx context.Context, + fetcher TargetFetcher, + targets []operation.NVLDomainTarget, +) (map[uuid.UUID]*rack.Rack, error) { + rackTargets, err := inventoryresolver.ResolveNVLDomainRackTargets( + ctx, + fetcher, + targets, + ) + if err != nil { + return nil, fmt.Errorf("failed to resolve NVLink domain targets: %w", err) + } + + return resolveRackTargetSpec(ctx, fetcher, rackTargets) } func resolveRackTargetSpec( diff --git a/rest-api/flow/internal/task/manager/resolver_test.go b/rest-api/flow/internal/task/manager/resolver_test.go index ae2fbb9c96..909c64718e 100644 --- a/rest-api/flow/internal/task/manager/resolver_test.go +++ b/rest-api/flow/internal/task/manager/resolver_test.go @@ -25,11 +25,14 @@ import ( type mockTargetFetcher struct { racks map[uuid.UUID]*rack.Rack racksByName map[string]*rack.Rack + domainRacks map[uuid.UUID][]*rack.Rack + domainRacksByName map[string][]*rack.Rack components map[uuid.UUID]*component.Component componentsByExternalID map[string][]*component.Component // Error injection getRackErr error + getDomainErr error getComponentErr error getExternalErr error } @@ -38,11 +41,26 @@ func newMockTargetFetcher() *mockTargetFetcher { return &mockTargetFetcher{ racks: make(map[uuid.UUID]*rack.Rack), racksByName: make(map[string]*rack.Rack), + domainRacks: make(map[uuid.UUID][]*rack.Rack), + domainRacksByName: make(map[string][]*rack.Rack), components: make(map[uuid.UUID]*component.Component), componentsByExternalID: make(map[string][]*component.Component), } } +func (m *mockTargetFetcher) GetRacksForNVLDomain( + _ context.Context, + id identifier.Identifier, +) ([]*rack.Rack, error) { + if m.getDomainErr != nil { + return nil, m.getDomainErr + } + if id.ID != uuid.Nil { + return m.domainRacks[id.ID], nil + } + return m.domainRacksByName[id.Name], nil +} + func (m *mockTargetFetcher) GetRackByIdentifier( ctx context.Context, id identifier.Identifier, @@ -364,6 +382,68 @@ func TestResolveTargetSpecToRacks_RackFetchError(t *testing.T) { assert.Nil(t, result) } +func TestResolveTargetSpecToRacks_NVLinkDomainTargets(t *testing.T) { + domainID := uuid.New() + rackOneID := uuid.New() + rackTwoID := uuid.New() + computeID := uuid.New() + nvSwitchID := uuid.New() + rackOne := newTestRack(rackOneID, "rack-1") + rackOne.AddComponent(newTestComponent( + computeID, + rackOneID, + devicetypes.ComponentTypeCompute, + "compute-1", + )) + rackOne.AddComponent(newTestComponent( + nvSwitchID, + rackOneID, + devicetypes.ComponentTypeNVSwitch, + "nvswitch-1", + )) + rackTwo := newTestRack(rackTwoID, "rack-2") + rackTwo.AddComponent(newTestComponent( + uuid.New(), + rackTwoID, + devicetypes.ComponentTypeCompute, + "compute-2", + )) + + testCases := map[string]identifier.Identifier{ + "by ID": {ID: domainID}, + "by name": {Name: "domain-1"}, + } + for name, domainIdentifier := range testCases { + t.Run(name, func(t *testing.T) { + fetcher := newMockTargetFetcher() + fetcher.addRack(rackOne) + fetcher.addRack(rackTwo) + fetcher.domainRacks[domainID] = []*rack.Rack{rackOne, rackTwo} + fetcher.domainRacksByName["domain-1"] = []*rack.Rack{rackOne, rackTwo} + + result, err := resolveTargetSpecToRacks( + context.Background(), + fetcher, + &operation.TargetSpec{ + NVLDomains: []operation.NVLDomainTarget{ + { + Identifier: domainIdentifier, + ComponentTypes: []devicetypes.ComponentType{ + devicetypes.ComponentTypeCompute, + }, + }, + }, + }, + ) + require.NoError(t, err) + require.Len(t, result, 2) + require.Len(t, result[rackOneID].Components, 1) + require.Equal(t, computeID, result[rackOneID].Components[0].Info.ID) + require.Len(t, result[rackTwoID].Components, 1) + }) + } +} + func TestResolveTargetSpecToRacks_ComponentTargetByUUID(t *testing.T) { ctx := context.Background() fetcher := newMockTargetFetcher() diff --git a/rest-api/flow/pkg/client/client.go b/rest-api/flow/pkg/client/client.go index 35517bb39a..199432df44 100644 --- a/rest-api/flow/pkg/client/client.go +++ b/rest-api/flow/pkg/client/client.go @@ -399,6 +399,71 @@ func (c *Client) UpgradeFirmwareByRackNames( }, nil } +// UpgradeFirmwareByNVLDomainIDs upgrades firmware for components in the given NVLink domains. +func (c *Client) UpgradeFirmwareByNVLDomainIDs( + ctx context.Context, + domainIDs []uuid.UUID, + componentType types.ComponentType, + startTime, endTime *time.Time, +) (*UpgradeFirmwareResult, error) { + targets := make([]*pb.NVLDomainTarget, 0, len(domainIDs)) + for _, id := range domainIDs { + targets = append(targets, &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Id{Id: uuidToProto(id)}, + ComponentTypes: componentTypesFilter(componentType), + }) + } + + return c.upgradeFirmwareByNVLDomains(ctx, targets, startTime, endTime) +} + +// UpgradeFirmwareByNVLDomainNames upgrades firmware for components in the given NVLink domains. +func (c *Client) UpgradeFirmwareByNVLDomainNames( + ctx context.Context, + domainNames []string, + componentType types.ComponentType, + startTime, endTime *time.Time, +) (*UpgradeFirmwareResult, error) { + targets := make([]*pb.NVLDomainTarget, 0, len(domainNames)) + for _, name := range domainNames { + targets = append(targets, &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Name{Name: name}, + ComponentTypes: componentTypesFilter(componentType), + }) + } + + return c.upgradeFirmwareByNVLDomains(ctx, targets, startTime, endTime) +} + +func (c *Client) upgradeFirmwareByNVLDomains( + ctx context.Context, + targets []*pb.NVLDomainTarget, + startTime, endTime *time.Time, +) (*UpgradeFirmwareResult, error) { + req := &pb.UpgradeFirmwareRequest{ + TargetSpec: &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{Targets: targets}, + }, + }, + } + if startTime != nil { + req.StartTime = timestamppb.New(*startTime) + } + if endTime != nil { + req.EndTime = timestamppb.New(*endTime) + } + + rsp, err := c.client.UpgradeFirmware(ctx, req) + if err != nil { + return nil, err + } + + return &UpgradeFirmwareResult{ + TaskIDs: uuidsFromProto(rsp.GetTaskIds()), + }, nil +} + // UpgradeFirmwareByMachineIDs upgrades firmware for the given machine IDs (external component IDs). func (c *Client) UpgradeFirmwareByMachineIDs( ctx context.Context, @@ -489,6 +554,50 @@ func (c *Client) PowerControlByRackNames( return c.executePowerControl(ctx, targetSpec, op) } +// PowerControlByNVLDomainIDs performs power control in the given NVLink domains. +func (c *Client) PowerControlByNVLDomainIDs( + ctx context.Context, + domainIDs []uuid.UUID, + componentType types.ComponentType, + op types.PowerControlOp, +) (*PowerControlResult, error) { + targets := make([]*pb.NVLDomainTarget, 0, len(domainIDs)) + for _, id := range domainIDs { + targets = append(targets, &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Id{Id: uuidToProto(id)}, + ComponentTypes: componentTypesFilter(componentType), + }) + } + + return c.executePowerControl(ctx, nvlDomainTargetSpec(targets), op) +} + +// PowerControlByNVLDomainNames performs power control in the given NVLink domains. +func (c *Client) PowerControlByNVLDomainNames( + ctx context.Context, + domainNames []string, + componentType types.ComponentType, + op types.PowerControlOp, +) (*PowerControlResult, error) { + targets := make([]*pb.NVLDomainTarget, 0, len(domainNames)) + for _, name := range domainNames { + targets = append(targets, &pb.NVLDomainTarget{ + Identifier: &pb.NVLDomainTarget_Name{Name: name}, + ComponentTypes: componentTypesFilter(componentType), + }) + } + + return c.executePowerControl(ctx, nvlDomainTargetSpec(targets), op) +} + +func nvlDomainTargetSpec(targets []*pb.NVLDomainTarget) *pb.OperationTargetSpec { + return &pb.OperationTargetSpec{ + Targets: &pb.OperationTargetSpec_NvlDomains{ + NvlDomains: &pb.NVLDomainTargets{Targets: targets}, + }, + } +} + // PowerControlByMachineIDs performs power control on the given machine IDs. func (c *Client) PowerControlByMachineIDs( ctx context.Context, diff --git a/rest-api/flow/pkg/client/external_test.go b/rest-api/flow/pkg/client/external_test.go index 9f096b895e..237303c7ae 100644 --- a/rest-api/flow/pkg/client/external_test.go +++ b/rest-api/flow/pkg/client/external_test.go @@ -74,6 +74,10 @@ func TestExternalUsability(t *testing.T) { _ = client.GetExpectedComponentsResult{} _ = client.ValidateComponentsResult{} _ = client.ListTasksResult{} + _ = (*client.Client).UpgradeFirmwareByNVLDomainIDs + _ = (*client.Client).UpgradeFirmwareByNVLDomainNames + _ = (*client.Client).PowerControlByNVLDomainIDs + _ = (*client.Client).PowerControlByNVLDomainNames // Verify enum types from types package _ = types.ComponentTypeCompute diff --git a/rest-api/flow/pkg/proto/v1/flow.pb.go b/rest-api/flow/pkg/proto/v1/flow.pb.go index ff7c29499e..aae4907587 100644 --- a/rest-api/flow/pkg/proto/v1/flow.pb.go +++ b/rest-api/flow/pkg/proto/v1/flow.pb.go @@ -1917,14 +1917,16 @@ func (x *Identifier) GetName() string { } // OperationTargetSpec contains targets for an operation. -// Supports either rack-level targeting (with optional type filtering) -// or component-level targeting (by UUID or external reference), but not both. +// Supports rack-level or NVLink-domain targeting (with optional type filtering), +// or component-level targeting (by UUID or external reference), but not more +// than one target kind at a time. type OperationTargetSpec struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Targets: // // *OperationTargetSpec_Racks // *OperationTargetSpec_Components + // *OperationTargetSpec_NvlDomains Targets isOperationTargetSpec_Targets `protobuf_oneof:"targets"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1985,6 +1987,15 @@ func (x *OperationTargetSpec) GetComponents() *ComponentTargets { return nil } +func (x *OperationTargetSpec) GetNvlDomains() *NVLDomainTargets { + if x != nil { + if x, ok := x.Targets.(*OperationTargetSpec_NvlDomains); ok { + return x.NvlDomains + } + } + return nil +} + type isOperationTargetSpec_Targets interface { isOperationTargetSpec_Targets() } @@ -1997,10 +2008,16 @@ type OperationTargetSpec_Components struct { Components *ComponentTargets `protobuf:"bytes,2,opt,name=components,proto3,oneof"` } +type OperationTargetSpec_NvlDomains struct { + NvlDomains *NVLDomainTargets `protobuf:"bytes,3,opt,name=nvl_domains,json=nvlDomains,proto3,oneof"` +} + func (*OperationTargetSpec_Racks) isOperationTargetSpec_Targets() {} func (*OperationTargetSpec_Components) isOperationTargetSpec_Targets() {} +func (*OperationTargetSpec_NvlDomains) isOperationTargetSpec_Targets() {} + // RackTargets contains one or more rack targets type RackTargets struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -4159,7 +4176,7 @@ func (x *UpgradeFirmwareRequest) GetOverrideReadinessCheck() bool { // GetComponents - retrieves components from local database type GetComponentsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, queries all components. + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, queries all components. Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries Pagination *Pagination `protobuf:"bytes,3,opt,name=pagination,proto3,oneof" json:"pagination,omitempty"` OrderBy *OrderBy `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3,oneof" json:"order_by,omitempty"` @@ -4279,7 +4296,7 @@ func (x *GetComponentsResponse) GetTotal() int32 { type ValidateComponentsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, returns all diffs. + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, returns all diffs. Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries Pagination *Pagination `protobuf:"bytes,3,opt,name=pagination,proto3,oneof" json:"pagination,omitempty"` OrderBy *OrderBy `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3,oneof" json:"order_by,omitempty"` @@ -5223,7 +5240,7 @@ func (x *QueueOptions) GetQueueTimeoutSeconds() int32 { type PowerOnRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,3,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` RuleId *UUID `protobuf:"bytes,4,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule @@ -5305,7 +5322,7 @@ func (x *PowerOnRackRequest) GetOverrideReadinessCheck() bool { type PowerOffRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Forced bool `protobuf:"varint,2,opt,name=forced,proto3" json:"forced,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,4,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` @@ -5395,7 +5412,7 @@ func (x *PowerOffRackRequest) GetOverrideReadinessCheck() bool { type PowerResetRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Forced bool `protobuf:"varint,2,opt,name=forced,proto3" json:"forced,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,4,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` @@ -5485,7 +5502,7 @@ func (x *PowerResetRackRequest) GetOverrideReadinessCheck() bool { type BringUpRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks for bring-up + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks, NVLink domains, or components for bring-up Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // optional task description RuleId *UUID `protobuf:"bytes,3,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule // When true, allow the bring-up sequence (which may power-cycle hosts @@ -5559,7 +5576,7 @@ func (x *BringUpRackRequest) GetOverrideReadinessCheck() bool { type IngestRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks for ingestion + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks, NVLink domains, or components for ingestion Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries (e.g. by type, name) Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description RuleId *UUID `protobuf:"bytes,4,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule @@ -7466,7 +7483,7 @@ func (*ScheduledOperation_Ingest) isScheduledOperation_Operation() {} // CreateTaskScheduleRequest creates a new TaskSchedule. // The target_spec on the operation message defines the initial scope; it follows -// the same targeting rules as AddTaskScheduleScope (rack-level or component-level). +// the same targeting rules as AddTaskScheduleScope. // Use AddTaskScheduleScope / RemoveTaskScheduleScope to modify the scope after creation. type CreateTaskScheduleRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -8069,8 +8086,9 @@ func (*TaskScheduleScope_Types) isTaskScheduleScope_ComponentFilter() {} func (*TaskScheduleScope_Components) isTaskScheduleScope_ComponentFilter() {} // AddTaskScheduleScopeRequest adds one or more scope entries to a schedule. -// Supports rack-level targeting (with optional component-type filter) and -// component-level targeting (specific components by UUID or external reference). +// Supports rack or NVLink domain targeting (with an optional component-type +// filter) and component targeting (specific components by UUID or external reference). +// NVLink domain membership is resolved to rack scopes when this request is handled. // For component-level targets the server resolves which rack each component // belongs to and groups them into per-rack scope entries automatically. // Racks already present in the scope have their component filter merged with the @@ -8223,7 +8241,7 @@ func (x *RemoveTaskScheduleScopeRequest) GetScopeId() *UUID { // desired target_spec: racks present in desired_scope but not in the current scope // are added; racks present in the current scope but absent from desired_scope are // removed; racks present in both have their component_filter updated if changed. -// For component-level targets the server resolves rack membership automatically. +// For NVLink domain and component targets the server resolves rack membership automatically. type UpdateTaskScheduleScopeRequest struct { state protoimpl.MessageState `protogen:"open.v1"` ScheduleId *UUID `protobuf:"bytes,1,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` @@ -11219,6 +11237,144 @@ func (x *OperationRunTarget) GetUpdatedAt() *timestamppb.Timestamp { return nil } +// NVLDomainTargets contains one or more NVLink domain targets. +type NVLDomainTargets struct { + state protoimpl.MessageState `protogen:"open.v1"` + Targets []*NVLDomainTarget `protobuf:"bytes,1,rep,name=targets,proto3" json:"targets,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NVLDomainTargets) Reset() { + *x = NVLDomainTargets{} + mi := &file_flow_proto_msgTypes[164] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NVLDomainTargets) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NVLDomainTargets) ProtoMessage() {} + +func (x *NVLDomainTargets) ProtoReflect() protoreflect.Message { + mi := &file_flow_proto_msgTypes[164] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NVLDomainTargets.ProtoReflect.Descriptor instead. +func (*NVLDomainTargets) Descriptor() ([]byte, []int) { + return file_flow_proto_rawDescGZIP(), []int{164} +} + +func (x *NVLDomainTargets) GetTargets() []*NVLDomainTarget { + if x != nil { + return x.Targets + } + return nil +} + +// NVLDomainTarget identifies an NVLink domain and optionally filters the +// components selected from every rack currently belonging to that domain. +type NVLDomainTarget struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: + // + // *NVLDomainTarget_Id + // *NVLDomainTarget_Name + Identifier isNVLDomainTarget_Identifier `protobuf_oneof:"identifier"` + // Optional: filter by component type. Omit (or send an empty list) to include all component types in the domain. + ComponentTypes []ComponentType `protobuf:"varint,3,rep,packed,name=component_types,json=componentTypes,proto3,enum=v1.ComponentType" json:"component_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NVLDomainTarget) Reset() { + *x = NVLDomainTarget{} + mi := &file_flow_proto_msgTypes[165] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NVLDomainTarget) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NVLDomainTarget) ProtoMessage() {} + +func (x *NVLDomainTarget) ProtoReflect() protoreflect.Message { + mi := &file_flow_proto_msgTypes[165] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NVLDomainTarget.ProtoReflect.Descriptor instead. +func (*NVLDomainTarget) Descriptor() ([]byte, []int) { + return file_flow_proto_rawDescGZIP(), []int{165} +} + +func (x *NVLDomainTarget) GetIdentifier() isNVLDomainTarget_Identifier { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *NVLDomainTarget) GetId() *UUID { + if x != nil { + if x, ok := x.Identifier.(*NVLDomainTarget_Id); ok { + return x.Id + } + } + return nil +} + +func (x *NVLDomainTarget) GetName() string { + if x != nil { + if x, ok := x.Identifier.(*NVLDomainTarget_Name); ok { + return x.Name + } + } + return "" +} + +func (x *NVLDomainTarget) GetComponentTypes() []ComponentType { + if x != nil { + return x.ComponentTypes + } + return nil +} + +type isNVLDomainTarget_Identifier interface { + isNVLDomainTarget_Identifier() +} + +type NVLDomainTarget_Id struct { + Id *UUID `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // NVLink domain UUID +} + +type NVLDomainTarget_Name struct { + Name string `protobuf:"bytes,2,opt,name=name,proto3,oneof"` // NVLink domain name +} + +func (*NVLDomainTarget_Id) isNVLDomainTarget_Identifier() {} + +func (*NVLDomainTarget_Name) isNVLDomainTarget_Identifier() {} + var File_flow_proto protoreflect.FileDescriptor const file_flow_proto_rawDesc = "" + @@ -11285,12 +11441,14 @@ const file_flow_proto_rawDesc = "" + "\n" + "Identifier\x12\x18\n" + "\x02id\x18\x01 \x01(\v2\b.v1.UUIDR\x02id\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\x81\x01\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xba\x01\n" + "\x13OperationTargetSpec\x12'\n" + "\x05racks\x18\x01 \x01(\v2\x0f.v1.RackTargetsH\x00R\x05racks\x126\n" + "\n" + "components\x18\x02 \x01(\v2\x14.v1.ComponentTargetsH\x00R\n" + - "componentsB\t\n" + + "components\x127\n" + + "\vnvl_domains\x18\x03 \x01(\v2\x14.v1.NVLDomainTargetsH\x00R\n" + + "nvlDomainsB\t\n" + "\atargets\"7\n" + "\vRackTargets\x12(\n" + "\atargets\x18\x01 \x03(\v2\x0e.v1.RackTargetR\atargets\"A\n" + @@ -12016,7 +12174,15 @@ const file_flow_proto_rawDesc = "" + "created_at\x18\n" + " \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + "\n" + - "updated_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt*D\n" + + "updated_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"A\n" + + "\x10NVLDomainTargets\x12-\n" + + "\atargets\x18\x01 \x03(\v2\x13.v1.NVLDomainTargetR\atargets\"\x8d\x01\n" + + "\x0fNVLDomainTarget\x12\x1a\n" + + "\x02id\x18\x01 \x01(\v2\b.v1.UUIDH\x00R\x02id\x12\x14\n" + + "\x04name\x18\x02 \x01(\tH\x00R\x04name\x12:\n" + + "\x0fcomponent_types\x18\x03 \x03(\x0e2\x11.v1.ComponentTypeR\x0ecomponentTypesB\f\n" + + "\n" + + "identifier*D\n" + "\aBMCType\x12\x14\n" + "\x10BMC_TYPE_UNKNOWN\x10\x00\x12\x11\n" + "\rBMC_TYPE_HOST\x10\x01\x12\x10\n" + @@ -12222,7 +12388,7 @@ func file_flow_proto_rawDescGZIP() []byte { } var file_flow_proto_enumTypes = make([]protoimpl.EnumInfo, 22) -var file_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 164) +var file_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 166) var file_flow_proto_goTypes = []any{ (BMCType)(0), // 0: v1.BMCType (ComponentType)(0), // 1: v1.ComponentType @@ -12410,10 +12576,12 @@ var file_flow_proto_goTypes = []any{ (*OperationRunPhaseStats)(nil), // 183: v1.OperationRunPhaseStats (*OperationRunTargetOutcomeCounts)(nil), // 184: v1.OperationRunTargetOutcomeCounts (*OperationRunTarget)(nil), // 185: v1.OperationRunTarget - (*timestamppb.Timestamp)(nil), // 186: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 187: google.protobuf.FieldMask - (*durationpb.Duration)(nil), // 188: google.protobuf.Duration - (*emptypb.Empty)(nil), // 189: google.protobuf.Empty + (*NVLDomainTargets)(nil), // 186: v1.NVLDomainTargets + (*NVLDomainTarget)(nil), // 187: v1.NVLDomainTarget + (*timestamppb.Timestamp)(nil), // 188: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 189: google.protobuf.FieldMask + (*durationpb.Duration)(nil), // 190: google.protobuf.Duration + (*emptypb.Empty)(nil), // 191: google.protobuf.Empty } var file_flow_proto_depIdxs = []int32{ 22, // 0: v1.DeviceInfo.id:type_name -> v1.UUID @@ -12433,396 +12601,400 @@ var file_flow_proto_depIdxs = []int32{ 22, // 14: v1.Identifier.id:type_name -> v1.UUID 33, // 15: v1.OperationTargetSpec.racks:type_name -> v1.RackTargets 34, // 16: v1.OperationTargetSpec.components:type_name -> v1.ComponentTargets - 39, // 17: v1.RackTargets.targets:type_name -> v1.RackTarget - 40, // 18: v1.ComponentTargets.targets:type_name -> v1.ComponentTarget - 1, // 19: v1.ComponentTypes.types:type_name -> v1.ComponentType - 35, // 20: v1.ComponentFilter.types:type_name -> v1.ComponentTypes - 34, // 21: v1.ComponentFilter.components:type_name -> v1.ComponentTargets - 38, // 22: v1.ComponentsByType.groups:type_name -> v1.ComponentsForType - 1, // 23: v1.ComponentsForType.type:type_name -> v1.ComponentType - 22, // 24: v1.ComponentsForType.component_ids:type_name -> v1.UUID - 22, // 25: v1.RackTarget.id:type_name -> v1.UUID - 1, // 26: v1.RackTarget.component_types:type_name -> v1.ComponentType - 22, // 27: v1.ComponentTarget.id:type_name -> v1.UUID - 41, // 28: v1.ComponentTarget.external:type_name -> v1.ExternalRef - 1, // 29: v1.ExternalRef.type:type_name -> v1.ComponentType - 31, // 30: v1.NVLDomain.identifier:type_name -> v1.Identifier - 2, // 31: v1.Filter.rack_field:type_name -> v1.RackFilterField - 3, // 32: v1.Filter.component_field:type_name -> v1.ComponentFilterField - 44, // 33: v1.Filter.query_info:type_name -> v1.StringQueryInfo - 5, // 34: v1.OrderBy.rack_field:type_name -> v1.RackOrderByField - 4, // 35: v1.OrderBy.component_field:type_name -> v1.ComponentOrderByField - 22, // 36: v1.Task.id:type_name -> v1.UUID - 22, // 37: v1.Task.rack_id:type_name -> v1.UUID - 22, // 38: v1.Task.component_uuids:type_name -> v1.UUID - 8, // 39: v1.Task.executor_type:type_name -> v1.TaskExecutorType - 7, // 40: v1.Task.status:type_name -> v1.TaskStatus - 186, // 41: v1.Task.queue_expires_at:type_name -> google.protobuf.Timestamp - 186, // 42: v1.Task.created_at:type_name -> google.protobuf.Timestamp - 186, // 43: v1.Task.finished_at:type_name -> google.protobuf.Timestamp - 22, // 44: v1.Task.applied_rule_id:type_name -> v1.UUID - 186, // 45: v1.Task.updated_at:type_name -> google.protobuf.Timestamp - 186, // 46: v1.Task.started_at:type_name -> google.protobuf.Timestamp - 30, // 47: v1.CreateExpectedRackRequest.rack:type_name -> v1.Rack - 22, // 48: v1.CreateExpectedRackResponse.id:type_name -> v1.UUID - 22, // 49: v1.GetRackInfoByIDRequest.id:type_name -> v1.UUID - 25, // 50: v1.GetRackInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo - 30, // 51: v1.GetRackInfoResponse.rack:type_name -> v1.Rack - 30, // 52: v1.PatchRackRequest.rack:type_name -> v1.Rack - 22, // 53: v1.GetComponentInfoByIDRequest.id:type_name -> v1.UUID - 25, // 54: v1.GetComponentInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo - 29, // 55: v1.GetComponentInfoResponse.component:type_name -> v1.Component - 30, // 56: v1.GetComponentInfoResponse.rack:type_name -> v1.Rack - 45, // 57: v1.GetListOfRacksRequest.filters:type_name -> v1.Filter - 43, // 58: v1.GetListOfRacksRequest.pagination:type_name -> v1.Pagination - 46, // 59: v1.GetListOfRacksRequest.order_by:type_name -> v1.OrderBy - 30, // 60: v1.GetListOfRacksResponse.racks:type_name -> v1.Rack - 42, // 61: v1.CreateNVLDomainRequest.nvl_domain:type_name -> v1.NVLDomain - 22, // 62: v1.CreateNVLDomainResponse.id:type_name -> v1.UUID - 31, // 63: v1.AttachRacksToNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier - 31, // 64: v1.AttachRacksToNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier - 31, // 65: v1.DetachRacksFromNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier - 44, // 66: v1.GetListOfNVLDomainsRequest.info:type_name -> v1.StringQueryInfo - 43, // 67: v1.GetListOfNVLDomainsRequest.pagination:type_name -> v1.Pagination - 42, // 68: v1.GetListOfNVLDomainsResponse.nvl_domains:type_name -> v1.NVLDomain - 31, // 69: v1.GetRacksForNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier - 30, // 70: v1.GetRacksForNVLDomainResponse.racks:type_name -> v1.Rack - 32, // 71: v1.UpgradeFirmwareRequest.target_spec:type_name -> v1.OperationTargetSpec - 186, // 72: v1.UpgradeFirmwareRequest.start_time:type_name -> google.protobuf.Timestamp - 186, // 73: v1.UpgradeFirmwareRequest.end_time:type_name -> google.protobuf.Timestamp - 88, // 74: v1.UpgradeFirmwareRequest.queue_options:type_name -> v1.QueueOptions - 22, // 75: v1.UpgradeFirmwareRequest.rule_id:type_name -> v1.UUID - 32, // 76: v1.GetComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 77: v1.GetComponentsRequest.filters:type_name -> v1.Filter - 43, // 78: v1.GetComponentsRequest.pagination:type_name -> v1.Pagination - 46, // 79: v1.GetComponentsRequest.order_by:type_name -> v1.OrderBy - 29, // 80: v1.GetComponentsResponse.components:type_name -> v1.Component - 32, // 81: v1.ValidateComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 82: v1.ValidateComponentsRequest.filters:type_name -> v1.Filter - 43, // 83: v1.ValidateComponentsRequest.pagination:type_name -> v1.Pagination - 46, // 84: v1.ValidateComponentsRequest.order_by:type_name -> v1.OrderBy - 73, // 85: v1.ValidateComponentsResponse.diffs:type_name -> v1.ComponentDiff - 11, // 86: v1.ComponentDiff.type:type_name -> v1.DiffType - 29, // 87: v1.ComponentDiff.expected:type_name -> v1.Component - 29, // 88: v1.ComponentDiff.actual:type_name -> v1.Component - 74, // 89: v1.ComponentDiff.field_diffs:type_name -> v1.FieldDiff - 22, // 90: v1.ComponentDiff.id:type_name -> v1.UUID - 29, // 91: v1.AddComponentRequest.component:type_name -> v1.Component - 29, // 92: v1.AddComponentResponse.component:type_name -> v1.Component - 22, // 93: v1.DeleteComponentRequest.id:type_name -> v1.UUID - 22, // 94: v1.DeleteRackRequest.id:type_name -> v1.UUID - 22, // 95: v1.PurgeRackRequest.id:type_name -> v1.UUID - 22, // 96: v1.PurgeComponentRequest.id:type_name -> v1.UUID - 22, // 97: v1.PatchComponentRequest.id:type_name -> v1.UUID - 27, // 98: v1.PatchComponentRequest.position:type_name -> v1.RackPosition - 22, // 99: v1.PatchComponentRequest.rack_id:type_name -> v1.UUID - 26, // 100: v1.PatchComponentRequest.bmcs:type_name -> v1.BMCInfo - 29, // 101: v1.PatchComponentResponse.component:type_name -> v1.Component - 22, // 102: v1.SubmitTaskResponse.task_ids:type_name -> v1.UUID - 12, // 103: v1.QueueOptions.conflict_strategy:type_name -> v1.ConflictStrategy - 32, // 104: v1.PowerOnRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 105: v1.PowerOnRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 106: v1.PowerOnRackRequest.rule_id:type_name -> v1.UUID - 32, // 107: v1.PowerOffRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 108: v1.PowerOffRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 109: v1.PowerOffRackRequest.rule_id:type_name -> v1.UUID - 32, // 110: v1.PowerResetRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 111: v1.PowerResetRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 112: v1.PowerResetRackRequest.rule_id:type_name -> v1.UUID - 32, // 113: v1.BringUpRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 22, // 114: v1.BringUpRackRequest.rule_id:type_name -> v1.UUID - 32, // 115: v1.IngestRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 116: v1.IngestRackRequest.filters:type_name -> v1.Filter - 22, // 117: v1.IngestRackRequest.rule_id:type_name -> v1.UUID - 32, // 118: v1.DecommissionRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 119: v1.DecommissionRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 120: v1.DecommissionRackRequest.rule_id:type_name -> v1.UUID - 22, // 121: v1.ListTasksRequest.rack_id:type_name -> v1.UUID - 43, // 122: v1.ListTasksRequest.pagination:type_name -> v1.Pagination - 22, // 123: v1.ListTasksRequest.component_id:type_name -> v1.UUID - 47, // 124: v1.ListTasksResponse.tasks:type_name -> v1.Task - 22, // 125: v1.GetTasksByIDsRequest.task_ids:type_name -> v1.UUID - 47, // 126: v1.GetTasksByIDsResponse.tasks:type_name -> v1.Task - 22, // 127: v1.CancelTaskRequest.task_id:type_name -> v1.UUID - 47, // 128: v1.CancelTaskResponse.task:type_name -> v1.Task - 22, // 129: v1.OperationRule.id:type_name -> v1.UUID - 13, // 130: v1.OperationRule.operation_type:type_name -> v1.OperationType - 186, // 131: v1.OperationRule.created_at:type_name -> google.protobuf.Timestamp - 186, // 132: v1.OperationRule.updated_at:type_name -> google.protobuf.Timestamp - 13, // 133: v1.CreateOperationRuleRequest.operation_type:type_name -> v1.OperationType - 22, // 134: v1.CreateOperationRuleResponse.id:type_name -> v1.UUID - 22, // 135: v1.UpdateOperationRuleRequest.rule_id:type_name -> v1.UUID - 22, // 136: v1.DeleteOperationRuleRequest.rule_id:type_name -> v1.UUID - 22, // 137: v1.SetRuleAsDefaultRequest.rule_id:type_name -> v1.UUID - 22, // 138: v1.GetOperationRuleRequest.rule_id:type_name -> v1.UUID - 13, // 139: v1.ListOperationRulesRequest.operation_type:type_name -> v1.OperationType - 103, // 140: v1.ListOperationRulesResponse.rules:type_name -> v1.OperationRule - 22, // 141: v1.AssociateRuleWithRackRequest.rack_id:type_name -> v1.UUID - 22, // 142: v1.AssociateRuleWithRackRequest.rule_id:type_name -> v1.UUID - 22, // 143: v1.DisassociateRuleFromRackRequest.rack_id:type_name -> v1.UUID - 13, // 144: v1.DisassociateRuleFromRackRequest.operation_type:type_name -> v1.OperationType - 22, // 145: v1.GetRackRuleAssociationRequest.rack_id:type_name -> v1.UUID - 13, // 146: v1.GetRackRuleAssociationRequest.operation_type:type_name -> v1.OperationType - 22, // 147: v1.GetRackRuleAssociationResponse.rule_id:type_name -> v1.UUID - 22, // 148: v1.ListRackRuleAssociationsRequest.rack_id:type_name -> v1.UUID - 22, // 149: v1.RackRuleAssociation.rack_id:type_name -> v1.UUID - 13, // 150: v1.RackRuleAssociation.operation_type:type_name -> v1.OperationType - 22, // 151: v1.RackRuleAssociation.rule_id:type_name -> v1.UUID - 186, // 152: v1.RackRuleAssociation.created_at:type_name -> google.protobuf.Timestamp - 186, // 153: v1.RackRuleAssociation.updated_at:type_name -> google.protobuf.Timestamp - 117, // 154: v1.ListRackRuleAssociationsResponse.associations:type_name -> v1.RackRuleAssociation - 14, // 155: v1.ScheduleSpec.type:type_name -> v1.ScheduleSpecType - 119, // 156: v1.ScheduleConfig.spec:type_name -> v1.ScheduleSpec - 15, // 157: v1.ScheduleConfig.overlap_policy:type_name -> v1.OverlapPolicy - 22, // 158: v1.TaskSchedule.id:type_name -> v1.UUID - 119, // 159: v1.TaskSchedule.spec:type_name -> v1.ScheduleSpec - 15, // 160: v1.TaskSchedule.overlap_policy:type_name -> v1.OverlapPolicy - 186, // 161: v1.TaskSchedule.next_run_at:type_name -> google.protobuf.Timestamp - 186, // 162: v1.TaskSchedule.last_run_at:type_name -> google.protobuf.Timestamp - 186, // 163: v1.TaskSchedule.created_at:type_name -> google.protobuf.Timestamp - 186, // 164: v1.TaskSchedule.updated_at:type_name -> google.protobuf.Timestamp - 89, // 165: v1.ScheduledOperation.power_on:type_name -> v1.PowerOnRackRequest - 90, // 166: v1.ScheduledOperation.power_off:type_name -> v1.PowerOffRackRequest - 91, // 167: v1.ScheduledOperation.power_reset:type_name -> v1.PowerResetRackRequest - 92, // 168: v1.ScheduledOperation.bring_up:type_name -> v1.BringUpRackRequest - 68, // 169: v1.ScheduledOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest - 93, // 170: v1.ScheduledOperation.ingest:type_name -> v1.IngestRackRequest - 120, // 171: v1.CreateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig - 122, // 172: v1.CreateTaskScheduleRequest.operation:type_name -> v1.ScheduledOperation - 22, // 173: v1.GetTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 174: v1.ListTaskSchedulesRequest.rack_id:type_name -> v1.UUID - 43, // 175: v1.ListTaskSchedulesRequest.pagination:type_name -> v1.Pagination - 121, // 176: v1.ListTaskSchedulesResponse.task_schedules:type_name -> v1.TaskSchedule - 22, // 177: v1.UpdateTaskScheduleRequest.id:type_name -> v1.UUID - 120, // 178: v1.UpdateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig - 187, // 179: v1.UpdateTaskScheduleRequest.update_mask:type_name -> google.protobuf.FieldMask - 22, // 180: v1.PauseTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 181: v1.ResumeTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 182: v1.DeleteTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 183: v1.TriggerTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 184: v1.TaskScheduleScope.id:type_name -> v1.UUID - 22, // 185: v1.TaskScheduleScope.schedule_id:type_name -> v1.UUID - 22, // 186: v1.TaskScheduleScope.rack_id:type_name -> v1.UUID - 35, // 187: v1.TaskScheduleScope.types:type_name -> v1.ComponentTypes - 34, // 188: v1.TaskScheduleScope.components:type_name -> v1.ComponentTargets - 22, // 189: v1.TaskScheduleScope.last_task_id:type_name -> v1.UUID - 186, // 190: v1.TaskScheduleScope.created_at:type_name -> google.protobuf.Timestamp - 22, // 191: v1.AddTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID - 32, // 192: v1.AddTaskScheduleScopeRequest.target_spec:type_name -> v1.OperationTargetSpec - 132, // 193: v1.AddTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope - 22, // 194: v1.RemoveTaskScheduleScopeRequest.scope_id:type_name -> v1.UUID - 22, // 195: v1.UpdateTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID - 32, // 196: v1.UpdateTaskScheduleScopeRequest.desired_scope:type_name -> v1.OperationTargetSpec - 132, // 197: v1.UpdateTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope - 22, // 198: v1.ListTaskScheduleScopesRequest.schedule_id:type_name -> v1.UUID - 132, // 199: v1.ListTaskScheduleScopesResponse.scopes:type_name -> v1.TaskScheduleScope - 122, // 200: v1.CheckScheduleConflictsRequest.operation:type_name -> v1.ScheduledOperation - 22, // 201: v1.CheckScheduleConflictsRequest.exclude_schedule_id:type_name -> v1.UUID - 121, // 202: v1.CheckScheduleConflictsResponse.conflicts:type_name -> v1.TaskSchedule - 144, // 203: v1.CreateOperationRunRequest.configuration:type_name -> v1.OperationRunConfiguration - 22, // 204: v1.CreateOperationRunResponse.id:type_name -> v1.UUID - 157, // 205: v1.OperationRunConfiguration.selector:type_name -> v1.OperationRunSelector - 159, // 206: v1.OperationRunConfiguration.options:type_name -> v1.OperationRunOptions - 177, // 207: v1.OperationRunConfiguration.operation:type_name -> v1.OperationRunOperation - 22, // 208: v1.GetOperationRunRequest.id:type_name -> v1.UUID - 180, // 209: v1.GetOperationRunResponse.operation_run:type_name -> v1.OperationRun - 149, // 210: v1.ListOperationRunsRequest.filter:type_name -> v1.OperationRunFilter - 43, // 211: v1.ListOperationRunsRequest.pagination:type_name -> v1.Pagination - 181, // 212: v1.ListOperationRunsResponse.operation_runs:type_name -> v1.OperationRunSummary - 44, // 213: v1.OperationRunFilter.name:type_name -> v1.StringQueryInfo - 150, // 214: v1.OperationRunFilter.states:type_name -> v1.OperationRunStateFilter - 179, // 215: v1.OperationRunFilter.operation_kinds:type_name -> v1.OperationKind - 18, // 216: v1.OperationRunStateFilter.status:type_name -> v1.OperationRunStatus - 19, // 217: v1.OperationRunStateFilter.reason:type_name -> v1.OperationRunStatusReason - 22, // 218: v1.ListOperationRunTargetsRequest.operation_run_id:type_name -> v1.UUID - 20, // 219: v1.ListOperationRunTargetsRequest.status:type_name -> v1.OperationRunTargetStatus - 43, // 220: v1.ListOperationRunTargetsRequest.pagination:type_name -> v1.Pagination - 16, // 221: v1.ListOperationRunTargetsRequest.phase_scope:type_name -> v1.OperationRunTargetPhaseScope - 185, // 222: v1.ListOperationRunTargetsResponse.targets:type_name -> v1.OperationRunTarget - 22, // 223: v1.PauseOperationRunRequest.id:type_name -> v1.UUID - 22, // 224: v1.ResumeOperationRunRequest.id:type_name -> v1.UUID - 22, // 225: v1.AdvanceOperationRunPhaseRequest.id:type_name -> v1.UUID - 22, // 226: v1.CancelOperationRunRequest.id:type_name -> v1.UUID - 158, // 227: v1.OperationRunSelector.percentage:type_name -> v1.PercentageSelector - 160, // 228: v1.OperationRunOptions.safety_policy:type_name -> v1.OperationRunSafetyPolicy - 174, // 229: v1.OperationRunOptions.conflict_policy:type_name -> v1.OperationRunConflictPolicy - 164, // 230: v1.OperationRunOptions.ordering_policy:type_name -> v1.OperationRunOrderingPolicy - 167, // 231: v1.OperationRunOptions.phase_policy:type_name -> v1.OperationRunPhasePolicy - 161, // 232: v1.OperationRunSafetyPolicy.gates:type_name -> v1.OperationRunSafetyGate - 162, // 233: v1.OperationRunSafetyGate.failure_rate:type_name -> v1.OperationRunFailureRateGate - 163, // 234: v1.OperationRunSafetyGate.failure_count:type_name -> v1.OperationRunFailureCountGate - 17, // 235: v1.OperationRunFailureRateGate.scope:type_name -> v1.OperationRunSafetyGateScope - 17, // 236: v1.OperationRunFailureCountGate.scope:type_name -> v1.OperationRunSafetyGateScope - 165, // 237: v1.OperationRunOrderingPolicy.random:type_name -> v1.OperationRunRandomOrdering - 166, // 238: v1.OperationRunOrderingPolicy.physical_location:type_name -> v1.OperationRunPhysicalLocationOrdering - 21, // 239: v1.OperationRunPhysicalLocationOrdering.strategy:type_name -> v1.OperationRunPhysicalLocationOrdering.Strategy - 168, // 240: v1.OperationRunPhasePolicy.equal:type_name -> v1.EqualOperationRunPhases - 169, // 241: v1.OperationRunPhasePolicy.percentage:type_name -> v1.PercentageOperationRunPhases - 171, // 242: v1.OperationRunPhasePolicy.count:type_name -> v1.CountOperationRunPhases - 173, // 243: v1.OperationRunPhasePolicy.advance_policy:type_name -> v1.OperationRunPhaseAdvancePolicy - 170, // 244: v1.PercentageOperationRunPhases.phases:type_name -> v1.OperationRunPercentagePhase - 172, // 245: v1.CountOperationRunPhases.phases:type_name -> v1.OperationRunCountPhase - 175, // 246: v1.OperationRunConflictPolicy.retry:type_name -> v1.OperationRunConflictRetryPolicy - 188, // 247: v1.OperationRunConflictRetryPolicy.retry_timeout:type_name -> google.protobuf.Duration - 188, // 248: v1.OperationRunConflictRetryPolicy.initial_retry_delay:type_name -> google.protobuf.Duration - 188, // 249: v1.OperationRunConflictRetryPolicy.max_retry_delay:type_name -> google.protobuf.Duration - 22, // 250: v1.OperationRunTargetScope.exclude_operation_run_ids:type_name -> v1.UUID - 36, // 251: v1.OperationRunTargetScope.default_scope_component_filter:type_name -> v1.ComponentFilter - 68, // 252: v1.OperationRunOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest - 176, // 253: v1.OperationRunOperation.target_scope:type_name -> v1.OperationRunTargetScope - 18, // 254: v1.OperationRunState.status:type_name -> v1.OperationRunStatus - 19, // 255: v1.OperationRunState.reason:type_name -> v1.OperationRunStatusReason - 13, // 256: v1.OperationKind.type:type_name -> v1.OperationType - 181, // 257: v1.OperationRun.summary:type_name -> v1.OperationRunSummary - 144, // 258: v1.OperationRun.configuration:type_name -> v1.OperationRunConfiguration - 182, // 259: v1.OperationRun.stats:type_name -> v1.OperationRunStats - 22, // 260: v1.OperationRunSummary.id:type_name -> v1.UUID - 179, // 261: v1.OperationRunSummary.operation_kind:type_name -> v1.OperationKind - 178, // 262: v1.OperationRunSummary.state:type_name -> v1.OperationRunState - 186, // 263: v1.OperationRunSummary.created_at:type_name -> google.protobuf.Timestamp - 186, // 264: v1.OperationRunSummary.updated_at:type_name -> google.protobuf.Timestamp - 186, // 265: v1.OperationRunSummary.started_at:type_name -> google.protobuf.Timestamp - 186, // 266: v1.OperationRunSummary.finished_at:type_name -> google.protobuf.Timestamp - 183, // 267: v1.OperationRunStats.current_phase_stats:type_name -> v1.OperationRunPhaseStats - 183, // 268: v1.OperationRunStats.cumulative_phase_stats:type_name -> v1.OperationRunPhaseStats - 184, // 269: v1.OperationRunPhaseStats.outcome_counts:type_name -> v1.OperationRunTargetOutcomeCounts - 22, // 270: v1.OperationRunTarget.id:type_name -> v1.UUID - 22, // 271: v1.OperationRunTarget.operation_run_id:type_name -> v1.UUID - 22, // 272: v1.OperationRunTarget.rack_id:type_name -> v1.UUID - 22, // 273: v1.OperationRunTarget.task_id:type_name -> v1.UUID - 20, // 274: v1.OperationRunTarget.status:type_name -> v1.OperationRunTargetStatus - 37, // 275: v1.OperationRunTarget.components_by_type:type_name -> v1.ComponentsByType - 186, // 276: v1.OperationRunTarget.created_at:type_name -> google.protobuf.Timestamp - 186, // 277: v1.OperationRunTarget.updated_at:type_name -> google.protobuf.Timestamp - 101, // 278: v1.Flow.Version:input_type -> v1.VersionRequest - 123, // 279: v1.Flow.CreateTaskSchedule:input_type -> v1.CreateTaskScheduleRequest - 124, // 280: v1.Flow.GetTaskSchedule:input_type -> v1.GetTaskScheduleRequest - 125, // 281: v1.Flow.ListTaskSchedules:input_type -> v1.ListTaskSchedulesRequest - 127, // 282: v1.Flow.UpdateTaskSchedule:input_type -> v1.UpdateTaskScheduleRequest - 128, // 283: v1.Flow.PauseTaskSchedule:input_type -> v1.PauseTaskScheduleRequest - 129, // 284: v1.Flow.ResumeTaskSchedule:input_type -> v1.ResumeTaskScheduleRequest - 130, // 285: v1.Flow.DeleteTaskSchedule:input_type -> v1.DeleteTaskScheduleRequest - 131, // 286: v1.Flow.TriggerTaskSchedule:input_type -> v1.TriggerTaskScheduleRequest - 133, // 287: v1.Flow.AddTaskScheduleScope:input_type -> v1.AddTaskScheduleScopeRequest - 135, // 288: v1.Flow.RemoveTaskScheduleScope:input_type -> v1.RemoveTaskScheduleScopeRequest - 136, // 289: v1.Flow.UpdateTaskScheduleScope:input_type -> v1.UpdateTaskScheduleScopeRequest - 138, // 290: v1.Flow.ListTaskScheduleScopes:input_type -> v1.ListTaskScheduleScopesRequest - 140, // 291: v1.Flow.CheckScheduleConflicts:input_type -> v1.CheckScheduleConflictsRequest - 48, // 292: v1.Flow.CreateExpectedRack:input_type -> v1.CreateExpectedRackRequest - 50, // 293: v1.Flow.GetRackInfoByID:input_type -> v1.GetRackInfoByIDRequest - 51, // 294: v1.Flow.GetRackInfoBySerial:input_type -> v1.GetRackInfoBySerialRequest - 58, // 295: v1.Flow.GetListOfRacks:input_type -> v1.GetListOfRacksRequest - 53, // 296: v1.Flow.PatchRack:input_type -> v1.PatchRackRequest - 79, // 297: v1.Flow.DeleteRack:input_type -> v1.DeleteRackRequest - 81, // 298: v1.Flow.PurgeRack:input_type -> v1.PurgeRackRequest - 68, // 299: v1.Flow.UpgradeFirmware:input_type -> v1.UpgradeFirmwareRequest - 92, // 300: v1.Flow.BringUpRack:input_type -> v1.BringUpRackRequest - 93, // 301: v1.Flow.IngestRack:input_type -> v1.IngestRackRequest - 94, // 302: v1.Flow.DecommissionRack:input_type -> v1.DecommissionRackRequest - 89, // 303: v1.Flow.PowerOnRack:input_type -> v1.PowerOnRackRequest - 90, // 304: v1.Flow.PowerOffRack:input_type -> v1.PowerOffRackRequest - 91, // 305: v1.Flow.PowerResetRack:input_type -> v1.PowerResetRackRequest - 55, // 306: v1.Flow.GetComponentInfoByID:input_type -> v1.GetComponentInfoByIDRequest - 56, // 307: v1.Flow.GetComponentInfoBySerial:input_type -> v1.GetComponentInfoBySerialRequest - 69, // 308: v1.Flow.GetComponents:input_type -> v1.GetComponentsRequest - 71, // 309: v1.Flow.ValidateComponents:input_type -> v1.ValidateComponentsRequest - 75, // 310: v1.Flow.AddComponent:input_type -> v1.AddComponentRequest - 85, // 311: v1.Flow.PatchComponent:input_type -> v1.PatchComponentRequest - 77, // 312: v1.Flow.DeleteComponent:input_type -> v1.DeleteComponentRequest - 83, // 313: v1.Flow.PurgeComponent:input_type -> v1.PurgeComponentRequest - 60, // 314: v1.Flow.CreateNVLDomain:input_type -> v1.CreateNVLDomainRequest - 62, // 315: v1.Flow.AttachRacksToNVLDomain:input_type -> v1.AttachRacksToNVLDomainRequest - 63, // 316: v1.Flow.DetachRacksFromNVLDomain:input_type -> v1.DetachRacksFromNVLDomainRequest - 64, // 317: v1.Flow.GetListOfNVLDomains:input_type -> v1.GetListOfNVLDomainsRequest - 66, // 318: v1.Flow.GetRacksForNVLDomain:input_type -> v1.GetRacksForNVLDomainRequest - 95, // 319: v1.Flow.ListTasks:input_type -> v1.ListTasksRequest - 97, // 320: v1.Flow.GetTasksByIDs:input_type -> v1.GetTasksByIDsRequest - 99, // 321: v1.Flow.CancelTask:input_type -> v1.CancelTaskRequest - 104, // 322: v1.Flow.CreateOperationRule:input_type -> v1.CreateOperationRuleRequest - 106, // 323: v1.Flow.UpdateOperationRule:input_type -> v1.UpdateOperationRuleRequest - 107, // 324: v1.Flow.DeleteOperationRule:input_type -> v1.DeleteOperationRuleRequest - 109, // 325: v1.Flow.GetOperationRule:input_type -> v1.GetOperationRuleRequest - 110, // 326: v1.Flow.ListOperationRules:input_type -> v1.ListOperationRulesRequest - 108, // 327: v1.Flow.SetRuleAsDefault:input_type -> v1.SetRuleAsDefaultRequest - 112, // 328: v1.Flow.AssociateRuleWithRack:input_type -> v1.AssociateRuleWithRackRequest - 113, // 329: v1.Flow.DisassociateRuleFromRack:input_type -> v1.DisassociateRuleFromRackRequest - 114, // 330: v1.Flow.GetRackRuleAssociation:input_type -> v1.GetRackRuleAssociationRequest - 116, // 331: v1.Flow.ListRackRuleAssociations:input_type -> v1.ListRackRuleAssociationsRequest - 142, // 332: v1.Flow.CreateOperationRun:input_type -> v1.CreateOperationRunRequest - 145, // 333: v1.Flow.GetOperationRun:input_type -> v1.GetOperationRunRequest - 147, // 334: v1.Flow.ListOperationRuns:input_type -> v1.ListOperationRunsRequest - 151, // 335: v1.Flow.ListOperationRunTargets:input_type -> v1.ListOperationRunTargetsRequest - 153, // 336: v1.Flow.PauseOperationRun:input_type -> v1.PauseOperationRunRequest - 154, // 337: v1.Flow.ResumeOperationRun:input_type -> v1.ResumeOperationRunRequest - 155, // 338: v1.Flow.AdvanceOperationRunPhase:input_type -> v1.AdvanceOperationRunPhaseRequest - 156, // 339: v1.Flow.CancelOperationRun:input_type -> v1.CancelOperationRunRequest - 102, // 340: v1.Flow.Version:output_type -> v1.BuildInfo - 121, // 341: v1.Flow.CreateTaskSchedule:output_type -> v1.TaskSchedule - 121, // 342: v1.Flow.GetTaskSchedule:output_type -> v1.TaskSchedule - 126, // 343: v1.Flow.ListTaskSchedules:output_type -> v1.ListTaskSchedulesResponse - 121, // 344: v1.Flow.UpdateTaskSchedule:output_type -> v1.TaskSchedule - 121, // 345: v1.Flow.PauseTaskSchedule:output_type -> v1.TaskSchedule - 121, // 346: v1.Flow.ResumeTaskSchedule:output_type -> v1.TaskSchedule - 189, // 347: v1.Flow.DeleteTaskSchedule:output_type -> google.protobuf.Empty - 87, // 348: v1.Flow.TriggerTaskSchedule:output_type -> v1.SubmitTaskResponse - 134, // 349: v1.Flow.AddTaskScheduleScope:output_type -> v1.AddTaskScheduleScopeResponse - 189, // 350: v1.Flow.RemoveTaskScheduleScope:output_type -> google.protobuf.Empty - 137, // 351: v1.Flow.UpdateTaskScheduleScope:output_type -> v1.UpdateTaskScheduleScopeResponse - 139, // 352: v1.Flow.ListTaskScheduleScopes:output_type -> v1.ListTaskScheduleScopesResponse - 141, // 353: v1.Flow.CheckScheduleConflicts:output_type -> v1.CheckScheduleConflictsResponse - 49, // 354: v1.Flow.CreateExpectedRack:output_type -> v1.CreateExpectedRackResponse - 52, // 355: v1.Flow.GetRackInfoByID:output_type -> v1.GetRackInfoResponse - 52, // 356: v1.Flow.GetRackInfoBySerial:output_type -> v1.GetRackInfoResponse - 59, // 357: v1.Flow.GetListOfRacks:output_type -> v1.GetListOfRacksResponse - 54, // 358: v1.Flow.PatchRack:output_type -> v1.PatchRackResponse - 80, // 359: v1.Flow.DeleteRack:output_type -> v1.DeleteRackResponse - 82, // 360: v1.Flow.PurgeRack:output_type -> v1.PurgeRackResponse - 87, // 361: v1.Flow.UpgradeFirmware:output_type -> v1.SubmitTaskResponse - 87, // 362: v1.Flow.BringUpRack:output_type -> v1.SubmitTaskResponse - 87, // 363: v1.Flow.IngestRack:output_type -> v1.SubmitTaskResponse - 87, // 364: v1.Flow.DecommissionRack:output_type -> v1.SubmitTaskResponse - 87, // 365: v1.Flow.PowerOnRack:output_type -> v1.SubmitTaskResponse - 87, // 366: v1.Flow.PowerOffRack:output_type -> v1.SubmitTaskResponse - 87, // 367: v1.Flow.PowerResetRack:output_type -> v1.SubmitTaskResponse - 57, // 368: v1.Flow.GetComponentInfoByID:output_type -> v1.GetComponentInfoResponse - 57, // 369: v1.Flow.GetComponentInfoBySerial:output_type -> v1.GetComponentInfoResponse - 70, // 370: v1.Flow.GetComponents:output_type -> v1.GetComponentsResponse - 72, // 371: v1.Flow.ValidateComponents:output_type -> v1.ValidateComponentsResponse - 76, // 372: v1.Flow.AddComponent:output_type -> v1.AddComponentResponse - 86, // 373: v1.Flow.PatchComponent:output_type -> v1.PatchComponentResponse - 78, // 374: v1.Flow.DeleteComponent:output_type -> v1.DeleteComponentResponse - 84, // 375: v1.Flow.PurgeComponent:output_type -> v1.PurgeComponentResponse - 61, // 376: v1.Flow.CreateNVLDomain:output_type -> v1.CreateNVLDomainResponse - 189, // 377: v1.Flow.AttachRacksToNVLDomain:output_type -> google.protobuf.Empty - 189, // 378: v1.Flow.DetachRacksFromNVLDomain:output_type -> google.protobuf.Empty - 65, // 379: v1.Flow.GetListOfNVLDomains:output_type -> v1.GetListOfNVLDomainsResponse - 67, // 380: v1.Flow.GetRacksForNVLDomain:output_type -> v1.GetRacksForNVLDomainResponse - 96, // 381: v1.Flow.ListTasks:output_type -> v1.ListTasksResponse - 98, // 382: v1.Flow.GetTasksByIDs:output_type -> v1.GetTasksByIDsResponse - 100, // 383: v1.Flow.CancelTask:output_type -> v1.CancelTaskResponse - 105, // 384: v1.Flow.CreateOperationRule:output_type -> v1.CreateOperationRuleResponse - 189, // 385: v1.Flow.UpdateOperationRule:output_type -> google.protobuf.Empty - 189, // 386: v1.Flow.DeleteOperationRule:output_type -> google.protobuf.Empty - 103, // 387: v1.Flow.GetOperationRule:output_type -> v1.OperationRule - 111, // 388: v1.Flow.ListOperationRules:output_type -> v1.ListOperationRulesResponse - 189, // 389: v1.Flow.SetRuleAsDefault:output_type -> google.protobuf.Empty - 189, // 390: v1.Flow.AssociateRuleWithRack:output_type -> google.protobuf.Empty - 189, // 391: v1.Flow.DisassociateRuleFromRack:output_type -> google.protobuf.Empty - 115, // 392: v1.Flow.GetRackRuleAssociation:output_type -> v1.GetRackRuleAssociationResponse - 118, // 393: v1.Flow.ListRackRuleAssociations:output_type -> v1.ListRackRuleAssociationsResponse - 143, // 394: v1.Flow.CreateOperationRun:output_type -> v1.CreateOperationRunResponse - 146, // 395: v1.Flow.GetOperationRun:output_type -> v1.GetOperationRunResponse - 148, // 396: v1.Flow.ListOperationRuns:output_type -> v1.ListOperationRunsResponse - 152, // 397: v1.Flow.ListOperationRunTargets:output_type -> v1.ListOperationRunTargetsResponse - 180, // 398: v1.Flow.PauseOperationRun:output_type -> v1.OperationRun - 180, // 399: v1.Flow.ResumeOperationRun:output_type -> v1.OperationRun - 180, // 400: v1.Flow.AdvanceOperationRunPhase:output_type -> v1.OperationRun - 180, // 401: v1.Flow.CancelOperationRun:output_type -> v1.OperationRun - 340, // [340:402] is the sub-list for method output_type - 278, // [278:340] is the sub-list for method input_type - 278, // [278:278] is the sub-list for extension type_name - 278, // [278:278] is the sub-list for extension extendee - 0, // [0:278] is the sub-list for field type_name + 186, // 17: v1.OperationTargetSpec.nvl_domains:type_name -> v1.NVLDomainTargets + 39, // 18: v1.RackTargets.targets:type_name -> v1.RackTarget + 40, // 19: v1.ComponentTargets.targets:type_name -> v1.ComponentTarget + 1, // 20: v1.ComponentTypes.types:type_name -> v1.ComponentType + 35, // 21: v1.ComponentFilter.types:type_name -> v1.ComponentTypes + 34, // 22: v1.ComponentFilter.components:type_name -> v1.ComponentTargets + 38, // 23: v1.ComponentsByType.groups:type_name -> v1.ComponentsForType + 1, // 24: v1.ComponentsForType.type:type_name -> v1.ComponentType + 22, // 25: v1.ComponentsForType.component_ids:type_name -> v1.UUID + 22, // 26: v1.RackTarget.id:type_name -> v1.UUID + 1, // 27: v1.RackTarget.component_types:type_name -> v1.ComponentType + 22, // 28: v1.ComponentTarget.id:type_name -> v1.UUID + 41, // 29: v1.ComponentTarget.external:type_name -> v1.ExternalRef + 1, // 30: v1.ExternalRef.type:type_name -> v1.ComponentType + 31, // 31: v1.NVLDomain.identifier:type_name -> v1.Identifier + 2, // 32: v1.Filter.rack_field:type_name -> v1.RackFilterField + 3, // 33: v1.Filter.component_field:type_name -> v1.ComponentFilterField + 44, // 34: v1.Filter.query_info:type_name -> v1.StringQueryInfo + 5, // 35: v1.OrderBy.rack_field:type_name -> v1.RackOrderByField + 4, // 36: v1.OrderBy.component_field:type_name -> v1.ComponentOrderByField + 22, // 37: v1.Task.id:type_name -> v1.UUID + 22, // 38: v1.Task.rack_id:type_name -> v1.UUID + 22, // 39: v1.Task.component_uuids:type_name -> v1.UUID + 8, // 40: v1.Task.executor_type:type_name -> v1.TaskExecutorType + 7, // 41: v1.Task.status:type_name -> v1.TaskStatus + 188, // 42: v1.Task.queue_expires_at:type_name -> google.protobuf.Timestamp + 188, // 43: v1.Task.created_at:type_name -> google.protobuf.Timestamp + 188, // 44: v1.Task.finished_at:type_name -> google.protobuf.Timestamp + 22, // 45: v1.Task.applied_rule_id:type_name -> v1.UUID + 188, // 46: v1.Task.updated_at:type_name -> google.protobuf.Timestamp + 188, // 47: v1.Task.started_at:type_name -> google.protobuf.Timestamp + 30, // 48: v1.CreateExpectedRackRequest.rack:type_name -> v1.Rack + 22, // 49: v1.CreateExpectedRackResponse.id:type_name -> v1.UUID + 22, // 50: v1.GetRackInfoByIDRequest.id:type_name -> v1.UUID + 25, // 51: v1.GetRackInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo + 30, // 52: v1.GetRackInfoResponse.rack:type_name -> v1.Rack + 30, // 53: v1.PatchRackRequest.rack:type_name -> v1.Rack + 22, // 54: v1.GetComponentInfoByIDRequest.id:type_name -> v1.UUID + 25, // 55: v1.GetComponentInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo + 29, // 56: v1.GetComponentInfoResponse.component:type_name -> v1.Component + 30, // 57: v1.GetComponentInfoResponse.rack:type_name -> v1.Rack + 45, // 58: v1.GetListOfRacksRequest.filters:type_name -> v1.Filter + 43, // 59: v1.GetListOfRacksRequest.pagination:type_name -> v1.Pagination + 46, // 60: v1.GetListOfRacksRequest.order_by:type_name -> v1.OrderBy + 30, // 61: v1.GetListOfRacksResponse.racks:type_name -> v1.Rack + 42, // 62: v1.CreateNVLDomainRequest.nvl_domain:type_name -> v1.NVLDomain + 22, // 63: v1.CreateNVLDomainResponse.id:type_name -> v1.UUID + 31, // 64: v1.AttachRacksToNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier + 31, // 65: v1.AttachRacksToNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier + 31, // 66: v1.DetachRacksFromNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier + 44, // 67: v1.GetListOfNVLDomainsRequest.info:type_name -> v1.StringQueryInfo + 43, // 68: v1.GetListOfNVLDomainsRequest.pagination:type_name -> v1.Pagination + 42, // 69: v1.GetListOfNVLDomainsResponse.nvl_domains:type_name -> v1.NVLDomain + 31, // 70: v1.GetRacksForNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier + 30, // 71: v1.GetRacksForNVLDomainResponse.racks:type_name -> v1.Rack + 32, // 72: v1.UpgradeFirmwareRequest.target_spec:type_name -> v1.OperationTargetSpec + 188, // 73: v1.UpgradeFirmwareRequest.start_time:type_name -> google.protobuf.Timestamp + 188, // 74: v1.UpgradeFirmwareRequest.end_time:type_name -> google.protobuf.Timestamp + 88, // 75: v1.UpgradeFirmwareRequest.queue_options:type_name -> v1.QueueOptions + 22, // 76: v1.UpgradeFirmwareRequest.rule_id:type_name -> v1.UUID + 32, // 77: v1.GetComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 78: v1.GetComponentsRequest.filters:type_name -> v1.Filter + 43, // 79: v1.GetComponentsRequest.pagination:type_name -> v1.Pagination + 46, // 80: v1.GetComponentsRequest.order_by:type_name -> v1.OrderBy + 29, // 81: v1.GetComponentsResponse.components:type_name -> v1.Component + 32, // 82: v1.ValidateComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 83: v1.ValidateComponentsRequest.filters:type_name -> v1.Filter + 43, // 84: v1.ValidateComponentsRequest.pagination:type_name -> v1.Pagination + 46, // 85: v1.ValidateComponentsRequest.order_by:type_name -> v1.OrderBy + 73, // 86: v1.ValidateComponentsResponse.diffs:type_name -> v1.ComponentDiff + 11, // 87: v1.ComponentDiff.type:type_name -> v1.DiffType + 29, // 88: v1.ComponentDiff.expected:type_name -> v1.Component + 29, // 89: v1.ComponentDiff.actual:type_name -> v1.Component + 74, // 90: v1.ComponentDiff.field_diffs:type_name -> v1.FieldDiff + 22, // 91: v1.ComponentDiff.id:type_name -> v1.UUID + 29, // 92: v1.AddComponentRequest.component:type_name -> v1.Component + 29, // 93: v1.AddComponentResponse.component:type_name -> v1.Component + 22, // 94: v1.DeleteComponentRequest.id:type_name -> v1.UUID + 22, // 95: v1.DeleteRackRequest.id:type_name -> v1.UUID + 22, // 96: v1.PurgeRackRequest.id:type_name -> v1.UUID + 22, // 97: v1.PurgeComponentRequest.id:type_name -> v1.UUID + 22, // 98: v1.PatchComponentRequest.id:type_name -> v1.UUID + 27, // 99: v1.PatchComponentRequest.position:type_name -> v1.RackPosition + 22, // 100: v1.PatchComponentRequest.rack_id:type_name -> v1.UUID + 26, // 101: v1.PatchComponentRequest.bmcs:type_name -> v1.BMCInfo + 29, // 102: v1.PatchComponentResponse.component:type_name -> v1.Component + 22, // 103: v1.SubmitTaskResponse.task_ids:type_name -> v1.UUID + 12, // 104: v1.QueueOptions.conflict_strategy:type_name -> v1.ConflictStrategy + 32, // 105: v1.PowerOnRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 106: v1.PowerOnRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 107: v1.PowerOnRackRequest.rule_id:type_name -> v1.UUID + 32, // 108: v1.PowerOffRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 109: v1.PowerOffRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 110: v1.PowerOffRackRequest.rule_id:type_name -> v1.UUID + 32, // 111: v1.PowerResetRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 112: v1.PowerResetRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 113: v1.PowerResetRackRequest.rule_id:type_name -> v1.UUID + 32, // 114: v1.BringUpRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 22, // 115: v1.BringUpRackRequest.rule_id:type_name -> v1.UUID + 32, // 116: v1.IngestRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 117: v1.IngestRackRequest.filters:type_name -> v1.Filter + 22, // 118: v1.IngestRackRequest.rule_id:type_name -> v1.UUID + 32, // 119: v1.DecommissionRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 120: v1.DecommissionRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 121: v1.DecommissionRackRequest.rule_id:type_name -> v1.UUID + 22, // 122: v1.ListTasksRequest.rack_id:type_name -> v1.UUID + 43, // 123: v1.ListTasksRequest.pagination:type_name -> v1.Pagination + 22, // 124: v1.ListTasksRequest.component_id:type_name -> v1.UUID + 47, // 125: v1.ListTasksResponse.tasks:type_name -> v1.Task + 22, // 126: v1.GetTasksByIDsRequest.task_ids:type_name -> v1.UUID + 47, // 127: v1.GetTasksByIDsResponse.tasks:type_name -> v1.Task + 22, // 128: v1.CancelTaskRequest.task_id:type_name -> v1.UUID + 47, // 129: v1.CancelTaskResponse.task:type_name -> v1.Task + 22, // 130: v1.OperationRule.id:type_name -> v1.UUID + 13, // 131: v1.OperationRule.operation_type:type_name -> v1.OperationType + 188, // 132: v1.OperationRule.created_at:type_name -> google.protobuf.Timestamp + 188, // 133: v1.OperationRule.updated_at:type_name -> google.protobuf.Timestamp + 13, // 134: v1.CreateOperationRuleRequest.operation_type:type_name -> v1.OperationType + 22, // 135: v1.CreateOperationRuleResponse.id:type_name -> v1.UUID + 22, // 136: v1.UpdateOperationRuleRequest.rule_id:type_name -> v1.UUID + 22, // 137: v1.DeleteOperationRuleRequest.rule_id:type_name -> v1.UUID + 22, // 138: v1.SetRuleAsDefaultRequest.rule_id:type_name -> v1.UUID + 22, // 139: v1.GetOperationRuleRequest.rule_id:type_name -> v1.UUID + 13, // 140: v1.ListOperationRulesRequest.operation_type:type_name -> v1.OperationType + 103, // 141: v1.ListOperationRulesResponse.rules:type_name -> v1.OperationRule + 22, // 142: v1.AssociateRuleWithRackRequest.rack_id:type_name -> v1.UUID + 22, // 143: v1.AssociateRuleWithRackRequest.rule_id:type_name -> v1.UUID + 22, // 144: v1.DisassociateRuleFromRackRequest.rack_id:type_name -> v1.UUID + 13, // 145: v1.DisassociateRuleFromRackRequest.operation_type:type_name -> v1.OperationType + 22, // 146: v1.GetRackRuleAssociationRequest.rack_id:type_name -> v1.UUID + 13, // 147: v1.GetRackRuleAssociationRequest.operation_type:type_name -> v1.OperationType + 22, // 148: v1.GetRackRuleAssociationResponse.rule_id:type_name -> v1.UUID + 22, // 149: v1.ListRackRuleAssociationsRequest.rack_id:type_name -> v1.UUID + 22, // 150: v1.RackRuleAssociation.rack_id:type_name -> v1.UUID + 13, // 151: v1.RackRuleAssociation.operation_type:type_name -> v1.OperationType + 22, // 152: v1.RackRuleAssociation.rule_id:type_name -> v1.UUID + 188, // 153: v1.RackRuleAssociation.created_at:type_name -> google.protobuf.Timestamp + 188, // 154: v1.RackRuleAssociation.updated_at:type_name -> google.protobuf.Timestamp + 117, // 155: v1.ListRackRuleAssociationsResponse.associations:type_name -> v1.RackRuleAssociation + 14, // 156: v1.ScheduleSpec.type:type_name -> v1.ScheduleSpecType + 119, // 157: v1.ScheduleConfig.spec:type_name -> v1.ScheduleSpec + 15, // 158: v1.ScheduleConfig.overlap_policy:type_name -> v1.OverlapPolicy + 22, // 159: v1.TaskSchedule.id:type_name -> v1.UUID + 119, // 160: v1.TaskSchedule.spec:type_name -> v1.ScheduleSpec + 15, // 161: v1.TaskSchedule.overlap_policy:type_name -> v1.OverlapPolicy + 188, // 162: v1.TaskSchedule.next_run_at:type_name -> google.protobuf.Timestamp + 188, // 163: v1.TaskSchedule.last_run_at:type_name -> google.protobuf.Timestamp + 188, // 164: v1.TaskSchedule.created_at:type_name -> google.protobuf.Timestamp + 188, // 165: v1.TaskSchedule.updated_at:type_name -> google.protobuf.Timestamp + 89, // 166: v1.ScheduledOperation.power_on:type_name -> v1.PowerOnRackRequest + 90, // 167: v1.ScheduledOperation.power_off:type_name -> v1.PowerOffRackRequest + 91, // 168: v1.ScheduledOperation.power_reset:type_name -> v1.PowerResetRackRequest + 92, // 169: v1.ScheduledOperation.bring_up:type_name -> v1.BringUpRackRequest + 68, // 170: v1.ScheduledOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest + 93, // 171: v1.ScheduledOperation.ingest:type_name -> v1.IngestRackRequest + 120, // 172: v1.CreateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig + 122, // 173: v1.CreateTaskScheduleRequest.operation:type_name -> v1.ScheduledOperation + 22, // 174: v1.GetTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 175: v1.ListTaskSchedulesRequest.rack_id:type_name -> v1.UUID + 43, // 176: v1.ListTaskSchedulesRequest.pagination:type_name -> v1.Pagination + 121, // 177: v1.ListTaskSchedulesResponse.task_schedules:type_name -> v1.TaskSchedule + 22, // 178: v1.UpdateTaskScheduleRequest.id:type_name -> v1.UUID + 120, // 179: v1.UpdateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig + 189, // 180: v1.UpdateTaskScheduleRequest.update_mask:type_name -> google.protobuf.FieldMask + 22, // 181: v1.PauseTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 182: v1.ResumeTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 183: v1.DeleteTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 184: v1.TriggerTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 185: v1.TaskScheduleScope.id:type_name -> v1.UUID + 22, // 186: v1.TaskScheduleScope.schedule_id:type_name -> v1.UUID + 22, // 187: v1.TaskScheduleScope.rack_id:type_name -> v1.UUID + 35, // 188: v1.TaskScheduleScope.types:type_name -> v1.ComponentTypes + 34, // 189: v1.TaskScheduleScope.components:type_name -> v1.ComponentTargets + 22, // 190: v1.TaskScheduleScope.last_task_id:type_name -> v1.UUID + 188, // 191: v1.TaskScheduleScope.created_at:type_name -> google.protobuf.Timestamp + 22, // 192: v1.AddTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID + 32, // 193: v1.AddTaskScheduleScopeRequest.target_spec:type_name -> v1.OperationTargetSpec + 132, // 194: v1.AddTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope + 22, // 195: v1.RemoveTaskScheduleScopeRequest.scope_id:type_name -> v1.UUID + 22, // 196: v1.UpdateTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID + 32, // 197: v1.UpdateTaskScheduleScopeRequest.desired_scope:type_name -> v1.OperationTargetSpec + 132, // 198: v1.UpdateTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope + 22, // 199: v1.ListTaskScheduleScopesRequest.schedule_id:type_name -> v1.UUID + 132, // 200: v1.ListTaskScheduleScopesResponse.scopes:type_name -> v1.TaskScheduleScope + 122, // 201: v1.CheckScheduleConflictsRequest.operation:type_name -> v1.ScheduledOperation + 22, // 202: v1.CheckScheduleConflictsRequest.exclude_schedule_id:type_name -> v1.UUID + 121, // 203: v1.CheckScheduleConflictsResponse.conflicts:type_name -> v1.TaskSchedule + 144, // 204: v1.CreateOperationRunRequest.configuration:type_name -> v1.OperationRunConfiguration + 22, // 205: v1.CreateOperationRunResponse.id:type_name -> v1.UUID + 157, // 206: v1.OperationRunConfiguration.selector:type_name -> v1.OperationRunSelector + 159, // 207: v1.OperationRunConfiguration.options:type_name -> v1.OperationRunOptions + 177, // 208: v1.OperationRunConfiguration.operation:type_name -> v1.OperationRunOperation + 22, // 209: v1.GetOperationRunRequest.id:type_name -> v1.UUID + 180, // 210: v1.GetOperationRunResponse.operation_run:type_name -> v1.OperationRun + 149, // 211: v1.ListOperationRunsRequest.filter:type_name -> v1.OperationRunFilter + 43, // 212: v1.ListOperationRunsRequest.pagination:type_name -> v1.Pagination + 181, // 213: v1.ListOperationRunsResponse.operation_runs:type_name -> v1.OperationRunSummary + 44, // 214: v1.OperationRunFilter.name:type_name -> v1.StringQueryInfo + 150, // 215: v1.OperationRunFilter.states:type_name -> v1.OperationRunStateFilter + 179, // 216: v1.OperationRunFilter.operation_kinds:type_name -> v1.OperationKind + 18, // 217: v1.OperationRunStateFilter.status:type_name -> v1.OperationRunStatus + 19, // 218: v1.OperationRunStateFilter.reason:type_name -> v1.OperationRunStatusReason + 22, // 219: v1.ListOperationRunTargetsRequest.operation_run_id:type_name -> v1.UUID + 20, // 220: v1.ListOperationRunTargetsRequest.status:type_name -> v1.OperationRunTargetStatus + 43, // 221: v1.ListOperationRunTargetsRequest.pagination:type_name -> v1.Pagination + 16, // 222: v1.ListOperationRunTargetsRequest.phase_scope:type_name -> v1.OperationRunTargetPhaseScope + 185, // 223: v1.ListOperationRunTargetsResponse.targets:type_name -> v1.OperationRunTarget + 22, // 224: v1.PauseOperationRunRequest.id:type_name -> v1.UUID + 22, // 225: v1.ResumeOperationRunRequest.id:type_name -> v1.UUID + 22, // 226: v1.AdvanceOperationRunPhaseRequest.id:type_name -> v1.UUID + 22, // 227: v1.CancelOperationRunRequest.id:type_name -> v1.UUID + 158, // 228: v1.OperationRunSelector.percentage:type_name -> v1.PercentageSelector + 160, // 229: v1.OperationRunOptions.safety_policy:type_name -> v1.OperationRunSafetyPolicy + 174, // 230: v1.OperationRunOptions.conflict_policy:type_name -> v1.OperationRunConflictPolicy + 164, // 231: v1.OperationRunOptions.ordering_policy:type_name -> v1.OperationRunOrderingPolicy + 167, // 232: v1.OperationRunOptions.phase_policy:type_name -> v1.OperationRunPhasePolicy + 161, // 233: v1.OperationRunSafetyPolicy.gates:type_name -> v1.OperationRunSafetyGate + 162, // 234: v1.OperationRunSafetyGate.failure_rate:type_name -> v1.OperationRunFailureRateGate + 163, // 235: v1.OperationRunSafetyGate.failure_count:type_name -> v1.OperationRunFailureCountGate + 17, // 236: v1.OperationRunFailureRateGate.scope:type_name -> v1.OperationRunSafetyGateScope + 17, // 237: v1.OperationRunFailureCountGate.scope:type_name -> v1.OperationRunSafetyGateScope + 165, // 238: v1.OperationRunOrderingPolicy.random:type_name -> v1.OperationRunRandomOrdering + 166, // 239: v1.OperationRunOrderingPolicy.physical_location:type_name -> v1.OperationRunPhysicalLocationOrdering + 21, // 240: v1.OperationRunPhysicalLocationOrdering.strategy:type_name -> v1.OperationRunPhysicalLocationOrdering.Strategy + 168, // 241: v1.OperationRunPhasePolicy.equal:type_name -> v1.EqualOperationRunPhases + 169, // 242: v1.OperationRunPhasePolicy.percentage:type_name -> v1.PercentageOperationRunPhases + 171, // 243: v1.OperationRunPhasePolicy.count:type_name -> v1.CountOperationRunPhases + 173, // 244: v1.OperationRunPhasePolicy.advance_policy:type_name -> v1.OperationRunPhaseAdvancePolicy + 170, // 245: v1.PercentageOperationRunPhases.phases:type_name -> v1.OperationRunPercentagePhase + 172, // 246: v1.CountOperationRunPhases.phases:type_name -> v1.OperationRunCountPhase + 175, // 247: v1.OperationRunConflictPolicy.retry:type_name -> v1.OperationRunConflictRetryPolicy + 190, // 248: v1.OperationRunConflictRetryPolicy.retry_timeout:type_name -> google.protobuf.Duration + 190, // 249: v1.OperationRunConflictRetryPolicy.initial_retry_delay:type_name -> google.protobuf.Duration + 190, // 250: v1.OperationRunConflictRetryPolicy.max_retry_delay:type_name -> google.protobuf.Duration + 22, // 251: v1.OperationRunTargetScope.exclude_operation_run_ids:type_name -> v1.UUID + 36, // 252: v1.OperationRunTargetScope.default_scope_component_filter:type_name -> v1.ComponentFilter + 68, // 253: v1.OperationRunOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest + 176, // 254: v1.OperationRunOperation.target_scope:type_name -> v1.OperationRunTargetScope + 18, // 255: v1.OperationRunState.status:type_name -> v1.OperationRunStatus + 19, // 256: v1.OperationRunState.reason:type_name -> v1.OperationRunStatusReason + 13, // 257: v1.OperationKind.type:type_name -> v1.OperationType + 181, // 258: v1.OperationRun.summary:type_name -> v1.OperationRunSummary + 144, // 259: v1.OperationRun.configuration:type_name -> v1.OperationRunConfiguration + 182, // 260: v1.OperationRun.stats:type_name -> v1.OperationRunStats + 22, // 261: v1.OperationRunSummary.id:type_name -> v1.UUID + 179, // 262: v1.OperationRunSummary.operation_kind:type_name -> v1.OperationKind + 178, // 263: v1.OperationRunSummary.state:type_name -> v1.OperationRunState + 188, // 264: v1.OperationRunSummary.created_at:type_name -> google.protobuf.Timestamp + 188, // 265: v1.OperationRunSummary.updated_at:type_name -> google.protobuf.Timestamp + 188, // 266: v1.OperationRunSummary.started_at:type_name -> google.protobuf.Timestamp + 188, // 267: v1.OperationRunSummary.finished_at:type_name -> google.protobuf.Timestamp + 183, // 268: v1.OperationRunStats.current_phase_stats:type_name -> v1.OperationRunPhaseStats + 183, // 269: v1.OperationRunStats.cumulative_phase_stats:type_name -> v1.OperationRunPhaseStats + 184, // 270: v1.OperationRunPhaseStats.outcome_counts:type_name -> v1.OperationRunTargetOutcomeCounts + 22, // 271: v1.OperationRunTarget.id:type_name -> v1.UUID + 22, // 272: v1.OperationRunTarget.operation_run_id:type_name -> v1.UUID + 22, // 273: v1.OperationRunTarget.rack_id:type_name -> v1.UUID + 22, // 274: v1.OperationRunTarget.task_id:type_name -> v1.UUID + 20, // 275: v1.OperationRunTarget.status:type_name -> v1.OperationRunTargetStatus + 37, // 276: v1.OperationRunTarget.components_by_type:type_name -> v1.ComponentsByType + 188, // 277: v1.OperationRunTarget.created_at:type_name -> google.protobuf.Timestamp + 188, // 278: v1.OperationRunTarget.updated_at:type_name -> google.protobuf.Timestamp + 187, // 279: v1.NVLDomainTargets.targets:type_name -> v1.NVLDomainTarget + 22, // 280: v1.NVLDomainTarget.id:type_name -> v1.UUID + 1, // 281: v1.NVLDomainTarget.component_types:type_name -> v1.ComponentType + 101, // 282: v1.Flow.Version:input_type -> v1.VersionRequest + 123, // 283: v1.Flow.CreateTaskSchedule:input_type -> v1.CreateTaskScheduleRequest + 124, // 284: v1.Flow.GetTaskSchedule:input_type -> v1.GetTaskScheduleRequest + 125, // 285: v1.Flow.ListTaskSchedules:input_type -> v1.ListTaskSchedulesRequest + 127, // 286: v1.Flow.UpdateTaskSchedule:input_type -> v1.UpdateTaskScheduleRequest + 128, // 287: v1.Flow.PauseTaskSchedule:input_type -> v1.PauseTaskScheduleRequest + 129, // 288: v1.Flow.ResumeTaskSchedule:input_type -> v1.ResumeTaskScheduleRequest + 130, // 289: v1.Flow.DeleteTaskSchedule:input_type -> v1.DeleteTaskScheduleRequest + 131, // 290: v1.Flow.TriggerTaskSchedule:input_type -> v1.TriggerTaskScheduleRequest + 133, // 291: v1.Flow.AddTaskScheduleScope:input_type -> v1.AddTaskScheduleScopeRequest + 135, // 292: v1.Flow.RemoveTaskScheduleScope:input_type -> v1.RemoveTaskScheduleScopeRequest + 136, // 293: v1.Flow.UpdateTaskScheduleScope:input_type -> v1.UpdateTaskScheduleScopeRequest + 138, // 294: v1.Flow.ListTaskScheduleScopes:input_type -> v1.ListTaskScheduleScopesRequest + 140, // 295: v1.Flow.CheckScheduleConflicts:input_type -> v1.CheckScheduleConflictsRequest + 48, // 296: v1.Flow.CreateExpectedRack:input_type -> v1.CreateExpectedRackRequest + 50, // 297: v1.Flow.GetRackInfoByID:input_type -> v1.GetRackInfoByIDRequest + 51, // 298: v1.Flow.GetRackInfoBySerial:input_type -> v1.GetRackInfoBySerialRequest + 58, // 299: v1.Flow.GetListOfRacks:input_type -> v1.GetListOfRacksRequest + 53, // 300: v1.Flow.PatchRack:input_type -> v1.PatchRackRequest + 79, // 301: v1.Flow.DeleteRack:input_type -> v1.DeleteRackRequest + 81, // 302: v1.Flow.PurgeRack:input_type -> v1.PurgeRackRequest + 68, // 303: v1.Flow.UpgradeFirmware:input_type -> v1.UpgradeFirmwareRequest + 92, // 304: v1.Flow.BringUpRack:input_type -> v1.BringUpRackRequest + 93, // 305: v1.Flow.IngestRack:input_type -> v1.IngestRackRequest + 94, // 306: v1.Flow.DecommissionRack:input_type -> v1.DecommissionRackRequest + 89, // 307: v1.Flow.PowerOnRack:input_type -> v1.PowerOnRackRequest + 90, // 308: v1.Flow.PowerOffRack:input_type -> v1.PowerOffRackRequest + 91, // 309: v1.Flow.PowerResetRack:input_type -> v1.PowerResetRackRequest + 55, // 310: v1.Flow.GetComponentInfoByID:input_type -> v1.GetComponentInfoByIDRequest + 56, // 311: v1.Flow.GetComponentInfoBySerial:input_type -> v1.GetComponentInfoBySerialRequest + 69, // 312: v1.Flow.GetComponents:input_type -> v1.GetComponentsRequest + 71, // 313: v1.Flow.ValidateComponents:input_type -> v1.ValidateComponentsRequest + 75, // 314: v1.Flow.AddComponent:input_type -> v1.AddComponentRequest + 85, // 315: v1.Flow.PatchComponent:input_type -> v1.PatchComponentRequest + 77, // 316: v1.Flow.DeleteComponent:input_type -> v1.DeleteComponentRequest + 83, // 317: v1.Flow.PurgeComponent:input_type -> v1.PurgeComponentRequest + 60, // 318: v1.Flow.CreateNVLDomain:input_type -> v1.CreateNVLDomainRequest + 62, // 319: v1.Flow.AttachRacksToNVLDomain:input_type -> v1.AttachRacksToNVLDomainRequest + 63, // 320: v1.Flow.DetachRacksFromNVLDomain:input_type -> v1.DetachRacksFromNVLDomainRequest + 64, // 321: v1.Flow.GetListOfNVLDomains:input_type -> v1.GetListOfNVLDomainsRequest + 66, // 322: v1.Flow.GetRacksForNVLDomain:input_type -> v1.GetRacksForNVLDomainRequest + 95, // 323: v1.Flow.ListTasks:input_type -> v1.ListTasksRequest + 97, // 324: v1.Flow.GetTasksByIDs:input_type -> v1.GetTasksByIDsRequest + 99, // 325: v1.Flow.CancelTask:input_type -> v1.CancelTaskRequest + 104, // 326: v1.Flow.CreateOperationRule:input_type -> v1.CreateOperationRuleRequest + 106, // 327: v1.Flow.UpdateOperationRule:input_type -> v1.UpdateOperationRuleRequest + 107, // 328: v1.Flow.DeleteOperationRule:input_type -> v1.DeleteOperationRuleRequest + 109, // 329: v1.Flow.GetOperationRule:input_type -> v1.GetOperationRuleRequest + 110, // 330: v1.Flow.ListOperationRules:input_type -> v1.ListOperationRulesRequest + 108, // 331: v1.Flow.SetRuleAsDefault:input_type -> v1.SetRuleAsDefaultRequest + 112, // 332: v1.Flow.AssociateRuleWithRack:input_type -> v1.AssociateRuleWithRackRequest + 113, // 333: v1.Flow.DisassociateRuleFromRack:input_type -> v1.DisassociateRuleFromRackRequest + 114, // 334: v1.Flow.GetRackRuleAssociation:input_type -> v1.GetRackRuleAssociationRequest + 116, // 335: v1.Flow.ListRackRuleAssociations:input_type -> v1.ListRackRuleAssociationsRequest + 142, // 336: v1.Flow.CreateOperationRun:input_type -> v1.CreateOperationRunRequest + 145, // 337: v1.Flow.GetOperationRun:input_type -> v1.GetOperationRunRequest + 147, // 338: v1.Flow.ListOperationRuns:input_type -> v1.ListOperationRunsRequest + 151, // 339: v1.Flow.ListOperationRunTargets:input_type -> v1.ListOperationRunTargetsRequest + 153, // 340: v1.Flow.PauseOperationRun:input_type -> v1.PauseOperationRunRequest + 154, // 341: v1.Flow.ResumeOperationRun:input_type -> v1.ResumeOperationRunRequest + 155, // 342: v1.Flow.AdvanceOperationRunPhase:input_type -> v1.AdvanceOperationRunPhaseRequest + 156, // 343: v1.Flow.CancelOperationRun:input_type -> v1.CancelOperationRunRequest + 102, // 344: v1.Flow.Version:output_type -> v1.BuildInfo + 121, // 345: v1.Flow.CreateTaskSchedule:output_type -> v1.TaskSchedule + 121, // 346: v1.Flow.GetTaskSchedule:output_type -> v1.TaskSchedule + 126, // 347: v1.Flow.ListTaskSchedules:output_type -> v1.ListTaskSchedulesResponse + 121, // 348: v1.Flow.UpdateTaskSchedule:output_type -> v1.TaskSchedule + 121, // 349: v1.Flow.PauseTaskSchedule:output_type -> v1.TaskSchedule + 121, // 350: v1.Flow.ResumeTaskSchedule:output_type -> v1.TaskSchedule + 191, // 351: v1.Flow.DeleteTaskSchedule:output_type -> google.protobuf.Empty + 87, // 352: v1.Flow.TriggerTaskSchedule:output_type -> v1.SubmitTaskResponse + 134, // 353: v1.Flow.AddTaskScheduleScope:output_type -> v1.AddTaskScheduleScopeResponse + 191, // 354: v1.Flow.RemoveTaskScheduleScope:output_type -> google.protobuf.Empty + 137, // 355: v1.Flow.UpdateTaskScheduleScope:output_type -> v1.UpdateTaskScheduleScopeResponse + 139, // 356: v1.Flow.ListTaskScheduleScopes:output_type -> v1.ListTaskScheduleScopesResponse + 141, // 357: v1.Flow.CheckScheduleConflicts:output_type -> v1.CheckScheduleConflictsResponse + 49, // 358: v1.Flow.CreateExpectedRack:output_type -> v1.CreateExpectedRackResponse + 52, // 359: v1.Flow.GetRackInfoByID:output_type -> v1.GetRackInfoResponse + 52, // 360: v1.Flow.GetRackInfoBySerial:output_type -> v1.GetRackInfoResponse + 59, // 361: v1.Flow.GetListOfRacks:output_type -> v1.GetListOfRacksResponse + 54, // 362: v1.Flow.PatchRack:output_type -> v1.PatchRackResponse + 80, // 363: v1.Flow.DeleteRack:output_type -> v1.DeleteRackResponse + 82, // 364: v1.Flow.PurgeRack:output_type -> v1.PurgeRackResponse + 87, // 365: v1.Flow.UpgradeFirmware:output_type -> v1.SubmitTaskResponse + 87, // 366: v1.Flow.BringUpRack:output_type -> v1.SubmitTaskResponse + 87, // 367: v1.Flow.IngestRack:output_type -> v1.SubmitTaskResponse + 87, // 368: v1.Flow.DecommissionRack:output_type -> v1.SubmitTaskResponse + 87, // 369: v1.Flow.PowerOnRack:output_type -> v1.SubmitTaskResponse + 87, // 370: v1.Flow.PowerOffRack:output_type -> v1.SubmitTaskResponse + 87, // 371: v1.Flow.PowerResetRack:output_type -> v1.SubmitTaskResponse + 57, // 372: v1.Flow.GetComponentInfoByID:output_type -> v1.GetComponentInfoResponse + 57, // 373: v1.Flow.GetComponentInfoBySerial:output_type -> v1.GetComponentInfoResponse + 70, // 374: v1.Flow.GetComponents:output_type -> v1.GetComponentsResponse + 72, // 375: v1.Flow.ValidateComponents:output_type -> v1.ValidateComponentsResponse + 76, // 376: v1.Flow.AddComponent:output_type -> v1.AddComponentResponse + 86, // 377: v1.Flow.PatchComponent:output_type -> v1.PatchComponentResponse + 78, // 378: v1.Flow.DeleteComponent:output_type -> v1.DeleteComponentResponse + 84, // 379: v1.Flow.PurgeComponent:output_type -> v1.PurgeComponentResponse + 61, // 380: v1.Flow.CreateNVLDomain:output_type -> v1.CreateNVLDomainResponse + 191, // 381: v1.Flow.AttachRacksToNVLDomain:output_type -> google.protobuf.Empty + 191, // 382: v1.Flow.DetachRacksFromNVLDomain:output_type -> google.protobuf.Empty + 65, // 383: v1.Flow.GetListOfNVLDomains:output_type -> v1.GetListOfNVLDomainsResponse + 67, // 384: v1.Flow.GetRacksForNVLDomain:output_type -> v1.GetRacksForNVLDomainResponse + 96, // 385: v1.Flow.ListTasks:output_type -> v1.ListTasksResponse + 98, // 386: v1.Flow.GetTasksByIDs:output_type -> v1.GetTasksByIDsResponse + 100, // 387: v1.Flow.CancelTask:output_type -> v1.CancelTaskResponse + 105, // 388: v1.Flow.CreateOperationRule:output_type -> v1.CreateOperationRuleResponse + 191, // 389: v1.Flow.UpdateOperationRule:output_type -> google.protobuf.Empty + 191, // 390: v1.Flow.DeleteOperationRule:output_type -> google.protobuf.Empty + 103, // 391: v1.Flow.GetOperationRule:output_type -> v1.OperationRule + 111, // 392: v1.Flow.ListOperationRules:output_type -> v1.ListOperationRulesResponse + 191, // 393: v1.Flow.SetRuleAsDefault:output_type -> google.protobuf.Empty + 191, // 394: v1.Flow.AssociateRuleWithRack:output_type -> google.protobuf.Empty + 191, // 395: v1.Flow.DisassociateRuleFromRack:output_type -> google.protobuf.Empty + 115, // 396: v1.Flow.GetRackRuleAssociation:output_type -> v1.GetRackRuleAssociationResponse + 118, // 397: v1.Flow.ListRackRuleAssociations:output_type -> v1.ListRackRuleAssociationsResponse + 143, // 398: v1.Flow.CreateOperationRun:output_type -> v1.CreateOperationRunResponse + 146, // 399: v1.Flow.GetOperationRun:output_type -> v1.GetOperationRunResponse + 148, // 400: v1.Flow.ListOperationRuns:output_type -> v1.ListOperationRunsResponse + 152, // 401: v1.Flow.ListOperationRunTargets:output_type -> v1.ListOperationRunTargetsResponse + 180, // 402: v1.Flow.PauseOperationRun:output_type -> v1.OperationRun + 180, // 403: v1.Flow.ResumeOperationRun:output_type -> v1.OperationRun + 180, // 404: v1.Flow.AdvanceOperationRunPhase:output_type -> v1.OperationRun + 180, // 405: v1.Flow.CancelOperationRun:output_type -> v1.OperationRun + 344, // [344:406] is the sub-list for method output_type + 282, // [282:344] is the sub-list for method input_type + 282, // [282:282] is the sub-list for extension type_name + 282, // [282:282] is the sub-list for extension extendee + 0, // [0:282] is the sub-list for field type_name } func init() { file_flow_proto_init() } @@ -12835,6 +13007,7 @@ func file_flow_proto_init() { file_flow_proto_msgTypes[10].OneofWrappers = []any{ (*OperationTargetSpec_Racks)(nil), (*OperationTargetSpec_Components)(nil), + (*OperationTargetSpec_NvlDomains)(nil), } file_flow_proto_msgTypes[14].OneofWrappers = []any{ (*ComponentFilter_Types)(nil), @@ -12915,13 +13088,17 @@ func file_flow_proto_init() { } file_flow_proto_msgTypes[157].OneofWrappers = []any{} file_flow_proto_msgTypes[159].OneofWrappers = []any{} + file_flow_proto_msgTypes[165].OneofWrappers = []any{ + (*NVLDomainTarget_Id)(nil), + (*NVLDomainTarget_Name)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_flow_proto_rawDesc), len(file_flow_proto_rawDesc)), NumEnums: 22, - NumMessages: 164, + NumMessages: 166, NumExtensions: 0, NumServices: 1, }, diff --git a/rest-api/flow/proto/v1/flow.proto b/rest-api/flow/proto/v1/flow.proto index 3dc6ff62dc..a02f6aa6d6 100644 --- a/rest-api/flow/proto/v1/flow.proto +++ b/rest-api/flow/proto/v1/flow.proto @@ -274,12 +274,14 @@ message Identifier { } // OperationTargetSpec contains targets for an operation. -// Supports either rack-level targeting (with optional type filtering) -// or component-level targeting (by UUID or external reference), but not both. +// Supports rack-level or NVLink-domain targeting (with optional type filtering), +// or component-level targeting (by UUID or external reference), but not more +// than one target kind at a time. message OperationTargetSpec { oneof targets { RackTargets racks = 1; ComponentTargets components = 2; + NVLDomainTargets nvl_domains = 3; } } @@ -524,7 +526,7 @@ message UpgradeFirmwareRequest { // GetComponents - retrieves components from local database message GetComponentsRequest { - optional OperationTargetSpec target_spec = 1; // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, queries all components. + optional OperationTargetSpec target_spec = 1; // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, queries all components. repeated Filter filters = 2; // Filter conditions for component queries optional Pagination pagination = 3; optional OrderBy order_by = 4; @@ -536,7 +538,7 @@ message GetComponentsResponse { } message ValidateComponentsRequest { - optional OperationTargetSpec target_spec = 1; // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, returns all diffs. + optional OperationTargetSpec target_spec = 1; // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, returns all diffs. repeated Filter filters = 2; // Filter conditions for component queries optional Pagination pagination = 3; optional OrderBy order_by = 4; @@ -657,7 +659,7 @@ message QueueOptions { } message PowerOnRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components string description = 2; // optional task description optional QueueOptions queue_options = 3; optional UUID rule_id = 4; // optional: override rule resolution with a specific rule @@ -671,7 +673,7 @@ message PowerOnRackRequest { } message PowerOffRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components bool forced = 2; string description = 3; // optional task description optional QueueOptions queue_options = 4; @@ -686,7 +688,7 @@ message PowerOffRackRequest { } message PowerResetRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components bool forced = 2; string description = 3; // optional task description optional QueueOptions queue_options = 4; @@ -701,7 +703,7 @@ message PowerResetRackRequest { } message BringUpRackRequest { - OperationTargetSpec target_spec = 1; // Target racks for bring-up + OperationTargetSpec target_spec = 1; // Target racks, NVLink domains, or components for bring-up string description = 2; // optional task description optional UUID rule_id = 3; // optional: override rule resolution with a specific rule // When true, allow the bring-up sequence (which may power-cycle hosts @@ -714,7 +716,7 @@ message BringUpRackRequest { } message IngestRackRequest { - OperationTargetSpec target_spec = 1; // Target racks for ingestion + OperationTargetSpec target_spec = 1; // Target racks, NVLink domains, or components for ingestion repeated Filter filters = 2; // Filter conditions for component queries (e.g. by type, name) string description = 3; // optional task description optional UUID rule_id = 4; // optional: override rule resolution with a specific rule @@ -961,7 +963,7 @@ message ScheduledOperation { // CreateTaskScheduleRequest creates a new TaskSchedule. // The target_spec on the operation message defines the initial scope; it follows -// the same targeting rules as AddTaskScheduleScope (rack-level or component-level). +// the same targeting rules as AddTaskScheduleScope. // Use AddTaskScheduleScope / RemoveTaskScheduleScope to modify the scope after creation. message CreateTaskScheduleRequest { ScheduleConfig schedule = 1; @@ -1050,8 +1052,9 @@ message TaskScheduleScope { } // AddTaskScheduleScopeRequest adds one or more scope entries to a schedule. -// Supports rack-level targeting (with optional component-type filter) and -// component-level targeting (specific components by UUID or external reference). +// Supports rack or NVLink domain targeting (with an optional component-type +// filter) and component targeting (specific components by UUID or external reference). +// NVLink domain membership is resolved to rack scopes when this request is handled. // For component-level targets the server resolves which rack each component // belongs to and groups them into per-rack scope entries automatically. // Racks already present in the scope have their component filter merged with the @@ -1077,7 +1080,7 @@ message RemoveTaskScheduleScopeRequest { // desired target_spec: racks present in desired_scope but not in the current scope // are added; racks present in the current scope but absent from desired_scope are // removed; racks present in both have their component_filter updated if changed. -// For component-level targets the server resolves rack membership automatically. +// For NVLink domain and component targets the server resolves rack membership automatically. message UpdateTaskScheduleScopeRequest { UUID schedule_id = 1; OperationTargetSpec desired_scope = 2; @@ -1521,3 +1524,19 @@ message OperationRunTarget { google.protobuf.Timestamp created_at = 10; google.protobuf.Timestamp updated_at = 11; } + +// NVLDomainTargets contains one or more NVLink domain targets. +message NVLDomainTargets { + repeated NVLDomainTarget targets = 1; +} + +// NVLDomainTarget identifies an NVLink domain and optionally filters the +// components selected from every rack currently belonging to that domain. +message NVLDomainTarget { + oneof identifier { + UUID id = 1; // NVLink domain UUID + string name = 2; // NVLink domain name + } + // Optional: filter by component type. Omit (or send an empty list) to include all component types in the domain. + repeated ComponentType component_types = 3; +} diff --git a/rest-api/proto/flow/gen/v1/flow.pb.go b/rest-api/proto/flow/gen/v1/flow.pb.go index d3456e7a8b..b062f09f65 100644 --- a/rest-api/proto/flow/gen/v1/flow.pb.go +++ b/rest-api/proto/flow/gen/v1/flow.pb.go @@ -1917,14 +1917,16 @@ func (x *Identifier) GetName() string { } // OperationTargetSpec contains targets for an operation. -// Supports either rack-level targeting (with optional type filtering) -// or component-level targeting (by UUID or external reference), but not both. +// Supports rack-level or NVLink-domain targeting (with optional type filtering), +// or component-level targeting (by UUID or external reference), but not more +// than one target kind at a time. type OperationTargetSpec struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Targets: // // *OperationTargetSpec_Racks // *OperationTargetSpec_Components + // *OperationTargetSpec_NvlDomains Targets isOperationTargetSpec_Targets `protobuf_oneof:"targets"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1985,6 +1987,15 @@ func (x *OperationTargetSpec) GetComponents() *ComponentTargets { return nil } +func (x *OperationTargetSpec) GetNvlDomains() *NVLDomainTargets { + if x != nil { + if x, ok := x.Targets.(*OperationTargetSpec_NvlDomains); ok { + return x.NvlDomains + } + } + return nil +} + type isOperationTargetSpec_Targets interface { isOperationTargetSpec_Targets() } @@ -1997,10 +2008,16 @@ type OperationTargetSpec_Components struct { Components *ComponentTargets `protobuf:"bytes,2,opt,name=components,proto3,oneof"` } +type OperationTargetSpec_NvlDomains struct { + NvlDomains *NVLDomainTargets `protobuf:"bytes,3,opt,name=nvl_domains,json=nvlDomains,proto3,oneof"` +} + func (*OperationTargetSpec_Racks) isOperationTargetSpec_Targets() {} func (*OperationTargetSpec_Components) isOperationTargetSpec_Targets() {} +func (*OperationTargetSpec_NvlDomains) isOperationTargetSpec_Targets() {} + // RackTargets contains one or more rack targets type RackTargets struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -4159,7 +4176,7 @@ func (x *UpgradeFirmwareRequest) GetOverrideReadinessCheck() bool { // GetComponents - retrieves components from local database type GetComponentsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, queries all components. + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, queries all components. Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries Pagination *Pagination `protobuf:"bytes,3,opt,name=pagination,proto3,oneof" json:"pagination,omitempty"` OrderBy *OrderBy `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3,oneof" json:"order_by,omitempty"` @@ -4279,7 +4296,7 @@ func (x *GetComponentsResponse) GetTotal() int32 { type ValidateComponentsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, returns all diffs. + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3,oneof" json:"target_spec,omitempty"` // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, returns all diffs. Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries Pagination *Pagination `protobuf:"bytes,3,opt,name=pagination,proto3,oneof" json:"pagination,omitempty"` OrderBy *OrderBy `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3,oneof" json:"order_by,omitempty"` @@ -5223,7 +5240,7 @@ func (x *QueueOptions) GetQueueTimeoutSeconds() int32 { type PowerOnRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,3,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` RuleId *UUID `protobuf:"bytes,4,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule @@ -5305,7 +5322,7 @@ func (x *PowerOnRackRequest) GetOverrideReadinessCheck() bool { type PowerOffRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Forced bool `protobuf:"varint,2,opt,name=forced,proto3" json:"forced,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,4,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` @@ -5395,7 +5412,7 @@ func (x *PowerOffRackRequest) GetOverrideReadinessCheck() bool { type PowerResetRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Flexible targeting: rack(s) with optional type filter, or specific components + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks or NVLink domains with an optional type filter, or specific components Forced bool `protobuf:"varint,2,opt,name=forced,proto3" json:"forced,omitempty"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description QueueOptions *QueueOptions `protobuf:"bytes,4,opt,name=queue_options,json=queueOptions,proto3,oneof" json:"queue_options,omitempty"` @@ -5485,7 +5502,7 @@ func (x *PowerResetRackRequest) GetOverrideReadinessCheck() bool { type BringUpRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks for bring-up + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks, NVLink domains, or components for bring-up Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // optional task description RuleId *UUID `protobuf:"bytes,3,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule // When true, allow the bring-up sequence (which may power-cycle hosts @@ -5559,7 +5576,7 @@ func (x *BringUpRackRequest) GetOverrideReadinessCheck() bool { type IngestRackRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks for ingestion + TargetSpec *OperationTargetSpec `protobuf:"bytes,1,opt,name=target_spec,json=targetSpec,proto3" json:"target_spec,omitempty"` // Target racks, NVLink domains, or components for ingestion Filters []*Filter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` // Filter conditions for component queries (e.g. by type, name) Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // optional task description RuleId *UUID `protobuf:"bytes,4,opt,name=rule_id,json=ruleId,proto3,oneof" json:"rule_id,omitempty"` // optional: override rule resolution with a specific rule @@ -7398,7 +7415,7 @@ func (*ScheduledOperation_Ingest) isScheduledOperation_Operation() {} // CreateTaskScheduleRequest creates a new TaskSchedule. // The target_spec on the operation message defines the initial scope; it follows -// the same targeting rules as AddTaskScheduleScope (rack-level or component-level). +// the same targeting rules as AddTaskScheduleScope. // Use AddTaskScheduleScope / RemoveTaskScheduleScope to modify the scope after creation. type CreateTaskScheduleRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -8001,8 +8018,9 @@ func (*TaskScheduleScope_Types) isTaskScheduleScope_ComponentFilter() {} func (*TaskScheduleScope_Components) isTaskScheduleScope_ComponentFilter() {} // AddTaskScheduleScopeRequest adds one or more scope entries to a schedule. -// Supports rack-level targeting (with optional component-type filter) and -// component-level targeting (specific components by UUID or external reference). +// Supports rack or NVLink domain targeting (with an optional component-type +// filter) and component targeting (specific components by UUID or external reference). +// NVLink domain membership is resolved to rack scopes when this request is handled. // For component-level targets the server resolves which rack each component // belongs to and groups them into per-rack scope entries automatically. // Racks already present in the scope have their component filter merged with the @@ -8155,7 +8173,7 @@ func (x *RemoveTaskScheduleScopeRequest) GetScopeId() *UUID { // desired target_spec: racks present in desired_scope but not in the current scope // are added; racks present in the current scope but absent from desired_scope are // removed; racks present in both have their component_filter updated if changed. -// For component-level targets the server resolves rack membership automatically. +// For NVLink domain and component targets the server resolves rack membership automatically. type UpdateTaskScheduleScopeRequest struct { state protoimpl.MessageState `protogen:"open.v1"` ScheduleId *UUID `protobuf:"bytes,1,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` @@ -11151,6 +11169,144 @@ func (x *OperationRunTarget) GetUpdatedAt() *timestamppb.Timestamp { return nil } +// NVLDomainTargets contains one or more NVLink domain targets. +type NVLDomainTargets struct { + state protoimpl.MessageState `protogen:"open.v1"` + Targets []*NVLDomainTarget `protobuf:"bytes,1,rep,name=targets,proto3" json:"targets,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NVLDomainTargets) Reset() { + *x = NVLDomainTargets{} + mi := &file_flow_proto_msgTypes[163] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NVLDomainTargets) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NVLDomainTargets) ProtoMessage() {} + +func (x *NVLDomainTargets) ProtoReflect() protoreflect.Message { + mi := &file_flow_proto_msgTypes[163] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NVLDomainTargets.ProtoReflect.Descriptor instead. +func (*NVLDomainTargets) Descriptor() ([]byte, []int) { + return file_flow_proto_rawDescGZIP(), []int{163} +} + +func (x *NVLDomainTargets) GetTargets() []*NVLDomainTarget { + if x != nil { + return x.Targets + } + return nil +} + +// NVLDomainTarget identifies an NVLink domain and optionally filters the +// components selected from every rack currently belonging to that domain. +type NVLDomainTarget struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: + // + // *NVLDomainTarget_Id + // *NVLDomainTarget_Name + Identifier isNVLDomainTarget_Identifier `protobuf_oneof:"identifier"` + // Optional: filter by component type. Omit (or send an empty list) to include all component types in the domain. + ComponentTypes []ComponentType `protobuf:"varint,3,rep,packed,name=component_types,json=componentTypes,proto3,enum=v1.ComponentType" json:"component_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NVLDomainTarget) Reset() { + *x = NVLDomainTarget{} + mi := &file_flow_proto_msgTypes[164] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NVLDomainTarget) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NVLDomainTarget) ProtoMessage() {} + +func (x *NVLDomainTarget) ProtoReflect() protoreflect.Message { + mi := &file_flow_proto_msgTypes[164] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NVLDomainTarget.ProtoReflect.Descriptor instead. +func (*NVLDomainTarget) Descriptor() ([]byte, []int) { + return file_flow_proto_rawDescGZIP(), []int{164} +} + +func (x *NVLDomainTarget) GetIdentifier() isNVLDomainTarget_Identifier { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *NVLDomainTarget) GetId() *UUID { + if x != nil { + if x, ok := x.Identifier.(*NVLDomainTarget_Id); ok { + return x.Id + } + } + return nil +} + +func (x *NVLDomainTarget) GetName() string { + if x != nil { + if x, ok := x.Identifier.(*NVLDomainTarget_Name); ok { + return x.Name + } + } + return "" +} + +func (x *NVLDomainTarget) GetComponentTypes() []ComponentType { + if x != nil { + return x.ComponentTypes + } + return nil +} + +type isNVLDomainTarget_Identifier interface { + isNVLDomainTarget_Identifier() +} + +type NVLDomainTarget_Id struct { + Id *UUID `protobuf:"bytes,1,opt,name=id,proto3,oneof"` // NVLink domain UUID +} + +type NVLDomainTarget_Name struct { + Name string `protobuf:"bytes,2,opt,name=name,proto3,oneof"` // NVLink domain name +} + +func (*NVLDomainTarget_Id) isNVLDomainTarget_Identifier() {} + +func (*NVLDomainTarget_Name) isNVLDomainTarget_Identifier() {} + var File_flow_proto protoreflect.FileDescriptor const file_flow_proto_rawDesc = "" + @@ -11217,12 +11373,14 @@ const file_flow_proto_rawDesc = "" + "\n" + "Identifier\x12\x18\n" + "\x02id\x18\x01 \x01(\v2\b.v1.UUIDR\x02id\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\x81\x01\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xba\x01\n" + "\x13OperationTargetSpec\x12'\n" + "\x05racks\x18\x01 \x01(\v2\x0f.v1.RackTargetsH\x00R\x05racks\x126\n" + "\n" + "components\x18\x02 \x01(\v2\x14.v1.ComponentTargetsH\x00R\n" + - "componentsB\t\n" + + "components\x127\n" + + "\vnvl_domains\x18\x03 \x01(\v2\x14.v1.NVLDomainTargetsH\x00R\n" + + "nvlDomainsB\t\n" + "\atargets\"7\n" + "\vRackTargets\x12(\n" + "\atargets\x18\x01 \x03(\v2\x0e.v1.RackTargetR\atargets\"A\n" + @@ -11939,7 +12097,15 @@ const file_flow_proto_rawDesc = "" + "created_at\x18\n" + " \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + "\n" + - "updated_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt*D\n" + + "updated_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"A\n" + + "\x10NVLDomainTargets\x12-\n" + + "\atargets\x18\x01 \x03(\v2\x13.v1.NVLDomainTargetR\atargets\"\x8d\x01\n" + + "\x0fNVLDomainTarget\x12\x1a\n" + + "\x02id\x18\x01 \x01(\v2\b.v1.UUIDH\x00R\x02id\x12\x14\n" + + "\x04name\x18\x02 \x01(\tH\x00R\x04name\x12:\n" + + "\x0fcomponent_types\x18\x03 \x03(\x0e2\x11.v1.ComponentTypeR\x0ecomponentTypesB\f\n" + + "\n" + + "identifier*D\n" + "\aBMCType\x12\x14\n" + "\x10BMC_TYPE_UNKNOWN\x10\x00\x12\x11\n" + "\rBMC_TYPE_HOST\x10\x01\x12\x10\n" + @@ -12144,7 +12310,7 @@ func file_flow_proto_rawDescGZIP() []byte { } var file_flow_proto_enumTypes = make([]protoimpl.EnumInfo, 22) -var file_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 163) +var file_flow_proto_msgTypes = make([]protoimpl.MessageInfo, 165) var file_flow_proto_goTypes = []any{ (BMCType)(0), // 0: v1.BMCType (ComponentType)(0), // 1: v1.ComponentType @@ -12331,10 +12497,12 @@ var file_flow_proto_goTypes = []any{ (*OperationRunPhaseStats)(nil), // 182: v1.OperationRunPhaseStats (*OperationRunTargetOutcomeCounts)(nil), // 183: v1.OperationRunTargetOutcomeCounts (*OperationRunTarget)(nil), // 184: v1.OperationRunTarget - (*timestamppb.Timestamp)(nil), // 185: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 186: google.protobuf.FieldMask - (*durationpb.Duration)(nil), // 187: google.protobuf.Duration - (*emptypb.Empty)(nil), // 188: google.protobuf.Empty + (*NVLDomainTargets)(nil), // 185: v1.NVLDomainTargets + (*NVLDomainTarget)(nil), // 186: v1.NVLDomainTarget + (*timestamppb.Timestamp)(nil), // 187: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 188: google.protobuf.FieldMask + (*durationpb.Duration)(nil), // 189: google.protobuf.Duration + (*emptypb.Empty)(nil), // 190: google.protobuf.Empty } var file_flow_proto_depIdxs = []int32{ 22, // 0: v1.DeviceInfo.id:type_name -> v1.UUID @@ -12354,391 +12522,395 @@ var file_flow_proto_depIdxs = []int32{ 22, // 14: v1.Identifier.id:type_name -> v1.UUID 33, // 15: v1.OperationTargetSpec.racks:type_name -> v1.RackTargets 34, // 16: v1.OperationTargetSpec.components:type_name -> v1.ComponentTargets - 39, // 17: v1.RackTargets.targets:type_name -> v1.RackTarget - 40, // 18: v1.ComponentTargets.targets:type_name -> v1.ComponentTarget - 1, // 19: v1.ComponentTypes.types:type_name -> v1.ComponentType - 35, // 20: v1.ComponentFilter.types:type_name -> v1.ComponentTypes - 34, // 21: v1.ComponentFilter.components:type_name -> v1.ComponentTargets - 38, // 22: v1.ComponentsByType.groups:type_name -> v1.ComponentsForType - 1, // 23: v1.ComponentsForType.type:type_name -> v1.ComponentType - 22, // 24: v1.ComponentsForType.component_ids:type_name -> v1.UUID - 22, // 25: v1.RackTarget.id:type_name -> v1.UUID - 1, // 26: v1.RackTarget.component_types:type_name -> v1.ComponentType - 22, // 27: v1.ComponentTarget.id:type_name -> v1.UUID - 41, // 28: v1.ComponentTarget.external:type_name -> v1.ExternalRef - 1, // 29: v1.ExternalRef.type:type_name -> v1.ComponentType - 31, // 30: v1.NVLDomain.identifier:type_name -> v1.Identifier - 2, // 31: v1.Filter.rack_field:type_name -> v1.RackFilterField - 3, // 32: v1.Filter.component_field:type_name -> v1.ComponentFilterField - 44, // 33: v1.Filter.query_info:type_name -> v1.StringQueryInfo - 5, // 34: v1.OrderBy.rack_field:type_name -> v1.RackOrderByField - 4, // 35: v1.OrderBy.component_field:type_name -> v1.ComponentOrderByField - 22, // 36: v1.Task.id:type_name -> v1.UUID - 22, // 37: v1.Task.rack_id:type_name -> v1.UUID - 22, // 38: v1.Task.component_uuids:type_name -> v1.UUID - 8, // 39: v1.Task.executor_type:type_name -> v1.TaskExecutorType - 7, // 40: v1.Task.status:type_name -> v1.TaskStatus - 185, // 41: v1.Task.queue_expires_at:type_name -> google.protobuf.Timestamp - 185, // 42: v1.Task.created_at:type_name -> google.protobuf.Timestamp - 185, // 43: v1.Task.finished_at:type_name -> google.protobuf.Timestamp - 22, // 44: v1.Task.applied_rule_id:type_name -> v1.UUID - 185, // 45: v1.Task.updated_at:type_name -> google.protobuf.Timestamp - 185, // 46: v1.Task.started_at:type_name -> google.protobuf.Timestamp - 30, // 47: v1.CreateExpectedRackRequest.rack:type_name -> v1.Rack - 22, // 48: v1.CreateExpectedRackResponse.id:type_name -> v1.UUID - 22, // 49: v1.GetRackInfoByIDRequest.id:type_name -> v1.UUID - 25, // 50: v1.GetRackInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo - 30, // 51: v1.GetRackInfoResponse.rack:type_name -> v1.Rack - 30, // 52: v1.PatchRackRequest.rack:type_name -> v1.Rack - 22, // 53: v1.GetComponentInfoByIDRequest.id:type_name -> v1.UUID - 25, // 54: v1.GetComponentInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo - 29, // 55: v1.GetComponentInfoResponse.component:type_name -> v1.Component - 30, // 56: v1.GetComponentInfoResponse.rack:type_name -> v1.Rack - 45, // 57: v1.GetListOfRacksRequest.filters:type_name -> v1.Filter - 43, // 58: v1.GetListOfRacksRequest.pagination:type_name -> v1.Pagination - 46, // 59: v1.GetListOfRacksRequest.order_by:type_name -> v1.OrderBy - 30, // 60: v1.GetListOfRacksResponse.racks:type_name -> v1.Rack - 42, // 61: v1.CreateNVLDomainRequest.nvl_domain:type_name -> v1.NVLDomain - 22, // 62: v1.CreateNVLDomainResponse.id:type_name -> v1.UUID - 31, // 63: v1.AttachRacksToNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier - 31, // 64: v1.AttachRacksToNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier - 31, // 65: v1.DetachRacksFromNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier - 44, // 66: v1.GetListOfNVLDomainsRequest.info:type_name -> v1.StringQueryInfo - 43, // 67: v1.GetListOfNVLDomainsRequest.pagination:type_name -> v1.Pagination - 42, // 68: v1.GetListOfNVLDomainsResponse.nvl_domains:type_name -> v1.NVLDomain - 31, // 69: v1.GetRacksForNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier - 30, // 70: v1.GetRacksForNVLDomainResponse.racks:type_name -> v1.Rack - 32, // 71: v1.UpgradeFirmwareRequest.target_spec:type_name -> v1.OperationTargetSpec - 185, // 72: v1.UpgradeFirmwareRequest.start_time:type_name -> google.protobuf.Timestamp - 185, // 73: v1.UpgradeFirmwareRequest.end_time:type_name -> google.protobuf.Timestamp - 88, // 74: v1.UpgradeFirmwareRequest.queue_options:type_name -> v1.QueueOptions - 22, // 75: v1.UpgradeFirmwareRequest.rule_id:type_name -> v1.UUID - 32, // 76: v1.GetComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 77: v1.GetComponentsRequest.filters:type_name -> v1.Filter - 43, // 78: v1.GetComponentsRequest.pagination:type_name -> v1.Pagination - 46, // 79: v1.GetComponentsRequest.order_by:type_name -> v1.OrderBy - 29, // 80: v1.GetComponentsResponse.components:type_name -> v1.Component - 32, // 81: v1.ValidateComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 82: v1.ValidateComponentsRequest.filters:type_name -> v1.Filter - 43, // 83: v1.ValidateComponentsRequest.pagination:type_name -> v1.Pagination - 46, // 84: v1.ValidateComponentsRequest.order_by:type_name -> v1.OrderBy - 73, // 85: v1.ValidateComponentsResponse.diffs:type_name -> v1.ComponentDiff - 11, // 86: v1.ComponentDiff.type:type_name -> v1.DiffType - 29, // 87: v1.ComponentDiff.expected:type_name -> v1.Component - 29, // 88: v1.ComponentDiff.actual:type_name -> v1.Component - 74, // 89: v1.ComponentDiff.field_diffs:type_name -> v1.FieldDiff - 22, // 90: v1.ComponentDiff.id:type_name -> v1.UUID - 29, // 91: v1.AddComponentRequest.component:type_name -> v1.Component - 29, // 92: v1.AddComponentResponse.component:type_name -> v1.Component - 22, // 93: v1.DeleteComponentRequest.id:type_name -> v1.UUID - 22, // 94: v1.DeleteRackRequest.id:type_name -> v1.UUID - 22, // 95: v1.PurgeRackRequest.id:type_name -> v1.UUID - 22, // 96: v1.PurgeComponentRequest.id:type_name -> v1.UUID - 22, // 97: v1.PatchComponentRequest.id:type_name -> v1.UUID - 27, // 98: v1.PatchComponentRequest.position:type_name -> v1.RackPosition - 22, // 99: v1.PatchComponentRequest.rack_id:type_name -> v1.UUID - 26, // 100: v1.PatchComponentRequest.bmcs:type_name -> v1.BMCInfo - 29, // 101: v1.PatchComponentResponse.component:type_name -> v1.Component - 22, // 102: v1.SubmitTaskResponse.task_ids:type_name -> v1.UUID - 12, // 103: v1.QueueOptions.conflict_strategy:type_name -> v1.ConflictStrategy - 32, // 104: v1.PowerOnRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 105: v1.PowerOnRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 106: v1.PowerOnRackRequest.rule_id:type_name -> v1.UUID - 32, // 107: v1.PowerOffRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 108: v1.PowerOffRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 109: v1.PowerOffRackRequest.rule_id:type_name -> v1.UUID - 32, // 110: v1.PowerResetRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 88, // 111: v1.PowerResetRackRequest.queue_options:type_name -> v1.QueueOptions - 22, // 112: v1.PowerResetRackRequest.rule_id:type_name -> v1.UUID - 32, // 113: v1.BringUpRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 22, // 114: v1.BringUpRackRequest.rule_id:type_name -> v1.UUID - 32, // 115: v1.IngestRackRequest.target_spec:type_name -> v1.OperationTargetSpec - 45, // 116: v1.IngestRackRequest.filters:type_name -> v1.Filter - 22, // 117: v1.IngestRackRequest.rule_id:type_name -> v1.UUID - 22, // 118: v1.ListTasksRequest.rack_id:type_name -> v1.UUID - 43, // 119: v1.ListTasksRequest.pagination:type_name -> v1.Pagination - 22, // 120: v1.ListTasksRequest.component_id:type_name -> v1.UUID - 47, // 121: v1.ListTasksResponse.tasks:type_name -> v1.Task - 22, // 122: v1.GetTasksByIDsRequest.task_ids:type_name -> v1.UUID - 47, // 123: v1.GetTasksByIDsResponse.tasks:type_name -> v1.Task - 22, // 124: v1.CancelTaskRequest.task_id:type_name -> v1.UUID - 47, // 125: v1.CancelTaskResponse.task:type_name -> v1.Task - 22, // 126: v1.OperationRule.id:type_name -> v1.UUID - 13, // 127: v1.OperationRule.operation_type:type_name -> v1.OperationType - 185, // 128: v1.OperationRule.created_at:type_name -> google.protobuf.Timestamp - 185, // 129: v1.OperationRule.updated_at:type_name -> google.protobuf.Timestamp - 13, // 130: v1.CreateOperationRuleRequest.operation_type:type_name -> v1.OperationType - 22, // 131: v1.CreateOperationRuleResponse.id:type_name -> v1.UUID - 22, // 132: v1.UpdateOperationRuleRequest.rule_id:type_name -> v1.UUID - 22, // 133: v1.DeleteOperationRuleRequest.rule_id:type_name -> v1.UUID - 22, // 134: v1.SetRuleAsDefaultRequest.rule_id:type_name -> v1.UUID - 22, // 135: v1.GetOperationRuleRequest.rule_id:type_name -> v1.UUID - 13, // 136: v1.ListOperationRulesRequest.operation_type:type_name -> v1.OperationType - 102, // 137: v1.ListOperationRulesResponse.rules:type_name -> v1.OperationRule - 22, // 138: v1.AssociateRuleWithRackRequest.rack_id:type_name -> v1.UUID - 22, // 139: v1.AssociateRuleWithRackRequest.rule_id:type_name -> v1.UUID - 22, // 140: v1.DisassociateRuleFromRackRequest.rack_id:type_name -> v1.UUID - 13, // 141: v1.DisassociateRuleFromRackRequest.operation_type:type_name -> v1.OperationType - 22, // 142: v1.GetRackRuleAssociationRequest.rack_id:type_name -> v1.UUID - 13, // 143: v1.GetRackRuleAssociationRequest.operation_type:type_name -> v1.OperationType - 22, // 144: v1.GetRackRuleAssociationResponse.rule_id:type_name -> v1.UUID - 22, // 145: v1.ListRackRuleAssociationsRequest.rack_id:type_name -> v1.UUID - 22, // 146: v1.RackRuleAssociation.rack_id:type_name -> v1.UUID - 13, // 147: v1.RackRuleAssociation.operation_type:type_name -> v1.OperationType - 22, // 148: v1.RackRuleAssociation.rule_id:type_name -> v1.UUID - 185, // 149: v1.RackRuleAssociation.created_at:type_name -> google.protobuf.Timestamp - 185, // 150: v1.RackRuleAssociation.updated_at:type_name -> google.protobuf.Timestamp - 116, // 151: v1.ListRackRuleAssociationsResponse.associations:type_name -> v1.RackRuleAssociation - 14, // 152: v1.ScheduleSpec.type:type_name -> v1.ScheduleSpecType - 118, // 153: v1.ScheduleConfig.spec:type_name -> v1.ScheduleSpec - 15, // 154: v1.ScheduleConfig.overlap_policy:type_name -> v1.OverlapPolicy - 22, // 155: v1.TaskSchedule.id:type_name -> v1.UUID - 118, // 156: v1.TaskSchedule.spec:type_name -> v1.ScheduleSpec - 15, // 157: v1.TaskSchedule.overlap_policy:type_name -> v1.OverlapPolicy - 185, // 158: v1.TaskSchedule.next_run_at:type_name -> google.protobuf.Timestamp - 185, // 159: v1.TaskSchedule.last_run_at:type_name -> google.protobuf.Timestamp - 185, // 160: v1.TaskSchedule.created_at:type_name -> google.protobuf.Timestamp - 185, // 161: v1.TaskSchedule.updated_at:type_name -> google.protobuf.Timestamp - 89, // 162: v1.ScheduledOperation.power_on:type_name -> v1.PowerOnRackRequest - 90, // 163: v1.ScheduledOperation.power_off:type_name -> v1.PowerOffRackRequest - 91, // 164: v1.ScheduledOperation.power_reset:type_name -> v1.PowerResetRackRequest - 92, // 165: v1.ScheduledOperation.bring_up:type_name -> v1.BringUpRackRequest - 68, // 166: v1.ScheduledOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest - 93, // 167: v1.ScheduledOperation.ingest:type_name -> v1.IngestRackRequest - 119, // 168: v1.CreateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig - 121, // 169: v1.CreateTaskScheduleRequest.operation:type_name -> v1.ScheduledOperation - 22, // 170: v1.GetTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 171: v1.ListTaskSchedulesRequest.rack_id:type_name -> v1.UUID - 43, // 172: v1.ListTaskSchedulesRequest.pagination:type_name -> v1.Pagination - 120, // 173: v1.ListTaskSchedulesResponse.task_schedules:type_name -> v1.TaskSchedule - 22, // 174: v1.UpdateTaskScheduleRequest.id:type_name -> v1.UUID - 119, // 175: v1.UpdateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig - 186, // 176: v1.UpdateTaskScheduleRequest.update_mask:type_name -> google.protobuf.FieldMask - 22, // 177: v1.PauseTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 178: v1.ResumeTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 179: v1.DeleteTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 180: v1.TriggerTaskScheduleRequest.id:type_name -> v1.UUID - 22, // 181: v1.TaskScheduleScope.id:type_name -> v1.UUID - 22, // 182: v1.TaskScheduleScope.schedule_id:type_name -> v1.UUID - 22, // 183: v1.TaskScheduleScope.rack_id:type_name -> v1.UUID - 35, // 184: v1.TaskScheduleScope.types:type_name -> v1.ComponentTypes - 34, // 185: v1.TaskScheduleScope.components:type_name -> v1.ComponentTargets - 22, // 186: v1.TaskScheduleScope.last_task_id:type_name -> v1.UUID - 185, // 187: v1.TaskScheduleScope.created_at:type_name -> google.protobuf.Timestamp - 22, // 188: v1.AddTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID - 32, // 189: v1.AddTaskScheduleScopeRequest.target_spec:type_name -> v1.OperationTargetSpec - 131, // 190: v1.AddTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope - 22, // 191: v1.RemoveTaskScheduleScopeRequest.scope_id:type_name -> v1.UUID - 22, // 192: v1.UpdateTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID - 32, // 193: v1.UpdateTaskScheduleScopeRequest.desired_scope:type_name -> v1.OperationTargetSpec - 131, // 194: v1.UpdateTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope - 22, // 195: v1.ListTaskScheduleScopesRequest.schedule_id:type_name -> v1.UUID - 131, // 196: v1.ListTaskScheduleScopesResponse.scopes:type_name -> v1.TaskScheduleScope - 121, // 197: v1.CheckScheduleConflictsRequest.operation:type_name -> v1.ScheduledOperation - 22, // 198: v1.CheckScheduleConflictsRequest.exclude_schedule_id:type_name -> v1.UUID - 120, // 199: v1.CheckScheduleConflictsResponse.conflicts:type_name -> v1.TaskSchedule - 143, // 200: v1.CreateOperationRunRequest.configuration:type_name -> v1.OperationRunConfiguration - 22, // 201: v1.CreateOperationRunResponse.id:type_name -> v1.UUID - 156, // 202: v1.OperationRunConfiguration.selector:type_name -> v1.OperationRunSelector - 158, // 203: v1.OperationRunConfiguration.options:type_name -> v1.OperationRunOptions - 176, // 204: v1.OperationRunConfiguration.operation:type_name -> v1.OperationRunOperation - 22, // 205: v1.GetOperationRunRequest.id:type_name -> v1.UUID - 179, // 206: v1.GetOperationRunResponse.operation_run:type_name -> v1.OperationRun - 148, // 207: v1.ListOperationRunsRequest.filter:type_name -> v1.OperationRunFilter - 43, // 208: v1.ListOperationRunsRequest.pagination:type_name -> v1.Pagination - 180, // 209: v1.ListOperationRunsResponse.operation_runs:type_name -> v1.OperationRunSummary - 44, // 210: v1.OperationRunFilter.name:type_name -> v1.StringQueryInfo - 149, // 211: v1.OperationRunFilter.states:type_name -> v1.OperationRunStateFilter - 178, // 212: v1.OperationRunFilter.operation_kinds:type_name -> v1.OperationKind - 18, // 213: v1.OperationRunStateFilter.status:type_name -> v1.OperationRunStatus - 19, // 214: v1.OperationRunStateFilter.reason:type_name -> v1.OperationRunStatusReason - 22, // 215: v1.ListOperationRunTargetsRequest.operation_run_id:type_name -> v1.UUID - 20, // 216: v1.ListOperationRunTargetsRequest.status:type_name -> v1.OperationRunTargetStatus - 43, // 217: v1.ListOperationRunTargetsRequest.pagination:type_name -> v1.Pagination - 16, // 218: v1.ListOperationRunTargetsRequest.phase_scope:type_name -> v1.OperationRunTargetPhaseScope - 184, // 219: v1.ListOperationRunTargetsResponse.targets:type_name -> v1.OperationRunTarget - 22, // 220: v1.PauseOperationRunRequest.id:type_name -> v1.UUID - 22, // 221: v1.ResumeOperationRunRequest.id:type_name -> v1.UUID - 22, // 222: v1.AdvanceOperationRunPhaseRequest.id:type_name -> v1.UUID - 22, // 223: v1.CancelOperationRunRequest.id:type_name -> v1.UUID - 157, // 224: v1.OperationRunSelector.percentage:type_name -> v1.PercentageSelector - 159, // 225: v1.OperationRunOptions.safety_policy:type_name -> v1.OperationRunSafetyPolicy - 173, // 226: v1.OperationRunOptions.conflict_policy:type_name -> v1.OperationRunConflictPolicy - 163, // 227: v1.OperationRunOptions.ordering_policy:type_name -> v1.OperationRunOrderingPolicy - 166, // 228: v1.OperationRunOptions.phase_policy:type_name -> v1.OperationRunPhasePolicy - 160, // 229: v1.OperationRunSafetyPolicy.gates:type_name -> v1.OperationRunSafetyGate - 161, // 230: v1.OperationRunSafetyGate.failure_rate:type_name -> v1.OperationRunFailureRateGate - 162, // 231: v1.OperationRunSafetyGate.failure_count:type_name -> v1.OperationRunFailureCountGate - 17, // 232: v1.OperationRunFailureRateGate.scope:type_name -> v1.OperationRunSafetyGateScope - 17, // 233: v1.OperationRunFailureCountGate.scope:type_name -> v1.OperationRunSafetyGateScope - 164, // 234: v1.OperationRunOrderingPolicy.random:type_name -> v1.OperationRunRandomOrdering - 165, // 235: v1.OperationRunOrderingPolicy.physical_location:type_name -> v1.OperationRunPhysicalLocationOrdering - 21, // 236: v1.OperationRunPhysicalLocationOrdering.strategy:type_name -> v1.OperationRunPhysicalLocationOrdering.Strategy - 167, // 237: v1.OperationRunPhasePolicy.equal:type_name -> v1.EqualOperationRunPhases - 168, // 238: v1.OperationRunPhasePolicy.percentage:type_name -> v1.PercentageOperationRunPhases - 170, // 239: v1.OperationRunPhasePolicy.count:type_name -> v1.CountOperationRunPhases - 172, // 240: v1.OperationRunPhasePolicy.advance_policy:type_name -> v1.OperationRunPhaseAdvancePolicy - 169, // 241: v1.PercentageOperationRunPhases.phases:type_name -> v1.OperationRunPercentagePhase - 171, // 242: v1.CountOperationRunPhases.phases:type_name -> v1.OperationRunCountPhase - 174, // 243: v1.OperationRunConflictPolicy.retry:type_name -> v1.OperationRunConflictRetryPolicy - 187, // 244: v1.OperationRunConflictRetryPolicy.retry_timeout:type_name -> google.protobuf.Duration - 187, // 245: v1.OperationRunConflictRetryPolicy.initial_retry_delay:type_name -> google.protobuf.Duration - 187, // 246: v1.OperationRunConflictRetryPolicy.max_retry_delay:type_name -> google.protobuf.Duration - 22, // 247: v1.OperationRunTargetScope.exclude_operation_run_ids:type_name -> v1.UUID - 36, // 248: v1.OperationRunTargetScope.default_scope_component_filter:type_name -> v1.ComponentFilter - 68, // 249: v1.OperationRunOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest - 175, // 250: v1.OperationRunOperation.target_scope:type_name -> v1.OperationRunTargetScope - 18, // 251: v1.OperationRunState.status:type_name -> v1.OperationRunStatus - 19, // 252: v1.OperationRunState.reason:type_name -> v1.OperationRunStatusReason - 13, // 253: v1.OperationKind.type:type_name -> v1.OperationType - 180, // 254: v1.OperationRun.summary:type_name -> v1.OperationRunSummary - 143, // 255: v1.OperationRun.configuration:type_name -> v1.OperationRunConfiguration - 181, // 256: v1.OperationRun.stats:type_name -> v1.OperationRunStats - 22, // 257: v1.OperationRunSummary.id:type_name -> v1.UUID - 178, // 258: v1.OperationRunSummary.operation_kind:type_name -> v1.OperationKind - 177, // 259: v1.OperationRunSummary.state:type_name -> v1.OperationRunState - 185, // 260: v1.OperationRunSummary.created_at:type_name -> google.protobuf.Timestamp - 185, // 261: v1.OperationRunSummary.updated_at:type_name -> google.protobuf.Timestamp - 185, // 262: v1.OperationRunSummary.started_at:type_name -> google.protobuf.Timestamp - 185, // 263: v1.OperationRunSummary.finished_at:type_name -> google.protobuf.Timestamp - 182, // 264: v1.OperationRunStats.current_phase_stats:type_name -> v1.OperationRunPhaseStats - 182, // 265: v1.OperationRunStats.cumulative_phase_stats:type_name -> v1.OperationRunPhaseStats - 183, // 266: v1.OperationRunPhaseStats.outcome_counts:type_name -> v1.OperationRunTargetOutcomeCounts - 22, // 267: v1.OperationRunTarget.id:type_name -> v1.UUID - 22, // 268: v1.OperationRunTarget.operation_run_id:type_name -> v1.UUID - 22, // 269: v1.OperationRunTarget.rack_id:type_name -> v1.UUID - 22, // 270: v1.OperationRunTarget.task_id:type_name -> v1.UUID - 20, // 271: v1.OperationRunTarget.status:type_name -> v1.OperationRunTargetStatus - 37, // 272: v1.OperationRunTarget.components_by_type:type_name -> v1.ComponentsByType - 185, // 273: v1.OperationRunTarget.created_at:type_name -> google.protobuf.Timestamp - 185, // 274: v1.OperationRunTarget.updated_at:type_name -> google.protobuf.Timestamp - 100, // 275: v1.Flow.Version:input_type -> v1.VersionRequest - 122, // 276: v1.Flow.CreateTaskSchedule:input_type -> v1.CreateTaskScheduleRequest - 123, // 277: v1.Flow.GetTaskSchedule:input_type -> v1.GetTaskScheduleRequest - 124, // 278: v1.Flow.ListTaskSchedules:input_type -> v1.ListTaskSchedulesRequest - 126, // 279: v1.Flow.UpdateTaskSchedule:input_type -> v1.UpdateTaskScheduleRequest - 127, // 280: v1.Flow.PauseTaskSchedule:input_type -> v1.PauseTaskScheduleRequest - 128, // 281: v1.Flow.ResumeTaskSchedule:input_type -> v1.ResumeTaskScheduleRequest - 129, // 282: v1.Flow.DeleteTaskSchedule:input_type -> v1.DeleteTaskScheduleRequest - 130, // 283: v1.Flow.TriggerTaskSchedule:input_type -> v1.TriggerTaskScheduleRequest - 132, // 284: v1.Flow.AddTaskScheduleScope:input_type -> v1.AddTaskScheduleScopeRequest - 134, // 285: v1.Flow.RemoveTaskScheduleScope:input_type -> v1.RemoveTaskScheduleScopeRequest - 135, // 286: v1.Flow.UpdateTaskScheduleScope:input_type -> v1.UpdateTaskScheduleScopeRequest - 137, // 287: v1.Flow.ListTaskScheduleScopes:input_type -> v1.ListTaskScheduleScopesRequest - 139, // 288: v1.Flow.CheckScheduleConflicts:input_type -> v1.CheckScheduleConflictsRequest - 48, // 289: v1.Flow.CreateExpectedRack:input_type -> v1.CreateExpectedRackRequest - 50, // 290: v1.Flow.GetRackInfoByID:input_type -> v1.GetRackInfoByIDRequest - 51, // 291: v1.Flow.GetRackInfoBySerial:input_type -> v1.GetRackInfoBySerialRequest - 58, // 292: v1.Flow.GetListOfRacks:input_type -> v1.GetListOfRacksRequest - 53, // 293: v1.Flow.PatchRack:input_type -> v1.PatchRackRequest - 79, // 294: v1.Flow.DeleteRack:input_type -> v1.DeleteRackRequest - 81, // 295: v1.Flow.PurgeRack:input_type -> v1.PurgeRackRequest - 68, // 296: v1.Flow.UpgradeFirmware:input_type -> v1.UpgradeFirmwareRequest - 92, // 297: v1.Flow.BringUpRack:input_type -> v1.BringUpRackRequest - 93, // 298: v1.Flow.IngestRack:input_type -> v1.IngestRackRequest - 89, // 299: v1.Flow.PowerOnRack:input_type -> v1.PowerOnRackRequest - 90, // 300: v1.Flow.PowerOffRack:input_type -> v1.PowerOffRackRequest - 91, // 301: v1.Flow.PowerResetRack:input_type -> v1.PowerResetRackRequest - 55, // 302: v1.Flow.GetComponentInfoByID:input_type -> v1.GetComponentInfoByIDRequest - 56, // 303: v1.Flow.GetComponentInfoBySerial:input_type -> v1.GetComponentInfoBySerialRequest - 69, // 304: v1.Flow.GetComponents:input_type -> v1.GetComponentsRequest - 71, // 305: v1.Flow.ValidateComponents:input_type -> v1.ValidateComponentsRequest - 75, // 306: v1.Flow.AddComponent:input_type -> v1.AddComponentRequest - 85, // 307: v1.Flow.PatchComponent:input_type -> v1.PatchComponentRequest - 77, // 308: v1.Flow.DeleteComponent:input_type -> v1.DeleteComponentRequest - 83, // 309: v1.Flow.PurgeComponent:input_type -> v1.PurgeComponentRequest - 60, // 310: v1.Flow.CreateNVLDomain:input_type -> v1.CreateNVLDomainRequest - 62, // 311: v1.Flow.AttachRacksToNVLDomain:input_type -> v1.AttachRacksToNVLDomainRequest - 63, // 312: v1.Flow.DetachRacksFromNVLDomain:input_type -> v1.DetachRacksFromNVLDomainRequest - 64, // 313: v1.Flow.GetListOfNVLDomains:input_type -> v1.GetListOfNVLDomainsRequest - 66, // 314: v1.Flow.GetRacksForNVLDomain:input_type -> v1.GetRacksForNVLDomainRequest - 94, // 315: v1.Flow.ListTasks:input_type -> v1.ListTasksRequest - 96, // 316: v1.Flow.GetTasksByIDs:input_type -> v1.GetTasksByIDsRequest - 98, // 317: v1.Flow.CancelTask:input_type -> v1.CancelTaskRequest - 103, // 318: v1.Flow.CreateOperationRule:input_type -> v1.CreateOperationRuleRequest - 105, // 319: v1.Flow.UpdateOperationRule:input_type -> v1.UpdateOperationRuleRequest - 106, // 320: v1.Flow.DeleteOperationRule:input_type -> v1.DeleteOperationRuleRequest - 108, // 321: v1.Flow.GetOperationRule:input_type -> v1.GetOperationRuleRequest - 109, // 322: v1.Flow.ListOperationRules:input_type -> v1.ListOperationRulesRequest - 107, // 323: v1.Flow.SetRuleAsDefault:input_type -> v1.SetRuleAsDefaultRequest - 111, // 324: v1.Flow.AssociateRuleWithRack:input_type -> v1.AssociateRuleWithRackRequest - 112, // 325: v1.Flow.DisassociateRuleFromRack:input_type -> v1.DisassociateRuleFromRackRequest - 113, // 326: v1.Flow.GetRackRuleAssociation:input_type -> v1.GetRackRuleAssociationRequest - 115, // 327: v1.Flow.ListRackRuleAssociations:input_type -> v1.ListRackRuleAssociationsRequest - 141, // 328: v1.Flow.CreateOperationRun:input_type -> v1.CreateOperationRunRequest - 144, // 329: v1.Flow.GetOperationRun:input_type -> v1.GetOperationRunRequest - 146, // 330: v1.Flow.ListOperationRuns:input_type -> v1.ListOperationRunsRequest - 150, // 331: v1.Flow.ListOperationRunTargets:input_type -> v1.ListOperationRunTargetsRequest - 152, // 332: v1.Flow.PauseOperationRun:input_type -> v1.PauseOperationRunRequest - 153, // 333: v1.Flow.ResumeOperationRun:input_type -> v1.ResumeOperationRunRequest - 154, // 334: v1.Flow.AdvanceOperationRunPhase:input_type -> v1.AdvanceOperationRunPhaseRequest - 155, // 335: v1.Flow.CancelOperationRun:input_type -> v1.CancelOperationRunRequest - 101, // 336: v1.Flow.Version:output_type -> v1.BuildInfo - 120, // 337: v1.Flow.CreateTaskSchedule:output_type -> v1.TaskSchedule - 120, // 338: v1.Flow.GetTaskSchedule:output_type -> v1.TaskSchedule - 125, // 339: v1.Flow.ListTaskSchedules:output_type -> v1.ListTaskSchedulesResponse - 120, // 340: v1.Flow.UpdateTaskSchedule:output_type -> v1.TaskSchedule - 120, // 341: v1.Flow.PauseTaskSchedule:output_type -> v1.TaskSchedule - 120, // 342: v1.Flow.ResumeTaskSchedule:output_type -> v1.TaskSchedule - 188, // 343: v1.Flow.DeleteTaskSchedule:output_type -> google.protobuf.Empty - 87, // 344: v1.Flow.TriggerTaskSchedule:output_type -> v1.SubmitTaskResponse - 133, // 345: v1.Flow.AddTaskScheduleScope:output_type -> v1.AddTaskScheduleScopeResponse - 188, // 346: v1.Flow.RemoveTaskScheduleScope:output_type -> google.protobuf.Empty - 136, // 347: v1.Flow.UpdateTaskScheduleScope:output_type -> v1.UpdateTaskScheduleScopeResponse - 138, // 348: v1.Flow.ListTaskScheduleScopes:output_type -> v1.ListTaskScheduleScopesResponse - 140, // 349: v1.Flow.CheckScheduleConflicts:output_type -> v1.CheckScheduleConflictsResponse - 49, // 350: v1.Flow.CreateExpectedRack:output_type -> v1.CreateExpectedRackResponse - 52, // 351: v1.Flow.GetRackInfoByID:output_type -> v1.GetRackInfoResponse - 52, // 352: v1.Flow.GetRackInfoBySerial:output_type -> v1.GetRackInfoResponse - 59, // 353: v1.Flow.GetListOfRacks:output_type -> v1.GetListOfRacksResponse - 54, // 354: v1.Flow.PatchRack:output_type -> v1.PatchRackResponse - 80, // 355: v1.Flow.DeleteRack:output_type -> v1.DeleteRackResponse - 82, // 356: v1.Flow.PurgeRack:output_type -> v1.PurgeRackResponse - 87, // 357: v1.Flow.UpgradeFirmware:output_type -> v1.SubmitTaskResponse - 87, // 358: v1.Flow.BringUpRack:output_type -> v1.SubmitTaskResponse - 87, // 359: v1.Flow.IngestRack:output_type -> v1.SubmitTaskResponse - 87, // 360: v1.Flow.PowerOnRack:output_type -> v1.SubmitTaskResponse - 87, // 361: v1.Flow.PowerOffRack:output_type -> v1.SubmitTaskResponse - 87, // 362: v1.Flow.PowerResetRack:output_type -> v1.SubmitTaskResponse - 57, // 363: v1.Flow.GetComponentInfoByID:output_type -> v1.GetComponentInfoResponse - 57, // 364: v1.Flow.GetComponentInfoBySerial:output_type -> v1.GetComponentInfoResponse - 70, // 365: v1.Flow.GetComponents:output_type -> v1.GetComponentsResponse - 72, // 366: v1.Flow.ValidateComponents:output_type -> v1.ValidateComponentsResponse - 76, // 367: v1.Flow.AddComponent:output_type -> v1.AddComponentResponse - 86, // 368: v1.Flow.PatchComponent:output_type -> v1.PatchComponentResponse - 78, // 369: v1.Flow.DeleteComponent:output_type -> v1.DeleteComponentResponse - 84, // 370: v1.Flow.PurgeComponent:output_type -> v1.PurgeComponentResponse - 61, // 371: v1.Flow.CreateNVLDomain:output_type -> v1.CreateNVLDomainResponse - 188, // 372: v1.Flow.AttachRacksToNVLDomain:output_type -> google.protobuf.Empty - 188, // 373: v1.Flow.DetachRacksFromNVLDomain:output_type -> google.protobuf.Empty - 65, // 374: v1.Flow.GetListOfNVLDomains:output_type -> v1.GetListOfNVLDomainsResponse - 67, // 375: v1.Flow.GetRacksForNVLDomain:output_type -> v1.GetRacksForNVLDomainResponse - 95, // 376: v1.Flow.ListTasks:output_type -> v1.ListTasksResponse - 97, // 377: v1.Flow.GetTasksByIDs:output_type -> v1.GetTasksByIDsResponse - 99, // 378: v1.Flow.CancelTask:output_type -> v1.CancelTaskResponse - 104, // 379: v1.Flow.CreateOperationRule:output_type -> v1.CreateOperationRuleResponse - 188, // 380: v1.Flow.UpdateOperationRule:output_type -> google.protobuf.Empty - 188, // 381: v1.Flow.DeleteOperationRule:output_type -> google.protobuf.Empty - 102, // 382: v1.Flow.GetOperationRule:output_type -> v1.OperationRule - 110, // 383: v1.Flow.ListOperationRules:output_type -> v1.ListOperationRulesResponse - 188, // 384: v1.Flow.SetRuleAsDefault:output_type -> google.protobuf.Empty - 188, // 385: v1.Flow.AssociateRuleWithRack:output_type -> google.protobuf.Empty - 188, // 386: v1.Flow.DisassociateRuleFromRack:output_type -> google.protobuf.Empty - 114, // 387: v1.Flow.GetRackRuleAssociation:output_type -> v1.GetRackRuleAssociationResponse - 117, // 388: v1.Flow.ListRackRuleAssociations:output_type -> v1.ListRackRuleAssociationsResponse - 142, // 389: v1.Flow.CreateOperationRun:output_type -> v1.CreateOperationRunResponse - 145, // 390: v1.Flow.GetOperationRun:output_type -> v1.GetOperationRunResponse - 147, // 391: v1.Flow.ListOperationRuns:output_type -> v1.ListOperationRunsResponse - 151, // 392: v1.Flow.ListOperationRunTargets:output_type -> v1.ListOperationRunTargetsResponse - 179, // 393: v1.Flow.PauseOperationRun:output_type -> v1.OperationRun - 179, // 394: v1.Flow.ResumeOperationRun:output_type -> v1.OperationRun - 179, // 395: v1.Flow.AdvanceOperationRunPhase:output_type -> v1.OperationRun - 179, // 396: v1.Flow.CancelOperationRun:output_type -> v1.OperationRun - 336, // [336:397] is the sub-list for method output_type - 275, // [275:336] is the sub-list for method input_type - 275, // [275:275] is the sub-list for extension type_name - 275, // [275:275] is the sub-list for extension extendee - 0, // [0:275] is the sub-list for field type_name + 185, // 17: v1.OperationTargetSpec.nvl_domains:type_name -> v1.NVLDomainTargets + 39, // 18: v1.RackTargets.targets:type_name -> v1.RackTarget + 40, // 19: v1.ComponentTargets.targets:type_name -> v1.ComponentTarget + 1, // 20: v1.ComponentTypes.types:type_name -> v1.ComponentType + 35, // 21: v1.ComponentFilter.types:type_name -> v1.ComponentTypes + 34, // 22: v1.ComponentFilter.components:type_name -> v1.ComponentTargets + 38, // 23: v1.ComponentsByType.groups:type_name -> v1.ComponentsForType + 1, // 24: v1.ComponentsForType.type:type_name -> v1.ComponentType + 22, // 25: v1.ComponentsForType.component_ids:type_name -> v1.UUID + 22, // 26: v1.RackTarget.id:type_name -> v1.UUID + 1, // 27: v1.RackTarget.component_types:type_name -> v1.ComponentType + 22, // 28: v1.ComponentTarget.id:type_name -> v1.UUID + 41, // 29: v1.ComponentTarget.external:type_name -> v1.ExternalRef + 1, // 30: v1.ExternalRef.type:type_name -> v1.ComponentType + 31, // 31: v1.NVLDomain.identifier:type_name -> v1.Identifier + 2, // 32: v1.Filter.rack_field:type_name -> v1.RackFilterField + 3, // 33: v1.Filter.component_field:type_name -> v1.ComponentFilterField + 44, // 34: v1.Filter.query_info:type_name -> v1.StringQueryInfo + 5, // 35: v1.OrderBy.rack_field:type_name -> v1.RackOrderByField + 4, // 36: v1.OrderBy.component_field:type_name -> v1.ComponentOrderByField + 22, // 37: v1.Task.id:type_name -> v1.UUID + 22, // 38: v1.Task.rack_id:type_name -> v1.UUID + 22, // 39: v1.Task.component_uuids:type_name -> v1.UUID + 8, // 40: v1.Task.executor_type:type_name -> v1.TaskExecutorType + 7, // 41: v1.Task.status:type_name -> v1.TaskStatus + 187, // 42: v1.Task.queue_expires_at:type_name -> google.protobuf.Timestamp + 187, // 43: v1.Task.created_at:type_name -> google.protobuf.Timestamp + 187, // 44: v1.Task.finished_at:type_name -> google.protobuf.Timestamp + 22, // 45: v1.Task.applied_rule_id:type_name -> v1.UUID + 187, // 46: v1.Task.updated_at:type_name -> google.protobuf.Timestamp + 187, // 47: v1.Task.started_at:type_name -> google.protobuf.Timestamp + 30, // 48: v1.CreateExpectedRackRequest.rack:type_name -> v1.Rack + 22, // 49: v1.CreateExpectedRackResponse.id:type_name -> v1.UUID + 22, // 50: v1.GetRackInfoByIDRequest.id:type_name -> v1.UUID + 25, // 51: v1.GetRackInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo + 30, // 52: v1.GetRackInfoResponse.rack:type_name -> v1.Rack + 30, // 53: v1.PatchRackRequest.rack:type_name -> v1.Rack + 22, // 54: v1.GetComponentInfoByIDRequest.id:type_name -> v1.UUID + 25, // 55: v1.GetComponentInfoBySerialRequest.serial_info:type_name -> v1.DeviceSerialInfo + 29, // 56: v1.GetComponentInfoResponse.component:type_name -> v1.Component + 30, // 57: v1.GetComponentInfoResponse.rack:type_name -> v1.Rack + 45, // 58: v1.GetListOfRacksRequest.filters:type_name -> v1.Filter + 43, // 59: v1.GetListOfRacksRequest.pagination:type_name -> v1.Pagination + 46, // 60: v1.GetListOfRacksRequest.order_by:type_name -> v1.OrderBy + 30, // 61: v1.GetListOfRacksResponse.racks:type_name -> v1.Rack + 42, // 62: v1.CreateNVLDomainRequest.nvl_domain:type_name -> v1.NVLDomain + 22, // 63: v1.CreateNVLDomainResponse.id:type_name -> v1.UUID + 31, // 64: v1.AttachRacksToNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier + 31, // 65: v1.AttachRacksToNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier + 31, // 66: v1.DetachRacksFromNVLDomainRequest.rack_identifiers:type_name -> v1.Identifier + 44, // 67: v1.GetListOfNVLDomainsRequest.info:type_name -> v1.StringQueryInfo + 43, // 68: v1.GetListOfNVLDomainsRequest.pagination:type_name -> v1.Pagination + 42, // 69: v1.GetListOfNVLDomainsResponse.nvl_domains:type_name -> v1.NVLDomain + 31, // 70: v1.GetRacksForNVLDomainRequest.nvl_domain_identifier:type_name -> v1.Identifier + 30, // 71: v1.GetRacksForNVLDomainResponse.racks:type_name -> v1.Rack + 32, // 72: v1.UpgradeFirmwareRequest.target_spec:type_name -> v1.OperationTargetSpec + 187, // 73: v1.UpgradeFirmwareRequest.start_time:type_name -> google.protobuf.Timestamp + 187, // 74: v1.UpgradeFirmwareRequest.end_time:type_name -> google.protobuf.Timestamp + 88, // 75: v1.UpgradeFirmwareRequest.queue_options:type_name -> v1.QueueOptions + 22, // 76: v1.UpgradeFirmwareRequest.rule_id:type_name -> v1.UUID + 32, // 77: v1.GetComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 78: v1.GetComponentsRequest.filters:type_name -> v1.Filter + 43, // 79: v1.GetComponentsRequest.pagination:type_name -> v1.Pagination + 46, // 80: v1.GetComponentsRequest.order_by:type_name -> v1.OrderBy + 29, // 81: v1.GetComponentsResponse.components:type_name -> v1.Component + 32, // 82: v1.ValidateComponentsRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 83: v1.ValidateComponentsRequest.filters:type_name -> v1.Filter + 43, // 84: v1.ValidateComponentsRequest.pagination:type_name -> v1.Pagination + 46, // 85: v1.ValidateComponentsRequest.order_by:type_name -> v1.OrderBy + 73, // 86: v1.ValidateComponentsResponse.diffs:type_name -> v1.ComponentDiff + 11, // 87: v1.ComponentDiff.type:type_name -> v1.DiffType + 29, // 88: v1.ComponentDiff.expected:type_name -> v1.Component + 29, // 89: v1.ComponentDiff.actual:type_name -> v1.Component + 74, // 90: v1.ComponentDiff.field_diffs:type_name -> v1.FieldDiff + 22, // 91: v1.ComponentDiff.id:type_name -> v1.UUID + 29, // 92: v1.AddComponentRequest.component:type_name -> v1.Component + 29, // 93: v1.AddComponentResponse.component:type_name -> v1.Component + 22, // 94: v1.DeleteComponentRequest.id:type_name -> v1.UUID + 22, // 95: v1.DeleteRackRequest.id:type_name -> v1.UUID + 22, // 96: v1.PurgeRackRequest.id:type_name -> v1.UUID + 22, // 97: v1.PurgeComponentRequest.id:type_name -> v1.UUID + 22, // 98: v1.PatchComponentRequest.id:type_name -> v1.UUID + 27, // 99: v1.PatchComponentRequest.position:type_name -> v1.RackPosition + 22, // 100: v1.PatchComponentRequest.rack_id:type_name -> v1.UUID + 26, // 101: v1.PatchComponentRequest.bmcs:type_name -> v1.BMCInfo + 29, // 102: v1.PatchComponentResponse.component:type_name -> v1.Component + 22, // 103: v1.SubmitTaskResponse.task_ids:type_name -> v1.UUID + 12, // 104: v1.QueueOptions.conflict_strategy:type_name -> v1.ConflictStrategy + 32, // 105: v1.PowerOnRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 106: v1.PowerOnRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 107: v1.PowerOnRackRequest.rule_id:type_name -> v1.UUID + 32, // 108: v1.PowerOffRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 109: v1.PowerOffRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 110: v1.PowerOffRackRequest.rule_id:type_name -> v1.UUID + 32, // 111: v1.PowerResetRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 88, // 112: v1.PowerResetRackRequest.queue_options:type_name -> v1.QueueOptions + 22, // 113: v1.PowerResetRackRequest.rule_id:type_name -> v1.UUID + 32, // 114: v1.BringUpRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 22, // 115: v1.BringUpRackRequest.rule_id:type_name -> v1.UUID + 32, // 116: v1.IngestRackRequest.target_spec:type_name -> v1.OperationTargetSpec + 45, // 117: v1.IngestRackRequest.filters:type_name -> v1.Filter + 22, // 118: v1.IngestRackRequest.rule_id:type_name -> v1.UUID + 22, // 119: v1.ListTasksRequest.rack_id:type_name -> v1.UUID + 43, // 120: v1.ListTasksRequest.pagination:type_name -> v1.Pagination + 22, // 121: v1.ListTasksRequest.component_id:type_name -> v1.UUID + 47, // 122: v1.ListTasksResponse.tasks:type_name -> v1.Task + 22, // 123: v1.GetTasksByIDsRequest.task_ids:type_name -> v1.UUID + 47, // 124: v1.GetTasksByIDsResponse.tasks:type_name -> v1.Task + 22, // 125: v1.CancelTaskRequest.task_id:type_name -> v1.UUID + 47, // 126: v1.CancelTaskResponse.task:type_name -> v1.Task + 22, // 127: v1.OperationRule.id:type_name -> v1.UUID + 13, // 128: v1.OperationRule.operation_type:type_name -> v1.OperationType + 187, // 129: v1.OperationRule.created_at:type_name -> google.protobuf.Timestamp + 187, // 130: v1.OperationRule.updated_at:type_name -> google.protobuf.Timestamp + 13, // 131: v1.CreateOperationRuleRequest.operation_type:type_name -> v1.OperationType + 22, // 132: v1.CreateOperationRuleResponse.id:type_name -> v1.UUID + 22, // 133: v1.UpdateOperationRuleRequest.rule_id:type_name -> v1.UUID + 22, // 134: v1.DeleteOperationRuleRequest.rule_id:type_name -> v1.UUID + 22, // 135: v1.SetRuleAsDefaultRequest.rule_id:type_name -> v1.UUID + 22, // 136: v1.GetOperationRuleRequest.rule_id:type_name -> v1.UUID + 13, // 137: v1.ListOperationRulesRequest.operation_type:type_name -> v1.OperationType + 102, // 138: v1.ListOperationRulesResponse.rules:type_name -> v1.OperationRule + 22, // 139: v1.AssociateRuleWithRackRequest.rack_id:type_name -> v1.UUID + 22, // 140: v1.AssociateRuleWithRackRequest.rule_id:type_name -> v1.UUID + 22, // 141: v1.DisassociateRuleFromRackRequest.rack_id:type_name -> v1.UUID + 13, // 142: v1.DisassociateRuleFromRackRequest.operation_type:type_name -> v1.OperationType + 22, // 143: v1.GetRackRuleAssociationRequest.rack_id:type_name -> v1.UUID + 13, // 144: v1.GetRackRuleAssociationRequest.operation_type:type_name -> v1.OperationType + 22, // 145: v1.GetRackRuleAssociationResponse.rule_id:type_name -> v1.UUID + 22, // 146: v1.ListRackRuleAssociationsRequest.rack_id:type_name -> v1.UUID + 22, // 147: v1.RackRuleAssociation.rack_id:type_name -> v1.UUID + 13, // 148: v1.RackRuleAssociation.operation_type:type_name -> v1.OperationType + 22, // 149: v1.RackRuleAssociation.rule_id:type_name -> v1.UUID + 187, // 150: v1.RackRuleAssociation.created_at:type_name -> google.protobuf.Timestamp + 187, // 151: v1.RackRuleAssociation.updated_at:type_name -> google.protobuf.Timestamp + 116, // 152: v1.ListRackRuleAssociationsResponse.associations:type_name -> v1.RackRuleAssociation + 14, // 153: v1.ScheduleSpec.type:type_name -> v1.ScheduleSpecType + 118, // 154: v1.ScheduleConfig.spec:type_name -> v1.ScheduleSpec + 15, // 155: v1.ScheduleConfig.overlap_policy:type_name -> v1.OverlapPolicy + 22, // 156: v1.TaskSchedule.id:type_name -> v1.UUID + 118, // 157: v1.TaskSchedule.spec:type_name -> v1.ScheduleSpec + 15, // 158: v1.TaskSchedule.overlap_policy:type_name -> v1.OverlapPolicy + 187, // 159: v1.TaskSchedule.next_run_at:type_name -> google.protobuf.Timestamp + 187, // 160: v1.TaskSchedule.last_run_at:type_name -> google.protobuf.Timestamp + 187, // 161: v1.TaskSchedule.created_at:type_name -> google.protobuf.Timestamp + 187, // 162: v1.TaskSchedule.updated_at:type_name -> google.protobuf.Timestamp + 89, // 163: v1.ScheduledOperation.power_on:type_name -> v1.PowerOnRackRequest + 90, // 164: v1.ScheduledOperation.power_off:type_name -> v1.PowerOffRackRequest + 91, // 165: v1.ScheduledOperation.power_reset:type_name -> v1.PowerResetRackRequest + 92, // 166: v1.ScheduledOperation.bring_up:type_name -> v1.BringUpRackRequest + 68, // 167: v1.ScheduledOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest + 93, // 168: v1.ScheduledOperation.ingest:type_name -> v1.IngestRackRequest + 119, // 169: v1.CreateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig + 121, // 170: v1.CreateTaskScheduleRequest.operation:type_name -> v1.ScheduledOperation + 22, // 171: v1.GetTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 172: v1.ListTaskSchedulesRequest.rack_id:type_name -> v1.UUID + 43, // 173: v1.ListTaskSchedulesRequest.pagination:type_name -> v1.Pagination + 120, // 174: v1.ListTaskSchedulesResponse.task_schedules:type_name -> v1.TaskSchedule + 22, // 175: v1.UpdateTaskScheduleRequest.id:type_name -> v1.UUID + 119, // 176: v1.UpdateTaskScheduleRequest.schedule:type_name -> v1.ScheduleConfig + 188, // 177: v1.UpdateTaskScheduleRequest.update_mask:type_name -> google.protobuf.FieldMask + 22, // 178: v1.PauseTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 179: v1.ResumeTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 180: v1.DeleteTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 181: v1.TriggerTaskScheduleRequest.id:type_name -> v1.UUID + 22, // 182: v1.TaskScheduleScope.id:type_name -> v1.UUID + 22, // 183: v1.TaskScheduleScope.schedule_id:type_name -> v1.UUID + 22, // 184: v1.TaskScheduleScope.rack_id:type_name -> v1.UUID + 35, // 185: v1.TaskScheduleScope.types:type_name -> v1.ComponentTypes + 34, // 186: v1.TaskScheduleScope.components:type_name -> v1.ComponentTargets + 22, // 187: v1.TaskScheduleScope.last_task_id:type_name -> v1.UUID + 187, // 188: v1.TaskScheduleScope.created_at:type_name -> google.protobuf.Timestamp + 22, // 189: v1.AddTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID + 32, // 190: v1.AddTaskScheduleScopeRequest.target_spec:type_name -> v1.OperationTargetSpec + 131, // 191: v1.AddTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope + 22, // 192: v1.RemoveTaskScheduleScopeRequest.scope_id:type_name -> v1.UUID + 22, // 193: v1.UpdateTaskScheduleScopeRequest.schedule_id:type_name -> v1.UUID + 32, // 194: v1.UpdateTaskScheduleScopeRequest.desired_scope:type_name -> v1.OperationTargetSpec + 131, // 195: v1.UpdateTaskScheduleScopeResponse.scopes:type_name -> v1.TaskScheduleScope + 22, // 196: v1.ListTaskScheduleScopesRequest.schedule_id:type_name -> v1.UUID + 131, // 197: v1.ListTaskScheduleScopesResponse.scopes:type_name -> v1.TaskScheduleScope + 121, // 198: v1.CheckScheduleConflictsRequest.operation:type_name -> v1.ScheduledOperation + 22, // 199: v1.CheckScheduleConflictsRequest.exclude_schedule_id:type_name -> v1.UUID + 120, // 200: v1.CheckScheduleConflictsResponse.conflicts:type_name -> v1.TaskSchedule + 143, // 201: v1.CreateOperationRunRequest.configuration:type_name -> v1.OperationRunConfiguration + 22, // 202: v1.CreateOperationRunResponse.id:type_name -> v1.UUID + 156, // 203: v1.OperationRunConfiguration.selector:type_name -> v1.OperationRunSelector + 158, // 204: v1.OperationRunConfiguration.options:type_name -> v1.OperationRunOptions + 176, // 205: v1.OperationRunConfiguration.operation:type_name -> v1.OperationRunOperation + 22, // 206: v1.GetOperationRunRequest.id:type_name -> v1.UUID + 179, // 207: v1.GetOperationRunResponse.operation_run:type_name -> v1.OperationRun + 148, // 208: v1.ListOperationRunsRequest.filter:type_name -> v1.OperationRunFilter + 43, // 209: v1.ListOperationRunsRequest.pagination:type_name -> v1.Pagination + 180, // 210: v1.ListOperationRunsResponse.operation_runs:type_name -> v1.OperationRunSummary + 44, // 211: v1.OperationRunFilter.name:type_name -> v1.StringQueryInfo + 149, // 212: v1.OperationRunFilter.states:type_name -> v1.OperationRunStateFilter + 178, // 213: v1.OperationRunFilter.operation_kinds:type_name -> v1.OperationKind + 18, // 214: v1.OperationRunStateFilter.status:type_name -> v1.OperationRunStatus + 19, // 215: v1.OperationRunStateFilter.reason:type_name -> v1.OperationRunStatusReason + 22, // 216: v1.ListOperationRunTargetsRequest.operation_run_id:type_name -> v1.UUID + 20, // 217: v1.ListOperationRunTargetsRequest.status:type_name -> v1.OperationRunTargetStatus + 43, // 218: v1.ListOperationRunTargetsRequest.pagination:type_name -> v1.Pagination + 16, // 219: v1.ListOperationRunTargetsRequest.phase_scope:type_name -> v1.OperationRunTargetPhaseScope + 184, // 220: v1.ListOperationRunTargetsResponse.targets:type_name -> v1.OperationRunTarget + 22, // 221: v1.PauseOperationRunRequest.id:type_name -> v1.UUID + 22, // 222: v1.ResumeOperationRunRequest.id:type_name -> v1.UUID + 22, // 223: v1.AdvanceOperationRunPhaseRequest.id:type_name -> v1.UUID + 22, // 224: v1.CancelOperationRunRequest.id:type_name -> v1.UUID + 157, // 225: v1.OperationRunSelector.percentage:type_name -> v1.PercentageSelector + 159, // 226: v1.OperationRunOptions.safety_policy:type_name -> v1.OperationRunSafetyPolicy + 173, // 227: v1.OperationRunOptions.conflict_policy:type_name -> v1.OperationRunConflictPolicy + 163, // 228: v1.OperationRunOptions.ordering_policy:type_name -> v1.OperationRunOrderingPolicy + 166, // 229: v1.OperationRunOptions.phase_policy:type_name -> v1.OperationRunPhasePolicy + 160, // 230: v1.OperationRunSafetyPolicy.gates:type_name -> v1.OperationRunSafetyGate + 161, // 231: v1.OperationRunSafetyGate.failure_rate:type_name -> v1.OperationRunFailureRateGate + 162, // 232: v1.OperationRunSafetyGate.failure_count:type_name -> v1.OperationRunFailureCountGate + 17, // 233: v1.OperationRunFailureRateGate.scope:type_name -> v1.OperationRunSafetyGateScope + 17, // 234: v1.OperationRunFailureCountGate.scope:type_name -> v1.OperationRunSafetyGateScope + 164, // 235: v1.OperationRunOrderingPolicy.random:type_name -> v1.OperationRunRandomOrdering + 165, // 236: v1.OperationRunOrderingPolicy.physical_location:type_name -> v1.OperationRunPhysicalLocationOrdering + 21, // 237: v1.OperationRunPhysicalLocationOrdering.strategy:type_name -> v1.OperationRunPhysicalLocationOrdering.Strategy + 167, // 238: v1.OperationRunPhasePolicy.equal:type_name -> v1.EqualOperationRunPhases + 168, // 239: v1.OperationRunPhasePolicy.percentage:type_name -> v1.PercentageOperationRunPhases + 170, // 240: v1.OperationRunPhasePolicy.count:type_name -> v1.CountOperationRunPhases + 172, // 241: v1.OperationRunPhasePolicy.advance_policy:type_name -> v1.OperationRunPhaseAdvancePolicy + 169, // 242: v1.PercentageOperationRunPhases.phases:type_name -> v1.OperationRunPercentagePhase + 171, // 243: v1.CountOperationRunPhases.phases:type_name -> v1.OperationRunCountPhase + 174, // 244: v1.OperationRunConflictPolicy.retry:type_name -> v1.OperationRunConflictRetryPolicy + 189, // 245: v1.OperationRunConflictRetryPolicy.retry_timeout:type_name -> google.protobuf.Duration + 189, // 246: v1.OperationRunConflictRetryPolicy.initial_retry_delay:type_name -> google.protobuf.Duration + 189, // 247: v1.OperationRunConflictRetryPolicy.max_retry_delay:type_name -> google.protobuf.Duration + 22, // 248: v1.OperationRunTargetScope.exclude_operation_run_ids:type_name -> v1.UUID + 36, // 249: v1.OperationRunTargetScope.default_scope_component_filter:type_name -> v1.ComponentFilter + 68, // 250: v1.OperationRunOperation.upgrade_firmware:type_name -> v1.UpgradeFirmwareRequest + 175, // 251: v1.OperationRunOperation.target_scope:type_name -> v1.OperationRunTargetScope + 18, // 252: v1.OperationRunState.status:type_name -> v1.OperationRunStatus + 19, // 253: v1.OperationRunState.reason:type_name -> v1.OperationRunStatusReason + 13, // 254: v1.OperationKind.type:type_name -> v1.OperationType + 180, // 255: v1.OperationRun.summary:type_name -> v1.OperationRunSummary + 143, // 256: v1.OperationRun.configuration:type_name -> v1.OperationRunConfiguration + 181, // 257: v1.OperationRun.stats:type_name -> v1.OperationRunStats + 22, // 258: v1.OperationRunSummary.id:type_name -> v1.UUID + 178, // 259: v1.OperationRunSummary.operation_kind:type_name -> v1.OperationKind + 177, // 260: v1.OperationRunSummary.state:type_name -> v1.OperationRunState + 187, // 261: v1.OperationRunSummary.created_at:type_name -> google.protobuf.Timestamp + 187, // 262: v1.OperationRunSummary.updated_at:type_name -> google.protobuf.Timestamp + 187, // 263: v1.OperationRunSummary.started_at:type_name -> google.protobuf.Timestamp + 187, // 264: v1.OperationRunSummary.finished_at:type_name -> google.protobuf.Timestamp + 182, // 265: v1.OperationRunStats.current_phase_stats:type_name -> v1.OperationRunPhaseStats + 182, // 266: v1.OperationRunStats.cumulative_phase_stats:type_name -> v1.OperationRunPhaseStats + 183, // 267: v1.OperationRunPhaseStats.outcome_counts:type_name -> v1.OperationRunTargetOutcomeCounts + 22, // 268: v1.OperationRunTarget.id:type_name -> v1.UUID + 22, // 269: v1.OperationRunTarget.operation_run_id:type_name -> v1.UUID + 22, // 270: v1.OperationRunTarget.rack_id:type_name -> v1.UUID + 22, // 271: v1.OperationRunTarget.task_id:type_name -> v1.UUID + 20, // 272: v1.OperationRunTarget.status:type_name -> v1.OperationRunTargetStatus + 37, // 273: v1.OperationRunTarget.components_by_type:type_name -> v1.ComponentsByType + 187, // 274: v1.OperationRunTarget.created_at:type_name -> google.protobuf.Timestamp + 187, // 275: v1.OperationRunTarget.updated_at:type_name -> google.protobuf.Timestamp + 186, // 276: v1.NVLDomainTargets.targets:type_name -> v1.NVLDomainTarget + 22, // 277: v1.NVLDomainTarget.id:type_name -> v1.UUID + 1, // 278: v1.NVLDomainTarget.component_types:type_name -> v1.ComponentType + 100, // 279: v1.Flow.Version:input_type -> v1.VersionRequest + 122, // 280: v1.Flow.CreateTaskSchedule:input_type -> v1.CreateTaskScheduleRequest + 123, // 281: v1.Flow.GetTaskSchedule:input_type -> v1.GetTaskScheduleRequest + 124, // 282: v1.Flow.ListTaskSchedules:input_type -> v1.ListTaskSchedulesRequest + 126, // 283: v1.Flow.UpdateTaskSchedule:input_type -> v1.UpdateTaskScheduleRequest + 127, // 284: v1.Flow.PauseTaskSchedule:input_type -> v1.PauseTaskScheduleRequest + 128, // 285: v1.Flow.ResumeTaskSchedule:input_type -> v1.ResumeTaskScheduleRequest + 129, // 286: v1.Flow.DeleteTaskSchedule:input_type -> v1.DeleteTaskScheduleRequest + 130, // 287: v1.Flow.TriggerTaskSchedule:input_type -> v1.TriggerTaskScheduleRequest + 132, // 288: v1.Flow.AddTaskScheduleScope:input_type -> v1.AddTaskScheduleScopeRequest + 134, // 289: v1.Flow.RemoveTaskScheduleScope:input_type -> v1.RemoveTaskScheduleScopeRequest + 135, // 290: v1.Flow.UpdateTaskScheduleScope:input_type -> v1.UpdateTaskScheduleScopeRequest + 137, // 291: v1.Flow.ListTaskScheduleScopes:input_type -> v1.ListTaskScheduleScopesRequest + 139, // 292: v1.Flow.CheckScheduleConflicts:input_type -> v1.CheckScheduleConflictsRequest + 48, // 293: v1.Flow.CreateExpectedRack:input_type -> v1.CreateExpectedRackRequest + 50, // 294: v1.Flow.GetRackInfoByID:input_type -> v1.GetRackInfoByIDRequest + 51, // 295: v1.Flow.GetRackInfoBySerial:input_type -> v1.GetRackInfoBySerialRequest + 58, // 296: v1.Flow.GetListOfRacks:input_type -> v1.GetListOfRacksRequest + 53, // 297: v1.Flow.PatchRack:input_type -> v1.PatchRackRequest + 79, // 298: v1.Flow.DeleteRack:input_type -> v1.DeleteRackRequest + 81, // 299: v1.Flow.PurgeRack:input_type -> v1.PurgeRackRequest + 68, // 300: v1.Flow.UpgradeFirmware:input_type -> v1.UpgradeFirmwareRequest + 92, // 301: v1.Flow.BringUpRack:input_type -> v1.BringUpRackRequest + 93, // 302: v1.Flow.IngestRack:input_type -> v1.IngestRackRequest + 89, // 303: v1.Flow.PowerOnRack:input_type -> v1.PowerOnRackRequest + 90, // 304: v1.Flow.PowerOffRack:input_type -> v1.PowerOffRackRequest + 91, // 305: v1.Flow.PowerResetRack:input_type -> v1.PowerResetRackRequest + 55, // 306: v1.Flow.GetComponentInfoByID:input_type -> v1.GetComponentInfoByIDRequest + 56, // 307: v1.Flow.GetComponentInfoBySerial:input_type -> v1.GetComponentInfoBySerialRequest + 69, // 308: v1.Flow.GetComponents:input_type -> v1.GetComponentsRequest + 71, // 309: v1.Flow.ValidateComponents:input_type -> v1.ValidateComponentsRequest + 75, // 310: v1.Flow.AddComponent:input_type -> v1.AddComponentRequest + 85, // 311: v1.Flow.PatchComponent:input_type -> v1.PatchComponentRequest + 77, // 312: v1.Flow.DeleteComponent:input_type -> v1.DeleteComponentRequest + 83, // 313: v1.Flow.PurgeComponent:input_type -> v1.PurgeComponentRequest + 60, // 314: v1.Flow.CreateNVLDomain:input_type -> v1.CreateNVLDomainRequest + 62, // 315: v1.Flow.AttachRacksToNVLDomain:input_type -> v1.AttachRacksToNVLDomainRequest + 63, // 316: v1.Flow.DetachRacksFromNVLDomain:input_type -> v1.DetachRacksFromNVLDomainRequest + 64, // 317: v1.Flow.GetListOfNVLDomains:input_type -> v1.GetListOfNVLDomainsRequest + 66, // 318: v1.Flow.GetRacksForNVLDomain:input_type -> v1.GetRacksForNVLDomainRequest + 94, // 319: v1.Flow.ListTasks:input_type -> v1.ListTasksRequest + 96, // 320: v1.Flow.GetTasksByIDs:input_type -> v1.GetTasksByIDsRequest + 98, // 321: v1.Flow.CancelTask:input_type -> v1.CancelTaskRequest + 103, // 322: v1.Flow.CreateOperationRule:input_type -> v1.CreateOperationRuleRequest + 105, // 323: v1.Flow.UpdateOperationRule:input_type -> v1.UpdateOperationRuleRequest + 106, // 324: v1.Flow.DeleteOperationRule:input_type -> v1.DeleteOperationRuleRequest + 108, // 325: v1.Flow.GetOperationRule:input_type -> v1.GetOperationRuleRequest + 109, // 326: v1.Flow.ListOperationRules:input_type -> v1.ListOperationRulesRequest + 107, // 327: v1.Flow.SetRuleAsDefault:input_type -> v1.SetRuleAsDefaultRequest + 111, // 328: v1.Flow.AssociateRuleWithRack:input_type -> v1.AssociateRuleWithRackRequest + 112, // 329: v1.Flow.DisassociateRuleFromRack:input_type -> v1.DisassociateRuleFromRackRequest + 113, // 330: v1.Flow.GetRackRuleAssociation:input_type -> v1.GetRackRuleAssociationRequest + 115, // 331: v1.Flow.ListRackRuleAssociations:input_type -> v1.ListRackRuleAssociationsRequest + 141, // 332: v1.Flow.CreateOperationRun:input_type -> v1.CreateOperationRunRequest + 144, // 333: v1.Flow.GetOperationRun:input_type -> v1.GetOperationRunRequest + 146, // 334: v1.Flow.ListOperationRuns:input_type -> v1.ListOperationRunsRequest + 150, // 335: v1.Flow.ListOperationRunTargets:input_type -> v1.ListOperationRunTargetsRequest + 152, // 336: v1.Flow.PauseOperationRun:input_type -> v1.PauseOperationRunRequest + 153, // 337: v1.Flow.ResumeOperationRun:input_type -> v1.ResumeOperationRunRequest + 154, // 338: v1.Flow.AdvanceOperationRunPhase:input_type -> v1.AdvanceOperationRunPhaseRequest + 155, // 339: v1.Flow.CancelOperationRun:input_type -> v1.CancelOperationRunRequest + 101, // 340: v1.Flow.Version:output_type -> v1.BuildInfo + 120, // 341: v1.Flow.CreateTaskSchedule:output_type -> v1.TaskSchedule + 120, // 342: v1.Flow.GetTaskSchedule:output_type -> v1.TaskSchedule + 125, // 343: v1.Flow.ListTaskSchedules:output_type -> v1.ListTaskSchedulesResponse + 120, // 344: v1.Flow.UpdateTaskSchedule:output_type -> v1.TaskSchedule + 120, // 345: v1.Flow.PauseTaskSchedule:output_type -> v1.TaskSchedule + 120, // 346: v1.Flow.ResumeTaskSchedule:output_type -> v1.TaskSchedule + 190, // 347: v1.Flow.DeleteTaskSchedule:output_type -> google.protobuf.Empty + 87, // 348: v1.Flow.TriggerTaskSchedule:output_type -> v1.SubmitTaskResponse + 133, // 349: v1.Flow.AddTaskScheduleScope:output_type -> v1.AddTaskScheduleScopeResponse + 190, // 350: v1.Flow.RemoveTaskScheduleScope:output_type -> google.protobuf.Empty + 136, // 351: v1.Flow.UpdateTaskScheduleScope:output_type -> v1.UpdateTaskScheduleScopeResponse + 138, // 352: v1.Flow.ListTaskScheduleScopes:output_type -> v1.ListTaskScheduleScopesResponse + 140, // 353: v1.Flow.CheckScheduleConflicts:output_type -> v1.CheckScheduleConflictsResponse + 49, // 354: v1.Flow.CreateExpectedRack:output_type -> v1.CreateExpectedRackResponse + 52, // 355: v1.Flow.GetRackInfoByID:output_type -> v1.GetRackInfoResponse + 52, // 356: v1.Flow.GetRackInfoBySerial:output_type -> v1.GetRackInfoResponse + 59, // 357: v1.Flow.GetListOfRacks:output_type -> v1.GetListOfRacksResponse + 54, // 358: v1.Flow.PatchRack:output_type -> v1.PatchRackResponse + 80, // 359: v1.Flow.DeleteRack:output_type -> v1.DeleteRackResponse + 82, // 360: v1.Flow.PurgeRack:output_type -> v1.PurgeRackResponse + 87, // 361: v1.Flow.UpgradeFirmware:output_type -> v1.SubmitTaskResponse + 87, // 362: v1.Flow.BringUpRack:output_type -> v1.SubmitTaskResponse + 87, // 363: v1.Flow.IngestRack:output_type -> v1.SubmitTaskResponse + 87, // 364: v1.Flow.PowerOnRack:output_type -> v1.SubmitTaskResponse + 87, // 365: v1.Flow.PowerOffRack:output_type -> v1.SubmitTaskResponse + 87, // 366: v1.Flow.PowerResetRack:output_type -> v1.SubmitTaskResponse + 57, // 367: v1.Flow.GetComponentInfoByID:output_type -> v1.GetComponentInfoResponse + 57, // 368: v1.Flow.GetComponentInfoBySerial:output_type -> v1.GetComponentInfoResponse + 70, // 369: v1.Flow.GetComponents:output_type -> v1.GetComponentsResponse + 72, // 370: v1.Flow.ValidateComponents:output_type -> v1.ValidateComponentsResponse + 76, // 371: v1.Flow.AddComponent:output_type -> v1.AddComponentResponse + 86, // 372: v1.Flow.PatchComponent:output_type -> v1.PatchComponentResponse + 78, // 373: v1.Flow.DeleteComponent:output_type -> v1.DeleteComponentResponse + 84, // 374: v1.Flow.PurgeComponent:output_type -> v1.PurgeComponentResponse + 61, // 375: v1.Flow.CreateNVLDomain:output_type -> v1.CreateNVLDomainResponse + 190, // 376: v1.Flow.AttachRacksToNVLDomain:output_type -> google.protobuf.Empty + 190, // 377: v1.Flow.DetachRacksFromNVLDomain:output_type -> google.protobuf.Empty + 65, // 378: v1.Flow.GetListOfNVLDomains:output_type -> v1.GetListOfNVLDomainsResponse + 67, // 379: v1.Flow.GetRacksForNVLDomain:output_type -> v1.GetRacksForNVLDomainResponse + 95, // 380: v1.Flow.ListTasks:output_type -> v1.ListTasksResponse + 97, // 381: v1.Flow.GetTasksByIDs:output_type -> v1.GetTasksByIDsResponse + 99, // 382: v1.Flow.CancelTask:output_type -> v1.CancelTaskResponse + 104, // 383: v1.Flow.CreateOperationRule:output_type -> v1.CreateOperationRuleResponse + 190, // 384: v1.Flow.UpdateOperationRule:output_type -> google.protobuf.Empty + 190, // 385: v1.Flow.DeleteOperationRule:output_type -> google.protobuf.Empty + 102, // 386: v1.Flow.GetOperationRule:output_type -> v1.OperationRule + 110, // 387: v1.Flow.ListOperationRules:output_type -> v1.ListOperationRulesResponse + 190, // 388: v1.Flow.SetRuleAsDefault:output_type -> google.protobuf.Empty + 190, // 389: v1.Flow.AssociateRuleWithRack:output_type -> google.protobuf.Empty + 190, // 390: v1.Flow.DisassociateRuleFromRack:output_type -> google.protobuf.Empty + 114, // 391: v1.Flow.GetRackRuleAssociation:output_type -> v1.GetRackRuleAssociationResponse + 117, // 392: v1.Flow.ListRackRuleAssociations:output_type -> v1.ListRackRuleAssociationsResponse + 142, // 393: v1.Flow.CreateOperationRun:output_type -> v1.CreateOperationRunResponse + 145, // 394: v1.Flow.GetOperationRun:output_type -> v1.GetOperationRunResponse + 147, // 395: v1.Flow.ListOperationRuns:output_type -> v1.ListOperationRunsResponse + 151, // 396: v1.Flow.ListOperationRunTargets:output_type -> v1.ListOperationRunTargetsResponse + 179, // 397: v1.Flow.PauseOperationRun:output_type -> v1.OperationRun + 179, // 398: v1.Flow.ResumeOperationRun:output_type -> v1.OperationRun + 179, // 399: v1.Flow.AdvanceOperationRunPhase:output_type -> v1.OperationRun + 179, // 400: v1.Flow.CancelOperationRun:output_type -> v1.OperationRun + 340, // [340:401] is the sub-list for method output_type + 279, // [279:340] is the sub-list for method input_type + 279, // [279:279] is the sub-list for extension type_name + 279, // [279:279] is the sub-list for extension extendee + 0, // [0:279] is the sub-list for field type_name } func init() { file_flow_proto_init() } @@ -12751,6 +12923,7 @@ func file_flow_proto_init() { file_flow_proto_msgTypes[10].OneofWrappers = []any{ (*OperationTargetSpec_Racks)(nil), (*OperationTargetSpec_Components)(nil), + (*OperationTargetSpec_NvlDomains)(nil), } file_flow_proto_msgTypes[14].OneofWrappers = []any{ (*ComponentFilter_Types)(nil), @@ -12830,13 +13003,17 @@ func file_flow_proto_init() { } file_flow_proto_msgTypes[156].OneofWrappers = []any{} file_flow_proto_msgTypes[158].OneofWrappers = []any{} + file_flow_proto_msgTypes[164].OneofWrappers = []any{ + (*NVLDomainTarget_Id)(nil), + (*NVLDomainTarget_Name)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_flow_proto_rawDesc), len(file_flow_proto_rawDesc)), NumEnums: 22, - NumMessages: 163, + NumMessages: 165, NumExtensions: 0, NumServices: 1, }, diff --git a/rest-api/proto/flow/src/v1/flow.proto b/rest-api/proto/flow/src/v1/flow.proto index e5407d478e..f2ed856446 100644 --- a/rest-api/proto/flow/src/v1/flow.proto +++ b/rest-api/proto/flow/src/v1/flow.proto @@ -274,12 +274,14 @@ message Identifier { } // OperationTargetSpec contains targets for an operation. -// Supports either rack-level targeting (with optional type filtering) -// or component-level targeting (by UUID or external reference), but not both. +// Supports rack-level or NVLink-domain targeting (with optional type filtering), +// or component-level targeting (by UUID or external reference), but not more +// than one target kind at a time. message OperationTargetSpec { oneof targets { RackTargets racks = 1; ComponentTargets components = 2; + NVLDomainTargets nvl_domains = 3; } } @@ -524,7 +526,7 @@ message UpgradeFirmwareRequest { // GetComponents - retrieves components from local database message GetComponentsRequest { - optional OperationTargetSpec target_spec = 1; // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, queries all components. + optional OperationTargetSpec target_spec = 1; // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, queries all components. repeated Filter filters = 2; // Filter conditions for component queries optional Pagination pagination = 3; optional OrderBy order_by = 4; @@ -536,7 +538,7 @@ message GetComponentsResponse { } message ValidateComponentsRequest { - optional OperationTargetSpec target_spec = 1; // Optional: Flexible targeting: rack(s) with optional type filter, or specific components. If not provided, returns all diffs. + optional OperationTargetSpec target_spec = 1; // Optional: target racks or NVLink domains with an optional type filter, or specific components. If not provided, returns all diffs. repeated Filter filters = 2; // Filter conditions for component queries optional Pagination pagination = 3; optional OrderBy order_by = 4; @@ -657,7 +659,7 @@ message QueueOptions { } message PowerOnRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components string description = 2; // optional task description optional QueueOptions queue_options = 3; optional UUID rule_id = 4; // optional: override rule resolution with a specific rule @@ -671,7 +673,7 @@ message PowerOnRackRequest { } message PowerOffRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components bool forced = 2; string description = 3; // optional task description optional QueueOptions queue_options = 4; @@ -686,7 +688,7 @@ message PowerOffRackRequest { } message PowerResetRackRequest { - OperationTargetSpec target_spec = 1; // Flexible targeting: rack(s) with optional type filter, or specific components + OperationTargetSpec target_spec = 1; // Target racks or NVLink domains with an optional type filter, or specific components bool forced = 2; string description = 3; // optional task description optional QueueOptions queue_options = 4; @@ -701,7 +703,7 @@ message PowerResetRackRequest { } message BringUpRackRequest { - OperationTargetSpec target_spec = 1; // Target racks for bring-up + OperationTargetSpec target_spec = 1; // Target racks, NVLink domains, or components for bring-up string description = 2; // optional task description optional UUID rule_id = 3; // optional: override rule resolution with a specific rule // When true, allow the bring-up sequence (which may power-cycle hosts @@ -714,7 +716,7 @@ message BringUpRackRequest { } message IngestRackRequest { - OperationTargetSpec target_spec = 1; // Target racks for ingestion + OperationTargetSpec target_spec = 1; // Target racks, NVLink domains, or components for ingestion repeated Filter filters = 2; // Filter conditions for component queries (e.g. by type, name) string description = 3; // optional task description optional UUID rule_id = 4; // optional: override rule resolution with a specific rule @@ -954,7 +956,7 @@ message ScheduledOperation { // CreateTaskScheduleRequest creates a new TaskSchedule. // The target_spec on the operation message defines the initial scope; it follows -// the same targeting rules as AddTaskScheduleScope (rack-level or component-level). +// the same targeting rules as AddTaskScheduleScope. // Use AddTaskScheduleScope / RemoveTaskScheduleScope to modify the scope after creation. message CreateTaskScheduleRequest { ScheduleConfig schedule = 1; @@ -1043,8 +1045,9 @@ message TaskScheduleScope { } // AddTaskScheduleScopeRequest adds one or more scope entries to a schedule. -// Supports rack-level targeting (with optional component-type filter) and -// component-level targeting (specific components by UUID or external reference). +// Supports rack or NVLink domain targeting (with an optional component-type +// filter) and component targeting (specific components by UUID or external reference). +// NVLink domain membership is resolved to rack scopes when this request is handled. // For component-level targets the server resolves which rack each component // belongs to and groups them into per-rack scope entries automatically. // Racks already present in the scope have their component filter merged with the @@ -1070,7 +1073,7 @@ message RemoveTaskScheduleScopeRequest { // desired target_spec: racks present in desired_scope but not in the current scope // are added; racks present in the current scope but absent from desired_scope are // removed; racks present in both have their component_filter updated if changed. -// For component-level targets the server resolves rack membership automatically. +// For NVLink domain and component targets the server resolves rack membership automatically. message UpdateTaskScheduleScopeRequest { UUID schedule_id = 1; OperationTargetSpec desired_scope = 2; @@ -1514,3 +1517,19 @@ message OperationRunTarget { google.protobuf.Timestamp created_at = 10; google.protobuf.Timestamp updated_at = 11; } + +// NVLDomainTargets contains one or more NVLink domain targets. +message NVLDomainTargets { + repeated NVLDomainTarget targets = 1; +} + +// NVLDomainTarget identifies an NVLink domain and optionally filters the +// components selected from every rack currently belonging to that domain. +message NVLDomainTarget { + oneof identifier { + UUID id = 1; // NVLink domain UUID + string name = 2; // NVLink domain name + } + // Optional: filter by component type. Omit (or send an empty list) to include all component types in the domain. + repeated ComponentType component_types = 3; +}