Skip to content

Commit 325a2e5

Browse files
michal-kopczynskiMichal Kopczynski
andauthored
PRICE-1438: Add commitments isolation feature (#651)
* PRICE-1438: Add commitments isolation feature * api gen * gen docs * gen sdk * gs branch onto master * gen sdk --------- Co-authored-by: Michal Kopczynski <michal@cast.ai>
1 parent beba1c7 commit 325a2e5

File tree

6 files changed

+853
-9
lines changed

6 files changed

+853
-9
lines changed

castai/resource_commitments.go

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const (
2828
fieldCommitmentsGCPCUDs = "gcp_cuds"
2929
fieldCommitmentsConfigs = "commitment_configs"
3030
fieldCommitmentsOrganizationId = "organization_id"
31+
fieldCommitmentsImportMode = "import_mode"
32+
33+
importModeOverwrite = "OVERWRITE"
34+
importModeAppend = "APPEND"
3135
)
3236

3337
var (
@@ -156,6 +160,13 @@ func resourceCommitments() *schema.Resource {
156160
Optional: true,
157161
Description: "Organization ID. If not provided, will be fetched from the API using the authentication token.",
158162
},
163+
fieldCommitmentsImportMode: {
164+
Type: schema.TypeString,
165+
Optional: true,
166+
Default: importModeOverwrite,
167+
Description: "Import mode. OVERWRITE replaces all commitments for the CSP. APPEND upserts without deleting existing ones.",
168+
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{importModeOverwrite, importModeAppend}, false)),
169+
},
159170
// Input configurations
160171
fieldCommitmentsConfigs: {
161172
Type: schema.TypeList,
@@ -563,21 +574,42 @@ func resourceCastaiCommitmentsUpsert(ctx context.Context, data *schema.ResourceD
563574
return diag.FromErr(err)
564575
}
565576

577+
mode := data.Get(fieldCommitmentsImportMode).(string)
578+
566579
var imported []sdk.CastaiInventoryV1beta1Commitment
567580
switch {
568581
case reservationsOk:
569-
if err := importReservations(ctx, meta, reservations); err != nil {
582+
if err := importReservations(ctx, meta, reservations, mode); err != nil {
570583
return diag.FromErr(err)
571584
}
572585
orgCommitments, err := getOrganizationCommitments(ctx, meta)
573586
if err != nil {
574587
return diag.FromErr(err)
575588
}
576-
imported = lo.Filter(orgCommitments, func(c sdk.CastaiInventoryV1beta1Commitment, _ int) bool {
577-
return c.AzureReservationContext != nil
578-
})
579-
if len(imported) != len(reservations) {
580-
return diag.Errorf("expected %d Azure commitments, got %d", len(reservations), len(imported))
589+
590+
if mode == importModeAppend {
591+
// Build set of reservation IDs from the import input
592+
importReservationIDs := make(map[string]struct{})
593+
for _, r := range reservations {
594+
if r.ReservationId != nil {
595+
importReservationIDs[*r.ReservationId] = struct{}{}
596+
}
597+
}
598+
// Filter org commitments to only those matching our import input
599+
imported = lo.Filter(orgCommitments, func(c sdk.CastaiInventoryV1beta1Commitment, _ int) bool {
600+
if c.AzureReservationContext == nil || c.AzureReservationContext.Id == nil {
601+
return false
602+
}
603+
_, ok := importReservationIDs[*c.AzureReservationContext.Id]
604+
return ok
605+
})
606+
} else {
607+
imported = lo.Filter(orgCommitments, func(c sdk.CastaiInventoryV1beta1Commitment, _ int) bool {
608+
return c.AzureReservationContext != nil
609+
})
610+
if len(imported) != len(reservations) {
611+
return diag.Errorf("expected %d Azure commitments, got %d", len(reservations), len(imported))
612+
}
581613
}
582614
case cudsOk:
583615
if err := importCUDs(ctx, meta, cuds); err != nil {
@@ -649,7 +681,7 @@ func importCUDs(ctx context.Context, meta any, imports []sdk.CastaiInventoryV1be
649681
res, err := meta.(*ProviderConfig).api.CommitmentsAPIImportGCPCommitmentsWithResponse(
650682
ctx,
651683
&sdk.CommitmentsAPIImportGCPCommitmentsParams{
652-
Behaviour: lo.ToPtr[sdk.CommitmentsAPIImportGCPCommitmentsParamsBehaviour]("OVERWRITE"),
684+
Behaviour: lo.ToPtr[sdk.CommitmentsAPIImportGCPCommitmentsParamsBehaviour](importModeOverwrite),
653685
},
654686
imports,
655687
)
@@ -659,11 +691,26 @@ func importCUDs(ctx context.Context, meta any, imports []sdk.CastaiInventoryV1be
659691
return nil
660692
}
661693

662-
func importReservations(ctx context.Context, meta any, imports []sdk.CastaiInventoryV1beta1AzureReservationImport) error {
694+
func toAzureImportBehaviour(mode string) (sdk.CommitmentsAPIImportAzureReservationsParamsBehaviour, error) {
695+
switch mode {
696+
case importModeOverwrite:
697+
return sdk.CommitmentsAPIImportAzureReservationsParamsBehaviourOVERWRITE, nil
698+
case importModeAppend:
699+
return sdk.CommitmentsAPIImportAzureReservationsParamsBehaviourAPPEND, nil
700+
default:
701+
return "", fmt.Errorf("unsupported azure import mode: %q", mode)
702+
}
703+
}
704+
705+
func importReservations(ctx context.Context, meta any, imports []sdk.CastaiInventoryV1beta1AzureReservationImport, mode string) error {
706+
behaviour, err := toAzureImportBehaviour(mode)
707+
if err != nil {
708+
return err
709+
}
663710
res, err := meta.(*ProviderConfig).api.CommitmentsAPIImportAzureReservationsWithResponse(
664711
ctx,
665712
&sdk.CommitmentsAPIImportAzureReservationsParams{
666-
Behaviour: lo.ToPtr[sdk.CommitmentsAPIImportAzureReservationsParamsBehaviour]("OVERWRITE"),
713+
Behaviour: lo.ToPtr(behaviour),
667714
},
668715
imports,
669716
)
@@ -733,6 +780,23 @@ func populateCommitmentsResourceData(ctx context.Context, d *schema.ResourceData
733780
if err != nil {
734781
return err
735782
}
783+
784+
mode := ""
785+
if v, ok := d.GetOk(fieldCommitmentsImportMode); ok {
786+
mode = v.(string)
787+
}
788+
if mode == importModeAppend && reservationsOk {
789+
// Filter azureResources to only those matching our import identifiers
790+
importIDs := make(map[string]struct{})
791+
for _, r := range reservations {
792+
importIDs[r.ReservationID] = struct{}{}
793+
}
794+
azureResources = lo.Filter(azureResources, func(r *azureReservationResource, _ int) bool {
795+
_, ok := importIDs[r.ReservationID]
796+
return ok
797+
})
798+
}
799+
736800
if reservationsOk {
737801
sortCommitmentResources(azureResources, reservations)
738802
}

0 commit comments

Comments
 (0)