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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rest-api/api/pkg/api/handler/instancetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ func (gaith GetAllInstanceTypeHandler) Handle(c echo.Context) error {
instanceTypeIDsToMachineInstanceTypeMap[mi.InstanceTypeID] = append(instanceTypeIDsToMachineInstanceTypeMap[mi.InstanceTypeID], cmi)
}

var instantTypeIDsToAllocStatsMap map[uuid.UUID]*model.APIAllocationStats
var instantTypeIDsToAllocStatsMap map[uuid.UUID]*model.APIInstanceTypeAllocationStats
if includeAllocationStats {
instantTypeIDsToAllocStatsMap, apiErr = common.GetAllInstanceTypeAllocationStats(ctx, gaith.dbSession, stID, itIDs, logger, tenantID)
if apiErr != nil {
Expand Down Expand Up @@ -844,7 +844,7 @@ func (gith GetInstanceTypeHandler) Handle(c echo.Context) error {
}

// Allocation stats info for this Tnstance Type
var aas *model.APIAllocationStats
var aas *model.APIInstanceTypeAllocationStats

if includeAllocationStats {
aas, apiErr = common.GetInstanceTypeAllocationStats(ctx, gith.dbSession, logger, *it, tenantID)
Expand Down
4 changes: 2 additions & 2 deletions rest-api/api/pkg/api/handler/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ func (gtitsh GetTenantInstanceTypeStatsHandler) Handle(c echo.Context) error {
return acc + ac.ConstraintValue
}, 0)

apiAllocs := lo.Map(details, func(ac cdbm.AllocationConstraint, _ int) model.APITenantInstanceTypeAllocation {
return model.APITenantInstanceTypeAllocation{
apiAllocs := lo.Map(details, func(ac cdbm.AllocationConstraint, _ int) model.APITenantInstanceTypeAllocationStats {
return model.APITenantInstanceTypeAllocationStats{
ID: ac.Allocation.ID.String(),
Name: ac.Allocation.Name,
Total: ac.ConstraintValue,
Expand Down
4 changes: 2 additions & 2 deletions rest-api/api/pkg/api/handler/stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ func TestStatsHandlers(t *testing.T) {
assert.Equal(t, 0, gpuLStats.UsedMachineStats.Unknown)
assert.Equal(t, 2, len(gpuLStats.Tenants)) // alpha, beta

gpuLTenantByName := make(map[string]model.APIMachineInstanceTypeTenant)
gpuLTenantByName := make(map[string]model.APIMachineInstanceTypeTenantStats)
for _, tn := range gpuLStats.Tenants {
gpuLTenantByName[tn.Name] = tn
}
Expand Down Expand Up @@ -563,7 +563,7 @@ func TestStatsHandlers(t *testing.T) {
assert.Equal(t, 1, gpuSStats.UsedMachineStats.Initializing)
assert.Equal(t, 3, len(gpuSStats.Tenants)) // alpha, beta, gamma

gpuSTenantByName := make(map[string]model.APIMachineInstanceTypeTenant)
gpuSTenantByName := make(map[string]model.APIMachineInstanceTypeTenantStats)
for _, tn := range gpuSStats.Tenants {
gpuSTenantByName[tn.Name] = tn
}
Expand Down
10 changes: 0 additions & 10 deletions rest-api/api/pkg/api/handler/subnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,6 @@ func TestSubnetHandler_Create(t *testing.T) {
okBody, err := json.Marshal(model.APISubnetCreateRequest{Name: "ok1", Description: cutil.GetPtr(""), VpcID: vpc1.ID.String(), IPv4BlockID: cutil.GetPtr(ipb1.ID.String()), PrefixLength: prefixLen})
assert.Nil(t, err)

errBodyIPBlockSize, err := json.Marshal(model.APISubnetCreateRequest{Name: "okipb", Description: cutil.GetPtr(""), VpcID: vpc1.ID.String(), IPv4BlockID: cutil.GetPtr(ipb1.ID.String()), IPBlockSize: &prefixLen})
assert.Nil(t, err)

prefixLen = 16
okBodyFG, err := json.Marshal(model.APISubnetCreateRequest{Name: "okFG", Description: cutil.GetPtr(""), VpcID: vpc1.ID.String(), IPv4BlockID: cutil.GetPtr(ipbFG.ID.String()), PrefixLength: prefixLen})
assert.Nil(t, err)
Expand Down Expand Up @@ -407,13 +404,6 @@ func TestSubnetHandler_Create(t *testing.T) {
expectedStatus: http.StatusCreated,
expectedGateway: "192.168.0.1",
expectedPrefix: "192.168.0.0",
}, {
name: "error when ipBlockSize is specified",
reqOrgName: tnOrg1,
reqBody: string(errBodyIPBlockSize),
user: tnu,
expectedErr: true,
expectedStatus: http.StatusBadRequest,
},
{
name: "success case with Full Grant",
Expand Down
8 changes: 4 additions & 4 deletions rest-api/api/pkg/api/handler/util/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ func GetAndValidateQueryRelations(qParams url.Values, relatedEntities map[string
}

// GetAllInstanceTypeAllocationStats is a utility function to get all instance type allocation stats
func GetAllInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Session, siteID *uuid.UUID, instanceTypeIDs []uuid.UUID, logger zerolog.Logger, tenantID *uuid.UUID) (map[uuid.UUID]*cam.APIAllocationStats, *cutil.APIError) {
func GetAllInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Session, siteID *uuid.UUID, instanceTypeIDs []uuid.UUID, logger zerolog.Logger, tenantID *uuid.UUID) (map[uuid.UUID]*cam.APIInstanceTypeAllocationStats, *cutil.APIError) {
var instances []cdbm.Instance
var serr error

Expand Down Expand Up @@ -704,10 +704,10 @@ func GetAllInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Sessi
}

// Build allocation stats map for each instance type ID with total, used, max allocatable
allocAPIStatsMap := make(map[uuid.UUID]*cam.APIAllocationStats)
allocAPIStatsMap := make(map[uuid.UUID]*cam.APIInstanceTypeAllocationStats)

for _, instanceTypeID := range instanceTypeIDs {
aas := &cam.APIAllocationStats{}
aas := &cam.APIInstanceTypeAllocationStats{}

aas.Assigned = instanceTypeIDToMachinesMap[instanceTypeID]
aas.Total = instanceTypeToSumConstraintValue[instanceTypeID]
Expand Down Expand Up @@ -739,7 +739,7 @@ func GetAllInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Sessi
}

// GetInstanceTypeAllocationStats is a utility function to get the allocation stats from allocation constraints and instances based on instancetype
func GetInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Session, logger zerolog.Logger, it cdbm.InstanceType, tenantID *uuid.UUID) (*cam.APIAllocationStats, *cutil.APIError) {
func GetInstanceTypeAllocationStats(ctx context.Context, dbSession *cdb.Session, logger zerolog.Logger, it cdbm.InstanceType, tenantID *uuid.UUID) (*cam.APIInstanceTypeAllocationStats, *cutil.APIError) {
mstats, err := GetAllInstanceTypeAllocationStats(ctx, dbSession, it.SiteID, []uuid.UUID{it.ID}, logger, tenantID)
if err != nil {
return nil, err
Expand Down
12 changes: 6 additions & 6 deletions rest-api/api/pkg/api/handler/util/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@
it *cdbm.InstanceType
tnas []cdbm.Allocation
instances []cdbm.Instance
expectStats *cam.APIAllocationStats
expectStats *cam.APIInstanceTypeAllocationStats
expectErr bool
logger zerolog.Logger
}{
Expand All @@ -1452,7 +1452,7 @@
tenantID: cutil.GetPtr(tn1.ID),
instances: tn1inss,
it: it1,
expectStats: &cam.APIAllocationStats{
expectStats: &cam.APIInstanceTypeAllocationStats{
Assigned: len(m1s),
Total: alc1.ConstraintValue,
Used: len(tn1inss),
Expand All @@ -1467,7 +1467,7 @@
tenantID: cutil.GetPtr(tn2.ID),
instances: tn2inss,
it: it1,
expectStats: &cam.APIAllocationStats{
expectStats: &cam.APIInstanceTypeAllocationStats{
Assigned: len(m1s),
Total: alc2.ConstraintValue,
Used: len(tn2inss),
Expand All @@ -1482,7 +1482,7 @@
tenantID: cutil.GetPtr(tn3.ID),
instances: tn3inss,
it: it1,
expectStats: &cam.APIAllocationStats{
expectStats: &cam.APIInstanceTypeAllocationStats{
Assigned: len(m1s),
Total: alc3.ConstraintValue,
Used: len(tn3inss),
Expand All @@ -1497,7 +1497,7 @@
tenantID: nil,
instances: it1inss,
it: it1,
expectStats: &cam.APIAllocationStats{
expectStats: &cam.APIInstanceTypeAllocationStats{
Assigned: len(m1s),
Total: alc1.ConstraintValue + alc2.ConstraintValue + alc3.ConstraintValue,
Used: len(it1inss),
Expand All @@ -1512,7 +1512,7 @@
tenantID: nil,
instances: []cdbm.Instance{},
it: it2,
expectStats: &cam.APIAllocationStats{
expectStats: &cam.APIInstanceTypeAllocationStats{
Assigned: len(m2s),
Total: 0,
Used: 0,
Expand Down Expand Up @@ -1581,7 +1581,7 @@
mtn2 := TestBuildTenant(t, dbSession, "Test Mixed Role Tenant 2", mOrg3, mu3)

type args struct {
ctx context.Context

Check failure on line 1584 in rest-api/api/pkg/api/handler/util/common/common_test.go

View workflow job for this annotation

GitHub Actions / Lint and Test / Lint Go

found a struct that contains a context.Context field (containedctx)
logger zerolog.Logger
dbSession *cdb.Session
org string
Expand Down Expand Up @@ -2055,7 +2055,7 @@

tests := []struct {
name string
ctx context.Context

Check failure on line 2058 in rest-api/api/pkg/api/handler/util/common/common_test.go

View workflow job for this annotation

GitHub Actions / Lint and Test / Lint Go

found a struct that contains a context.Context field (containedctx)
logger zerolog.Logger
dbSession *cdb.Session
machineIDs []string
Expand Down
30 changes: 29 additions & 1 deletion rest-api/api/pkg/api/model/allocationconstraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/NVIDIA/infra-controller/rest-api/api/pkg/api/model/util"
cutil "github.com/NVIDIA/infra-controller/rest-api/common/pkg/util"
cdbm "github.com/NVIDIA/infra-controller/rest-api/db/pkg/db/model"
validation "github.com/go-ozzo/ozzo-validation/v4"
validationis "github.com/go-ozzo/ozzo-validation/v4/is"
Expand All @@ -19,6 +20,21 @@ const (
ValidationErrorAllocationConstraintConstraintType = "Constraint Type should be Reserved, OnDemand or Preemptible"
)

var (
// resourceTypeIDDeprecationTime is the time when the ResourceTypeID attribute will be no longer be available in the API
resourceTypeIDDeprecationTime, _ = time.Parse(time.RFC1123, "Thu, 09 Jul 2026 00:00:00 UTC")

// resourceTypeIDDeprecations is a list of deprecated entities for the ResourceTypeID attribute
allocationConstraintDeprecations = []DeprecatedEntity{
{
OldValue: "ResourceTypeID",
NewValue: cutil.GetPtr("resourceTypeId"),
Type: DeprecationTypeAttribute,
TakeActionBy: resourceTypeIDDeprecationTime,
},
}
)

// APIAllocationConstraintCreateRequest captures user request to create a new Allocation Constraint
type APIAllocationConstraintCreateRequest struct {
// ResourceType is the type of the resource for the Allocation Constraint
Expand Down Expand Up @@ -82,8 +98,10 @@ type APIAllocationConstraint struct {
AllocationID string `json:"allocationId"`
// ResourceType is the type of the Resource
ResourceType string `json:"resourceType"`
// ResourceTypeIDDeprecated is the deprecated improperly cased attribute
ResourceTypeIDDeprecated *string `json:"ResourceTypeID,omitempty"`
// ResourceTypeID is the ID of the resource corresponding to the Allocation Constraint
ResourceTypeID string `bun:"resource_type_id,type:uuid,notnull"`
ResourceTypeID string `json:"resourceTypeId"`
// ConstraintType is the type of the Allocation Constraint
ConstraintType string `json:"constraintType"`
// ConstraintValue is the value of the Allocation Constraint
Expand All @@ -98,6 +116,8 @@ type APIAllocationConstraint struct {
Created time.Time `json:"created"`
// UpdatedAt indicates the ISO datetime string for when the entity was last updated
Updated time.Time `json:"updated"`
// Deprecations is the list of deprecations for the Allocation Constraint
Deprecations []APIDeprecation `json:"deprecations,omitempty"`
}

// NewAPIAllocationConstraint accepts a DB layer Allocation Constraint object and returns an API object
Expand All @@ -122,5 +142,13 @@ func NewAPIAllocationConstraint(cdbm *cdbm.AllocationConstraint, dbinstp *cdbm.I
apiac.IPBlock = NewAPIIPBlockSummary(dbipb)
}

if time.Now().Before(resourceTypeIDDeprecationTime) {
apiac.ResourceTypeIDDeprecated = cutil.GetPtr(cdbm.ResourceTypeID.String())
}

for _, deprecation := range allocationConstraintDeprecations {
apiac.Deprecations = append(apiac.Deprecations, NewAPIDeprecation(deprecation))
}

return apiac
}
2 changes: 1 addition & 1 deletion rest-api/api/pkg/api/model/deprecation.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type APIDeprecation struct {
QueryParam *string `json:"queryParam,omitempty"`
// Endpoint denotes the endpoint that is deprecated (optional)
Endpoint *string `json:"endpoint,omitempty"`
// ReplacedBy denotes the field that replaces the deprecated field
// ReplacedBy denotes the field that replaces the deprecated field (optional)
ReplacedBy *string `json:"replacedBy,omitempty"`
// TakeActionBy indicates the ISO datetime string for when the deprecated field will no longer be accepted or available in the API
TakeActionBy time.Time `json:"takeActionBy"`
Expand Down
6 changes: 3 additions & 3 deletions rest-api/api/pkg/api/model/instancetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ type APIInstanceType struct {
// MachineInstanceTypes is the list of machines that are associated to this Instance Type
MachineInstanceTypes []APIMachineInstanceType `json:"machineInstanceTypes,omitempty"`
// AllocationStats is the stats of allocation that are associated to this Instance Type
AllocationStats *APIAllocationStats `json:"allocationStats,omitempty"`
AllocationStats *APIInstanceTypeAllocationStats `json:"allocationStats,omitempty"`
// Deprecations is the list of deprecation messages denoting fields which are being deprecated
Deprecations []APIDeprecation `json:"deprecations,omitempty"`
// Status is the status of the Instance Type
Expand All @@ -147,7 +147,7 @@ type APIInstanceType struct {
}

// NewAPIInstanceType accepts a DB layer Instance Type object returns an API layer object
func NewAPIInstanceType(dbit *cdbm.InstanceType, dbsds []cdbm.StatusDetail, mcs []cdbm.MachineCapability, mit []cdbm.MachineInstanceType, aas *APIAllocationStats) *APIInstanceType {
func NewAPIInstanceType(dbit *cdbm.InstanceType, dbsds []cdbm.StatusDetail, mcs []cdbm.MachineCapability, mit []cdbm.MachineInstanceType, aas *APIInstanceTypeAllocationStats) *APIInstanceType {
if dbit == nil {
return nil
}
Expand Down Expand Up @@ -223,7 +223,7 @@ func NewAPIInstanceTypeSummary(dbist *cdbm.InstanceType) *APIInstanceTypeSummary
}

// APIAllocationStats is the data structure to capture API representation of an InstanceType allocation stats
type APIAllocationStats struct {
type APIInstanceTypeAllocationStats struct {
// Assigned is the total number of Machines assigned to this Instance Type
Assigned int `json:"assigned"`
// Total is the total number of Machines allocated to different Tenants for this Instance Type
Expand Down
3 changes: 0 additions & 3 deletions rest-api/api/pkg/api/model/ipblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ type APIIPBlockCreateRequest struct {
RoutingType string `json:"routingType"`
// Prefix is the prefix of the network in CIDR notation
Prefix string `json:"prefix"`
// BlockSize is the legacy field for prefixLength
// NOTE: This field has been deprecated
BlockSize *int `json:"blockSize"`
// PrefixLength is the length of the prefix
PrefixLength int `json:"prefixLength"`
// ProtocolVersion is the version of the ip network ipv4 or ipv6
Expand Down
5 changes: 0 additions & 5 deletions rest-api/api/pkg/api/model/ipblock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ func TestAPIIPBlockCreateRequest_Validate(t *testing.T) {
obj: APIIPBlockCreateRequest{Name: "ab", Description: cutil.GetPtr("abc"), SiteID: uuid.New().String(), RoutingType: cdbm.IPBlockRoutingTypePublic, Prefix: "192.164.10.0", PrefixLength: prefLen, ProtocolVersion: "ipv4"},
expectErr: true,
},
{
desc: "error when neither BlockSize is specified",
obj: APIIPBlockCreateRequest{Name: "ab", Description: cutil.GetPtr("abc"), SiteID: uuid.New().String(), RoutingType: cdbm.IPBlockRoutingTypePublic, Prefix: "192.164.10.0", BlockSize: cutil.GetPtr(28), ProtocolVersion: cdbm.IPBlockProtocolVersionV4},
expectErr: true,
},
{
desc: "error when prefixLength is not specified",
obj: APIIPBlockCreateRequest{Name: "ab", Description: cutil.GetPtr("abc"), SiteID: uuid.New().String(), RoutingType: cdbm.IPBlockRoutingTypePublic, Prefix: "192.164.10.0", ProtocolVersion: cdbm.IPBlockProtocolVersionV4},
Expand Down
31 changes: 29 additions & 2 deletions rest-api/api/pkg/api/model/networksecuritygroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ var NetworkSecurityGroupRuleAPIPropagationStatusFromProtobufPropagationStatus =
cwssaws.NetworkSecurityGroupPropagationStatus_NSG_PROP_STATUS_ERROR: APINetworkSecurityGroupPropagationStatusError,
}

var (
// Time when the NetworkSecurityGroup propagation object_id attribute will be deprecated
networkSecurityGroupPropagationObjectIDDeprecationTime, _ = time.Parse(time.RFC1123, "Thu, 09 Jul 2026 00:00:00 UTC")

// Deprecations for the NetworkSecurityGroup model
networkSecurityGroupPropagationDetailsDeprecations = []DeprecatedEntity{
{
OldValue: "object_id",
NewValue: cutil.GetPtr("objectId"),
Type: DeprecationTypeAttribute,
TakeActionBy: networkSecurityGroupPropagationObjectIDDeprecationTime,
},
}
)

// APINetworkSecurityGroupCreateRequest is the data structure to capture instance request to create a new NetworkSecurityGroup
type APINetworkSecurityGroupCreateRequest struct {
// Name is the name of the NetworkSecurityGroup
Expand All @@ -117,7 +132,7 @@ type APINetworkSecurityGroupCreateRequest struct {
Rules []APINetworkSecurityGroupRule `json:"rules"`
// StatefulEgress defines whether a NetworkSecurityGroup's egress rules will be automatically stateful
StatefulEgress bool `json:"statefulEgress"`
// Labels to be associted with the NetworkSecurityGroup
// Labels to be associated with the NetworkSecurityGroup
Labels map[string]string `json:"labels"`
}

Expand Down Expand Up @@ -624,7 +639,9 @@ func NewAPINetworkSecurityGroupSummary(dbsg *cdbm.NetworkSecurityGroup) *APINetw

type APINetworkSecurityGroupPropagationDetails struct {
// The ID of the object (VPC/Instance/etc) for these details
ObjectID string `json:"object_id"`
ObjectIDDeprecated *string `json:"object_id,omitempty"`
// The ID of the object (VPC/Instance/etc) for these details
ObjectID string `json:"objectId"`
// The detailed propagation status that was
// actually returned from NICo
DetailedStatus string `json:"detailedStatus"`
Expand All @@ -640,6 +657,8 @@ type APINetworkSecurityGroupPropagationDetails struct {
// IDs of any instances associated with the ObjectID that have
// not yet updated their NSG rules.
UnpropagatedInstanceIds []string `json:"unpropagatedInstanceIds"`
// Deprecations is the list of deprecations for the NetworkSecurityGroupPropagationDetails
Deprecations []APIDeprecation `json:"deprecations,omitempty"`
}

func NewAPINetworkSecurityGroupPropagationDetails(s *cdbm.NetworkSecurityGroupPropagationDetails) *APINetworkSecurityGroupPropagationDetails {
Expand All @@ -654,6 +673,10 @@ func NewAPINetworkSecurityGroupPropagationDetails(s *cdbm.NetworkSecurityGroupPr
UnpropagatedInstanceIds: s.NetworkSecurityGroupPropagationObjectStatus.UnpropagatedInstanceIds,
}

if time.Now().Before(networkSecurityGroupPropagationObjectIDDeprecationTime) {
details.ObjectIDDeprecated = cutil.GetPtr(s.NetworkSecurityGroupPropagationObjectStatus.Id)
}

status, found := NetworkSecurityGroupRuleAPIPropagationDetailedStatusFromProtobufPropagationStatus[s.Status]
if !found {
// We could return an error, but we should probably _not_ fail
Expand All @@ -675,5 +698,9 @@ func NewAPINetworkSecurityGroupPropagationDetails(s *cdbm.NetworkSecurityGroupPr

details.Status = status

for _, deprecation := range networkSecurityGroupPropagationDetailsDeprecations {
details.Deprecations = append(details.Deprecations, NewAPIDeprecation(deprecation))
}

return details
}
Loading
Loading