@@ -92,14 +92,15 @@ func findProjectVariableByID(variables []variables.TenantProjectVariable, id str
9292}
9393
9494func (t * tenantProjectVariableResource ) Create (ctx context.Context , req resource.CreateRequest , resp * resource.CreateResponse ) {
95- internal .Mutex .Lock ()
96- defer internal .Mutex .Unlock ()
9795 var plan tenantProjectVariableResourceModel
9896 resp .Diagnostics .Append (req .Plan .Get (ctx , & plan )... )
9997 if resp .Diagnostics .HasError () {
10098 return
10199 }
102100
101+ internal .KeyedMutex .Lock (plan .TenantID .ValueString ())
102+ defer internal .KeyedMutex .Unlock (plan .TenantID .ValueString ())
103+
103104 tflog .Debug (ctx , "Creating tenant project variable" )
104105
105106 // Validate that either environment_id or scope is provided, but not both
@@ -149,6 +150,47 @@ func (t *tenantProjectVariableResource) Create(ctx context.Context, req resource
149150 resp .Diagnostics .Append (resp .State .Set (ctx , & plan )... )
150151}
151152
153+ func (t * tenantProjectVariableResource ) createV1 (ctx context.Context , plan * tenantProjectVariableResourceModel , tenant * tenants.Tenant , hasEnvironmentID bool , resp * resource.CreateResponse ) {
154+ tflog .Debug (ctx , "Using V1 API for tenant project variable" )
155+
156+ if ! hasEnvironmentID {
157+ resp .Diagnostics .AddError ("Invalid configuration" , "environment_id is required for V1 API" )
158+ return
159+ }
160+
161+ id := fmt .Sprintf ("%s:%s:%s:%s" , plan .TenantID .ValueString (), plan .ProjectID .ValueString (), plan .EnvironmentID .ValueString (), plan .TemplateID .ValueString ())
162+
163+ tenantVariables , err := t .Client .Tenants .GetVariables (tenant )
164+ if err != nil {
165+ resp .Diagnostics .AddError ("Error retrieving tenant variables" , err .Error ())
166+ return
167+ }
168+
169+ isSensitive , err := checkIfVariableIsSensitive (tenantVariables , * plan )
170+ if err != nil {
171+ resp .Diagnostics .AddError ("Error checking if variable is sensitive" , err .Error ())
172+ return
173+ }
174+
175+ if err := updateTenantProjectVariable (tenantVariables , * plan , isSensitive ); err != nil {
176+ resp .Diagnostics .AddError ("Error updating tenant project variable" , err .Error ())
177+ return
178+ }
179+
180+ _ , err = t .Client .Tenants .UpdateVariables (tenant , tenantVariables )
181+ if err != nil {
182+ resp .Diagnostics .AddError ("Error updating tenant variables" , err .Error ())
183+ return
184+ }
185+
186+ plan .ID = types .StringValue (id )
187+ plan .SpaceID = types .StringValue (tenant .SpaceID )
188+
189+ tflog .Debug (ctx , "Tenant project variable created with V1 API" , map [string ]interface {}{
190+ "id" : plan .ID .ValueString (),
191+ })
192+ }
193+
152194func (t * tenantProjectVariableResource ) createV2 (ctx context.Context , plan * tenantProjectVariableResourceModel , tenant * tenants.Tenant , spaceID string , hasEnvironmentID bool , resp * resource.CreateResponse ) {
153195 tflog .Debug (ctx , "Using V2 API for tenant project variable" )
154196
@@ -193,7 +235,7 @@ func (t *tenantProjectVariableResource) createV2(ctx context.Context, plan *tena
193235 }
194236
195237 // Build payloads for ALL existing variables plus the new one
196- var payloads []variables.TenantProjectVariablePayload
238+ payloads := []variables.TenantProjectVariablePayload {}
197239
198240 // Add all existing variables
199241 for _ , v := range getResp .Variables {
@@ -229,8 +271,29 @@ func (t *tenantProjectVariableResource) createV2(ctx context.Context, plan *tena
229271 var createdID string
230272 for _ , v := range updateResp .Variables {
231273 if v .ProjectID == plan .ProjectID .ValueString () && v .TemplateID == plan .TemplateID .ValueString () {
232- createdID = v .GetID ()
233- break
274+ // Also match on scope to handle multiple variables with same template but different scopes
275+ if len (plan .Scope ) > 0 {
276+ if len (v .Scope .EnvironmentIds ) > 0 {
277+ planEnvs := plan .Scope [0 ].EnvironmentIDs .Elements ()
278+ if len (planEnvs ) == len (v .Scope .EnvironmentIds ) {
279+ match := true
280+ planEnvSet := make (map [string ]bool )
281+ for _ , e := range planEnvs {
282+ planEnvSet [e .String ()] = true
283+ }
284+ for _ , serverEnv := range v .Scope .EnvironmentIds {
285+ if ! planEnvSet ["\" " + serverEnv + "\" " ] {
286+ match = false
287+ break
288+ }
289+ }
290+ if match {
291+ createdID = v .GetID ()
292+ break
293+ }
294+ }
295+ }
296+ }
234297 }
235298 }
236299
@@ -254,57 +317,16 @@ func (t *tenantProjectVariableResource) createV2(ctx context.Context, plan *tena
254317 })
255318}
256319
257- func (t * tenantProjectVariableResource ) createV1 (ctx context.Context , plan * tenantProjectVariableResourceModel , tenant * tenants.Tenant , hasEnvironmentID bool , resp * resource.CreateResponse ) {
258- tflog .Debug (ctx , "Using V1 API for tenant project variable" )
259-
260- if ! hasEnvironmentID {
261- resp .Diagnostics .AddError ("Invalid configuration" , "environment_id is required for V1 API" )
262- return
263- }
264-
265- id := fmt .Sprintf ("%s:%s:%s:%s" , plan .TenantID .ValueString (), plan .ProjectID .ValueString (), plan .EnvironmentID .ValueString (), plan .TemplateID .ValueString ())
266-
267- tenantVariables , err := t .Client .Tenants .GetVariables (tenant )
268- if err != nil {
269- resp .Diagnostics .AddError ("Error retrieving tenant variables" , err .Error ())
270- return
271- }
272-
273- isSensitive , err := checkIfVariableIsSensitive (tenantVariables , * plan )
274- if err != nil {
275- resp .Diagnostics .AddError ("Error checking if variable is sensitive" , err .Error ())
276- return
277- }
278-
279- if err := updateTenantProjectVariable (tenantVariables , * plan , isSensitive ); err != nil {
280- resp .Diagnostics .AddError ("Error updating tenant project variable" , err .Error ())
281- return
282- }
283-
284- _ , err = t .Client .Tenants .UpdateVariables (tenant , tenantVariables )
285- if err != nil {
286- resp .Diagnostics .AddError ("Error updating tenant variables" , err .Error ())
287- return
288- }
289-
290- plan .ID = types .StringValue (id )
291- plan .SpaceID = types .StringValue (tenant .SpaceID )
292-
293- tflog .Debug (ctx , "Tenant project variable created with V1 API" , map [string ]interface {}{
294- "id" : plan .ID .ValueString (),
295- })
296- }
297-
298320func (t * tenantProjectVariableResource ) Read (ctx context.Context , req resource.ReadRequest , resp * resource.ReadResponse ) {
299- internal .Mutex .Lock ()
300- defer internal .Mutex .Unlock ()
301-
302321 var state tenantProjectVariableResourceModel
303322 resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
304323 if resp .Diagnostics .HasError () {
305324 return
306325 }
307326
327+ internal .KeyedMutex .Lock (state .TenantID .ValueString ())
328+ defer internal .KeyedMutex .Unlock (state .TenantID .ValueString ())
329+
308330 tenant , err := tenants .GetByID (t .Client , state .SpaceID .ValueString (), state .TenantID .ValueString ())
309331 if err != nil {
310332 resp .Diagnostics .AddError ("Error retrieving tenant" , err .Error ())
@@ -482,15 +504,15 @@ func (t *tenantProjectVariableResource) migrateV1ToV2OnRead(ctx context.Context,
482504}
483505
484506func (t * tenantProjectVariableResource ) Update (ctx context.Context , req resource.UpdateRequest , resp * resource.UpdateResponse ) {
485- internal .Mutex .Lock ()
486- defer internal .Mutex .Unlock ()
487-
488507 var plan tenantProjectVariableResourceModel
489508 resp .Diagnostics .Append (req .Plan .Get (ctx , & plan )... )
490509 if resp .Diagnostics .HasError () {
491510 return
492511 }
493512
513+ internal .KeyedMutex .Lock (plan .TenantID .ValueString ())
514+ defer internal .KeyedMutex .Unlock (plan .TenantID .ValueString ())
515+
494516 // Validate that either environment_id or scope is provided, but not both
495517 hasEnvironmentID := ! plan .EnvironmentID .IsNull () && plan .EnvironmentID .ValueString () != ""
496518 hasScope := len (plan .Scope ) > 0
@@ -575,7 +597,7 @@ func (t *tenantProjectVariableResource) updateV2(ctx context.Context, plan *tena
575597 scope .EnvironmentIds = []string {plan .EnvironmentID .ValueString ()}
576598 }
577599
578- var payloads []variables.TenantProjectVariablePayload
600+ payloads := []variables.TenantProjectVariablePayload {}
579601
580602 for _ , v := range getResp .Variables {
581603 if v .GetID () == plan .ID .ValueString () {
@@ -676,7 +698,7 @@ func (t *tenantProjectVariableResource) migrateV1ToV2OnUpdate(ctx context.Contex
676698 scope .EnvironmentIds = []string {plan .EnvironmentID .ValueString ()}
677699 }
678700
679- var payloads []variables.TenantProjectVariablePayload
701+ payloads := []variables.TenantProjectVariablePayload {}
680702
681703 for _ , v := range getResp .Variables {
682704 if v .ProjectID == plan .ProjectID .ValueString () && v .TemplateID == plan .TemplateID .ValueString () {
@@ -737,15 +759,15 @@ func (t *tenantProjectVariableResource) migrateV1ToV2OnUpdate(ctx context.Contex
737759}
738760
739761func (t * tenantProjectVariableResource ) Delete (ctx context.Context , req resource.DeleteRequest , resp * resource.DeleteResponse ) {
740- internal .Mutex .Lock ()
741- defer internal .Mutex .Unlock ()
742-
743762 var state tenantProjectVariableResourceModel
744763 resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
745764 if resp .Diagnostics .HasError () {
746765 return
747766 }
748767
768+ internal .KeyedMutex .Lock (state .TenantID .ValueString ())
769+ defer internal .KeyedMutex .Unlock (state .TenantID .ValueString ())
770+
749771 tenant , err := tenants .GetByID (t .Client , state .SpaceID .ValueString (), state .TenantID .ValueString ())
750772 if err != nil {
751773 resp .Diagnostics .AddError ("Error retrieving tenant" , err .Error ())
@@ -757,8 +779,8 @@ func (t *tenantProjectVariableResource) Delete(ctx context.Context, req resource
757779 spaceID = tenant .SpaceID
758780 }
759781
760- useV1API := isCompositeID (state .ID .ValueString ())
761- if ! useV1API {
782+ isV1ID := isCompositeID (state .ID .ValueString ())
783+ if ! isV1ID {
762784 t .deleteV2 (ctx , & state , spaceID , resp )
763785 } else {
764786 t .deleteV1 (ctx , & state , tenant , resp )
@@ -786,7 +808,7 @@ func (t *tenantProjectVariableResource) deleteV2(ctx context.Context, state *ten
786808 return
787809 }
788810
789- var payloads []variables.TenantProjectVariablePayload
811+ payloads := []variables.TenantProjectVariablePayload {}
790812
791813 for _ , v := range getResp .Variables {
792814 if v .GetID () == state .ID .ValueString () {
0 commit comments