5
5
"fmt"
6
6
"regexp"
7
7
8
+ "github.com/coder/coder/v2/coderd/util/slice"
8
9
"github.com/coder/coder/v2/codersdk"
9
10
"github.com/coder/terraform-provider-coderd/internal/codersdkvalidator"
10
11
"github.com/google/uuid"
@@ -40,8 +41,9 @@ type OrganizationResourceModel struct {
40
41
Description types.String `tfsdk:"description"`
41
42
Icon types.String `tfsdk:"icon"`
42
43
43
- GroupSync types.Object `tfsdk:"group_sync"`
44
- RoleSync types.Object `tfsdk:"role_sync"`
44
+ OrgSyncIdpGroups types.Set `tfsdk:"org_sync_idp_groups"`
45
+ GroupSync types.Object `tfsdk:"group_sync"`
46
+ RoleSync types.Object `tfsdk:"role_sync"`
45
47
}
46
48
47
49
type GroupSyncModel struct {
@@ -134,6 +136,12 @@ This resource is only compatible with Coder version [2.16.0](https://github.com/
134
136
Computed : true ,
135
137
Default : stringdefault .StaticString ("" ),
136
138
},
139
+
140
+ "org_sync_idp_groups" : schema.SetAttribute {
141
+ ElementType : types .StringType ,
142
+ Optional : true ,
143
+ MarkdownDescription : "Claims from the IdP provider that will give users access to this organization." ,
144
+ },
137
145
},
138
146
139
147
Blocks : map [string ]schema.Block {
@@ -361,21 +369,38 @@ func (r *OrganizationResource) Create(ctx context.Context, req resource.CreateRe
361
369
// default it.
362
370
data .DisplayName = types .StringValue (org .DisplayName )
363
371
364
- // Now apply group and role sync settings, if specified
365
372
orgID := data .ID .ValueUUID ()
366
- tflog .Trace (ctx , "updating group sync" , map [string ]any {
367
- "orgID" : orgID ,
368
- })
373
+
374
+ // Apply org sync patches, if specified
375
+ if ! data .OrgSyncIdpGroups .IsNull () {
376
+ tflog .Trace (ctx , "updating org sync" , map [string ]any {
377
+ "orgID" : orgID ,
378
+ })
379
+
380
+ var claims []string
381
+ resp .Diagnostics .Append (data .OrgSyncIdpGroups .ElementsAs (ctx , & claims , false )... )
382
+ if resp .Diagnostics .HasError () {
383
+ return
384
+ }
385
+
386
+ resp .Diagnostics .Append (r .patchOrgSyncMapping (ctx , orgID , []string {}, claims )... )
387
+ }
388
+
389
+ // Apply group and role sync settings, if specified
369
390
if ! data .GroupSync .IsNull () {
391
+ tflog .Trace (ctx , "updating group sync" , map [string ]any {
392
+ "orgID" : orgID ,
393
+ })
394
+
370
395
resp .Diagnostics .Append (r .patchGroupSync (ctx , orgID , data .GroupSync )... )
371
396
if resp .Diagnostics .HasError () {
372
397
return
373
398
}
374
399
}
375
- tflog .Trace (ctx , "updating role sync" , map [string ]any {
376
- "orgID" : orgID ,
377
- })
378
400
if ! data .RoleSync .IsNull () {
401
+ tflog .Trace (ctx , "updating role sync" , map [string ]any {
402
+ "orgID" : orgID ,
403
+ })
379
404
resp .Diagnostics .Append (r .patchRoleSync (ctx , orgID , data .RoleSync )... )
380
405
if resp .Diagnostics .HasError () {
381
406
return
@@ -423,19 +448,42 @@ func (r *OrganizationResource) Update(ctx context.Context, req resource.UpdateRe
423
448
"icon" : org .Icon ,
424
449
})
425
450
426
- tflog .Trace (ctx , "updating group sync" , map [string ]any {
427
- "orgID" : orgID ,
428
- })
451
+ // Apply org sync patches, if specified
452
+ if ! data .OrgSyncIdpGroups .IsNull () {
453
+ tflog .Trace (ctx , "updating org sync mappings" , map [string ]any {
454
+ "orgID" : orgID ,
455
+ })
456
+
457
+ var state OrganizationResourceModel
458
+ resp .Diagnostics .Append (req .State .Get (ctx , & state )... )
459
+ var currentClaims []string
460
+ resp .Diagnostics .Append (state .OrgSyncIdpGroups .ElementsAs (ctx , & currentClaims , false )... )
461
+
462
+ var plannedClaims []string
463
+ resp .Diagnostics .Append (data .OrgSyncIdpGroups .ElementsAs (ctx , & plannedClaims , false )... )
464
+ if resp .Diagnostics .HasError () {
465
+ return
466
+ }
467
+
468
+ resp .Diagnostics .Append (r .patchOrgSyncMapping (ctx , orgID , currentClaims , plannedClaims )... )
469
+ if resp .Diagnostics .HasError () {
470
+ return
471
+ }
472
+ }
473
+
429
474
if ! data .GroupSync .IsNull () {
475
+ tflog .Trace (ctx , "updating group sync" , map [string ]any {
476
+ "orgID" : orgID ,
477
+ })
430
478
resp .Diagnostics .Append (r .patchGroupSync (ctx , orgID , data .GroupSync )... )
431
479
if resp .Diagnostics .HasError () {
432
480
return
433
481
}
434
482
}
435
- tflog .Trace (ctx , "updating role sync" , map [string ]any {
436
- "orgID" : orgID ,
437
- })
438
483
if ! data .RoleSync .IsNull () {
484
+ tflog .Trace (ctx , "updating role sync" , map [string ]any {
485
+ "orgID" : orgID ,
486
+ })
439
487
resp .Diagnostics .Append (r .patchRoleSync (ctx , orgID , data .RoleSync )... )
440
488
if resp .Diagnostics .HasError () {
441
489
return
@@ -456,6 +504,21 @@ func (r *OrganizationResource) Delete(ctx context.Context, req resource.DeleteRe
456
504
457
505
orgID := data .ID .ValueUUID ()
458
506
507
+ // Remove org sync mappings, if we were managing them
508
+ if ! data .OrgSyncIdpGroups .IsNull () {
509
+ tflog .Trace (ctx , "deleting org sync mappings" , map [string ]any {
510
+ "orgID" : orgID ,
511
+ })
512
+
513
+ var claims []string
514
+ resp .Diagnostics .Append (data .OrgSyncIdpGroups .ElementsAs (ctx , & claims , false )... )
515
+ if resp .Diagnostics .HasError () {
516
+ return
517
+ }
518
+
519
+ resp .Diagnostics .Append (r .patchOrgSyncMapping (ctx , orgID , claims , []string {})... )
520
+ }
521
+
459
522
tflog .Trace (ctx , "deleting organization" , map [string ]any {
460
523
"id" : orgID ,
461
524
"name" : data .Name .ValueString (),
@@ -554,3 +617,37 @@ func (r *OrganizationResource) patchRoleSync(
554
617
555
618
return diags
556
619
}
620
+
621
+ func (r * OrganizationResource ) patchOrgSyncMapping (
622
+ ctx context.Context ,
623
+ orgID uuid.UUID ,
624
+ currentClaims , plannedClaims []string ,
625
+ ) diag.Diagnostics {
626
+ var diags diag.Diagnostics
627
+
628
+ add , remove := slice .SymmetricDifference (currentClaims , plannedClaims )
629
+ var addMappings []codersdk.IDPSyncMapping [uuid.UUID ]
630
+ for _ , claim := range add {
631
+ addMappings = append (addMappings , codersdk.IDPSyncMapping [uuid.UUID ]{
632
+ Given : claim ,
633
+ Gets : orgID ,
634
+ })
635
+ }
636
+ var removeMappings []codersdk.IDPSyncMapping [uuid.UUID ]
637
+ for _ , claim := range remove {
638
+ removeMappings = append (removeMappings , codersdk.IDPSyncMapping [uuid.UUID ]{
639
+ Given : claim ,
640
+ Gets : orgID ,
641
+ })
642
+ }
643
+
644
+ _ , err := r .Client .PatchOrganizationIDPSyncMapping (ctx , codersdk.PatchOrganizationIDPSyncMappingRequest {
645
+ Add : addMappings ,
646
+ Remove : removeMappings ,
647
+ })
648
+ if err != nil {
649
+ diags .AddError ("Org Sync Update error" , err .Error ())
650
+ }
651
+
652
+ return diags
653
+ }
0 commit comments