Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5fa9117

Browse files
authored
feat: addcoderd_organization_sync_settings resource (#173)
1 parent34f115d commit5fa9117

File tree

5 files changed

+442
-0
lines changed

5 files changed

+442
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title:"coderd_organization_sync_settings Resource - terraform-provider-coderd"
4+
subcategory:""
5+
description:|-
6+
IdP sync settings for organizations.
7+
This resource can only be created once. Attempts to create multiple will fail.
8+
~> Warning
9+
This resource is only compatible with Coder version 2.19.0 https://github.com/coder/coder/releases/tag/v2.19.0 and later.
10+
---
11+
12+
#coderd_organization_sync_settings (Resource)
13+
14+
IdP sync settings for organizations.
15+
16+
This resource can only be created once. Attempts to create multiple will fail.
17+
18+
~>**Warning**
19+
This resource is only compatible with Coder version[2.19.0](https://github.com/coder/coder/releases/tag/v2.19.0) and later.
20+
21+
##Example Usage
22+
23+
```terraform
24+
// Important note: You can only have one resource of this type!
25+
resource "coderd_organization_sync_settings" "org_sync" {
26+
field = "wibble"
27+
assign_default = false
28+
29+
mapping = {
30+
wobble = [
31+
coderd_organization.my_organization.id,
32+
]
33+
}
34+
}
35+
```
36+
37+
<!-- schema generated by tfplugindocs-->
38+
##Schema
39+
40+
###Required
41+
42+
-`assign_default` (Boolean) When true, every user will be added to the default organization, regardless of claims.
43+
-`field` (String) The claim field that specifies what organizations a user should be in.
44+
45+
###Optional
46+
47+
-`mapping` (Map of List of String) A map from OIDC group name to Coder organization ID.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Important note: You can only have one resource of this type!
2+
resource"coderd_organization_sync_settings""org_sync" {
3+
field="wibble"
4+
assign_default=false
5+
6+
mapping={
7+
wobble= [
8+
coderd_organization.my_organization.id,
9+
]
10+
}
11+
}
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/coder/coder/v2/codersdk"
8+
"github.com/google/uuid"
9+
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
10+
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
"github.com/hashicorp/terraform-plugin-framework/resource"
12+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
13+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
14+
"github.com/hashicorp/terraform-plugin-framework/types"
15+
"github.com/hashicorp/terraform-plugin-log/tflog"
16+
)
17+
18+
// Ensure provider defined types fully satisfy framework interfaces.
19+
var_ resource.Resource=&OrganizationSyncSettingsResource{}
20+
21+
typeOrganizationSyncSettingsResourcestruct {
22+
*CoderdProviderData
23+
}
24+
25+
// OrganizationSyncSettingsResourceModel describes the resource data model.
26+
typeOrganizationSyncSettingsResourceModelstruct {
27+
Field types.String`tfsdk:"field"`
28+
AssignDefault types.Bool`tfsdk:"assign_default"`
29+
Mapping types.Map`tfsdk:"mapping"`
30+
}
31+
32+
funcNewOrganizationSyncSettingsResource() resource.Resource {
33+
return&OrganizationSyncSettingsResource{}
34+
}
35+
36+
func (r*OrganizationSyncSettingsResource)Metadata(ctx context.Context,req resource.MetadataRequest,resp*resource.MetadataResponse) {
37+
resp.TypeName=req.ProviderTypeName+"_organization_sync_settings"
38+
}
39+
40+
func (r*OrganizationSyncSettingsResource)Schema(ctx context.Context,req resource.SchemaRequest,resp*resource.SchemaResponse) {
41+
resp.Schema= schema.Schema{
42+
MarkdownDescription:`IdP sync settings for organizations.
43+
44+
This resource can only be created once. Attempts to create multiple will fail.
45+
46+
~> **Warning**
47+
This resource is only compatible with Coder version [2.19.0](https://github.com/coder/coder/releases/tag/v2.19.0) and later.
48+
`,
49+
Attributes:map[string]schema.Attribute{
50+
"field": schema.StringAttribute{
51+
Required:true,
52+
MarkdownDescription:"The claim field that specifies what organizations "+
53+
"a user should be in.",
54+
Validators: []validator.String{
55+
stringvalidator.LengthAtLeast(1),
56+
},
57+
},
58+
"assign_default": schema.BoolAttribute{
59+
Required:true,
60+
MarkdownDescription:"When true, every user will be added to the default "+
61+
"organization, regardless of claims.",
62+
},
63+
"mapping": schema.MapAttribute{
64+
ElementType: types.ListType{ElemType:UUIDType},
65+
Optional:true,
66+
MarkdownDescription:"A map from OIDC group name to Coder organization ID.",
67+
},
68+
},
69+
}
70+
}
71+
72+
func (r*OrganizationSyncSettingsResource)Configure(ctx context.Context,req resource.ConfigureRequest,resp*resource.ConfigureResponse) {
73+
// Prevent panic if the provider has not been configured.
74+
ifreq.ProviderData==nil {
75+
return
76+
}
77+
78+
data,ok:=req.ProviderData.(*CoderdProviderData)
79+
80+
if!ok {
81+
resp.Diagnostics.AddError(
82+
"Unable to configure provider data",
83+
fmt.Sprintf("Expected *CoderdProviderData, got: %T. Please report this issue to the provider developers.",req.ProviderData),
84+
)
85+
86+
return
87+
}
88+
89+
r.CoderdProviderData=data
90+
}
91+
92+
func (r*OrganizationSyncSettingsResource)Read(ctx context.Context,req resource.ReadRequest,resp*resource.ReadResponse) {
93+
// Read Terraform prior state data into the model
94+
vardataOrganizationSyncSettingsResourceModel
95+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
96+
ifresp.Diagnostics.HasError() {
97+
return
98+
}
99+
100+
settings,err:=r.Client.OrganizationIDPSyncSettings(ctx)
101+
iferr!=nil {
102+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("unable to get organization sync settings, got error: %s",err))
103+
return
104+
}
105+
106+
// Store the latest values that we just fetched.
107+
data.Field=types.StringValue(settings.Field)
108+
data.AssignDefault=types.BoolValue(settings.AssignDefault)
109+
110+
if!data.Mapping.IsNull() {
111+
// Convert IDs to strings
112+
elements:=make(map[string][]string)
113+
forkey,ids:=rangesettings.Mapping {
114+
for_,id:=rangeids {
115+
elements[key]=append(elements[key],id.String())
116+
}
117+
}
118+
119+
mapping,diags:=types.MapValueFrom(ctx, types.ListType{ElemType:UUIDType},elements)
120+
resp.Diagnostics.Append(diags...)
121+
ifresp.Diagnostics.HasError() {
122+
return
123+
}
124+
data.Mapping=mapping
125+
}
126+
127+
// Save updated data into Terraform state
128+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
129+
}
130+
131+
func (r*OrganizationSyncSettingsResource)Create(ctx context.Context,req resource.CreateRequest,resp*resource.CreateResponse) {
132+
// Read Terraform plan data into the model
133+
vardataOrganizationSyncSettingsResourceModel
134+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
135+
ifresp.Diagnostics.HasError() {
136+
return
137+
}
138+
139+
tflog.Trace(ctx,"creating organization sync",map[string]any{
140+
"field":data.Field.ValueString(),
141+
"assign_default":data.AssignDefault.ValueBool(),
142+
})
143+
144+
// Create and Update use a shared implementation
145+
resp.Diagnostics.Append(r.patch(ctx,data)...)
146+
ifresp.Diagnostics.HasError() {
147+
return
148+
}
149+
150+
tflog.Trace(ctx,"successfully created organization sync",map[string]any{
151+
"field":data.Field.ValueString(),
152+
"assign_default":data.AssignDefault.ValueBool(),
153+
})
154+
155+
// Save data into Terraform state
156+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
157+
}
158+
159+
func (r*OrganizationSyncSettingsResource)Update(ctx context.Context,req resource.UpdateRequest,resp*resource.UpdateResponse) {
160+
// Read Terraform plan data into the model
161+
vardataOrganizationSyncSettingsResourceModel
162+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
163+
ifresp.Diagnostics.HasError() {
164+
return
165+
}
166+
167+
// Update the organization metadata
168+
tflog.Trace(ctx,"updating organization",map[string]any{
169+
"field":data.Field.ValueString(),
170+
"assign_default":data.AssignDefault.ValueBool(),
171+
})
172+
173+
// Create and Update use a shared implementation
174+
resp.Diagnostics.Append(r.patch(ctx,data)...)
175+
ifresp.Diagnostics.HasError() {
176+
return
177+
}
178+
179+
tflog.Trace(ctx,"successfully updated organization",map[string]any{
180+
"field":data.Field.ValueString(),
181+
"assign_default":data.AssignDefault.ValueBool(),
182+
})
183+
184+
// Save updated data into Terraform state
185+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
186+
}
187+
188+
func (r*OrganizationSyncSettingsResource)patch(
189+
ctx context.Context,
190+
dataOrganizationSyncSettingsResourceModel,
191+
) diag.Diagnostics {
192+
vardiags diag.Diagnostics
193+
field:=data.Field.ValueString()
194+
assignDefault:=data.AssignDefault.ValueBool()
195+
196+
ifdata.Mapping.IsNull() {
197+
_,err:=r.Client.PatchOrganizationIDPSyncConfig(ctx, codersdk.PatchOrganizationIDPSyncConfigRequest{
198+
Field:field,
199+
AssignDefault:assignDefault,
200+
})
201+
202+
iferr!=nil {
203+
diags.AddError("failed to create organization sync",err.Error())
204+
returndiags
205+
}
206+
}else {
207+
settings:= codersdk.OrganizationSyncSettings{
208+
Field:field,
209+
AssignDefault:assignDefault,
210+
Mapping:map[string][]uuid.UUID{},
211+
}
212+
213+
// Terraform doesn't know how to turn one our `UUID` Terraform values into a
214+
// `uuid.UUID`, so we have to do the unwrapping manually here.
215+
varmappingmap[string][]UUID
216+
diags.Append(data.Mapping.ElementsAs(ctx,&mapping,false)...)
217+
ifdiags.HasError() {
218+
returndiags
219+
}
220+
forkey,ids:=rangemapping {
221+
for_,id:=rangeids {
222+
settings.Mapping[key]=append(settings.Mapping[key],id.ValueUUID())
223+
}
224+
}
225+
226+
_,err:=r.Client.PatchOrganizationIDPSyncSettings(ctx,settings)
227+
iferr!=nil {
228+
diags.AddError("failed to create organization sync",err.Error())
229+
returndiags
230+
}
231+
}
232+
233+
returndiags
234+
}
235+
236+
func (r*OrganizationSyncSettingsResource)Delete(ctx context.Context,req resource.DeleteRequest,resp*resource.DeleteResponse) {
237+
// Read Terraform prior state data into the model
238+
vardataOrganizationSyncSettingsResourceModel
239+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
240+
ifresp.Diagnostics.HasError() {
241+
return
242+
}
243+
244+
tflog.Trace(ctx,"deleting organization sync",map[string]any{})
245+
_,err:=r.Client.PatchOrganizationIDPSyncConfig(ctx, codersdk.PatchOrganizationIDPSyncConfigRequest{
246+
// This disables organization sync without causing state conflicts for
247+
// organization resources that might still specify `sync_mapping`.
248+
Field:"",
249+
})
250+
iferr!=nil {
251+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("unable to delete organization sync, got error: %s",err))
252+
return
253+
}
254+
tflog.Trace(ctx,"successfully deleted organization sync",map[string]any{})
255+
256+
// Read Terraform prior state data into the model
257+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
258+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp