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

Commit1ef2a69

Browse files
authored
feat: add organization resource (#131)
1 parent03a98cd commit1ef2a69

File tree

7 files changed

+427
-5
lines changed

7 files changed

+427
-5
lines changed

‎Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
default: testacc
22

33
fmt:
4+
go fmt ./...
45
terraform fmt -recursive
56

7+
vet:
8+
go vet ./...
9+
610
gen:
711
go generate ./...
812

‎docs/resources/organization.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title:"coderd_organization Resource - terraform-provider-coderd"
4+
subcategory:""
5+
description:|-
6+
An organization on the Coder deployment
7+
---
8+
9+
#coderd_organization (Resource)
10+
11+
An organization on the Coder deployment
12+
13+
14+
15+
<!-- schema generated by tfplugindocs-->
16+
##Schema
17+
18+
###Required
19+
20+
-`name` (String) Name of the organization.
21+
22+
###Optional
23+
24+
-`description` (String)
25+
-`display_name` (String) Display name of the organization. Defaults to name.
26+
-`icon` (String)
27+
28+
###Read-Only
29+
30+
-`id` (String) Organization ID
31+
32+
##Import
33+
34+
Import is supported using the following syntax:
35+
36+
```shell
37+
# Organizations can be imported by their name
38+
terraform import coderd_organization.our_org our_org
39+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Organizations can be imported by their name
2+
terraform import coderd_organization.our_org our_org
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/coder/coder/v2/codersdk"
8+
"github.com/coder/terraform-provider-coderd/internal/codersdkvalidator"
9+
"github.com/hashicorp/terraform-plugin-framework/path"
10+
"github.com/hashicorp/terraform-plugin-framework/resource"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
13+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
14+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
15+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
16+
"github.com/hashicorp/terraform-plugin-framework/types"
17+
"github.com/hashicorp/terraform-plugin-log/tflog"
18+
)
19+
20+
// Ensure provider defined types fully satisfy framework interfaces.
21+
var_ resource.Resource=&OrganizationResource{}
22+
var_ resource.ResourceWithImportState=&OrganizationResource{}
23+
24+
typeOrganizationResourcestruct {
25+
*CoderdProviderData
26+
}
27+
28+
// OrganizationResourceModel describes the resource data model.
29+
typeOrganizationResourceModelstruct {
30+
IDUUID`tfsdk:"id"`
31+
32+
Name types.String`tfsdk:"name"`
33+
DisplayName types.String`tfsdk:"display_name"`
34+
Description types.String`tfsdk:"description"`
35+
Icon types.String`tfsdk:"icon"`
36+
}
37+
38+
funcNewOrganizationResource() resource.Resource {
39+
return&OrganizationResource{}
40+
}
41+
42+
func (r*OrganizationResource)Metadata(ctx context.Context,req resource.MetadataRequest,resp*resource.MetadataResponse) {
43+
resp.TypeName=req.ProviderTypeName+"_organization"
44+
}
45+
46+
func (r*OrganizationResource)Schema(ctx context.Context,req resource.SchemaRequest,resp*resource.SchemaResponse) {
47+
resp.Schema= schema.Schema{
48+
MarkdownDescription:"An organization on the Coder deployment",
49+
50+
Attributes:map[string]schema.Attribute{
51+
"id": schema.StringAttribute{
52+
CustomType:UUIDType,
53+
Computed:true,
54+
MarkdownDescription:"Organization ID",
55+
PlanModifiers: []planmodifier.String{
56+
stringplanmodifier.UseStateForUnknown(),
57+
},
58+
},
59+
"name": schema.StringAttribute{
60+
MarkdownDescription:"Name of the organization.",
61+
Required:true,
62+
Validators: []validator.String{
63+
codersdkvalidator.Name(),
64+
},
65+
},
66+
"display_name": schema.StringAttribute{
67+
MarkdownDescription:"Display name of the organization. Defaults to name.",
68+
Computed:true,
69+
Optional:true,
70+
Default:stringdefault.StaticString(""),
71+
Validators: []validator.String{
72+
codersdkvalidator.DisplayName(),
73+
},
74+
},
75+
"description": schema.StringAttribute{
76+
Optional:true,
77+
Computed:true,
78+
Default:stringdefault.StaticString(""),
79+
},
80+
"icon": schema.StringAttribute{
81+
Optional:true,
82+
Computed:true,
83+
Default:stringdefault.StaticString(""),
84+
},
85+
},
86+
}
87+
}
88+
89+
func (r*OrganizationResource)Configure(ctx context.Context,req resource.ConfigureRequest,resp*resource.ConfigureResponse) {
90+
// Prevent panic if the provider has not been configured.
91+
ifreq.ProviderData==nil {
92+
return
93+
}
94+
95+
data,ok:=req.ProviderData.(*CoderdProviderData)
96+
97+
if!ok {
98+
resp.Diagnostics.AddError(
99+
"Unable to configure provider data",
100+
fmt.Sprintf("Expected *CoderdProviderData, got: %T. Please report this issue to the provider developers.",req.ProviderData),
101+
)
102+
103+
return
104+
}
105+
106+
r.CoderdProviderData=data
107+
}
108+
109+
func (r*OrganizationResource)Read(ctx context.Context,req resource.ReadRequest,resp*resource.ReadResponse) {
110+
// Read Terraform prior state data into the model
111+
vardataOrganizationResourceModel
112+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
113+
ifresp.Diagnostics.HasError() {
114+
return
115+
}
116+
117+
varorg codersdk.Organization
118+
varerrerror
119+
ifdata.ID.IsNull() {
120+
orgName:=data.Name.ValueString()
121+
org,err=r.Client.OrganizationByName(ctx,orgName)
122+
iferr!=nil {
123+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to get organization by name, got error: %s",err))
124+
return
125+
}
126+
data.ID=UUIDValue(org.ID)
127+
}else {
128+
orgID:=data.ID.ValueUUID()
129+
org,err=r.Client.Organization(ctx,orgID)
130+
iferr!=nil {
131+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to get organization by ID, got error: %s",err))
132+
return
133+
}
134+
}
135+
136+
// We've fetched the organization ID from state, and the latest values for
137+
// everything else from the backend. Ensure that any mutable data is synced
138+
// with the backend.
139+
data.Name=types.StringValue(org.Name)
140+
data.DisplayName=types.StringValue(org.DisplayName)
141+
data.Description=types.StringValue(org.Description)
142+
data.Icon=types.StringValue(org.Icon)
143+
144+
// Save updated data into Terraform state
145+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
146+
}
147+
148+
func (r*OrganizationResource)Create(ctx context.Context,req resource.CreateRequest,resp*resource.CreateResponse) {
149+
// Read Terraform plan data into the model
150+
vardataOrganizationResourceModel
151+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
152+
ifresp.Diagnostics.HasError() {
153+
return
154+
}
155+
156+
tflog.Trace(ctx,"creating organization",map[string]any{
157+
"id":data.ID.ValueUUID(),
158+
"name":data.Name.ValueString(),
159+
"display_name":data.DisplayName.ValueString(),
160+
"description":data.Description.ValueString(),
161+
"icon":data.Icon.ValueString(),
162+
})
163+
org,err:=r.Client.CreateOrganization(ctx, codersdk.CreateOrganizationRequest{
164+
Name:data.Name.ValueString(),
165+
DisplayName:data.DisplayName.ValueString(),
166+
Description:data.Description.ValueString(),
167+
Icon:data.Icon.ValueString(),
168+
})
169+
iferr!=nil {
170+
resp.Diagnostics.AddError("Failed to create organization",err.Error())
171+
return
172+
}
173+
tflog.Trace(ctx,"successfully created organization",map[string]any{
174+
"id":org.ID,
175+
"name":org.Name,
176+
"display_name":org.DisplayName,
177+
"description":org.Description,
178+
"icon":org.Icon,
179+
})
180+
// Fill in `ID` since it must be "computed".
181+
data.ID=UUIDValue(org.ID)
182+
// We also fill in `DisplayName`, since it's optional but the backend will
183+
// default it.
184+
data.DisplayName=types.StringValue(org.DisplayName)
185+
186+
// Save data into Terraform state
187+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
188+
}
189+
190+
func (r*OrganizationResource)Update(ctx context.Context,req resource.UpdateRequest,resp*resource.UpdateResponse) {
191+
// Read Terraform plan data into the model
192+
vardataOrganizationResourceModel
193+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
194+
ifresp.Diagnostics.HasError() {
195+
return
196+
}
197+
198+
orgID:=data.ID.ValueUUID()
199+
200+
// Update the organization metadata
201+
tflog.Trace(ctx,"updating organization",map[string]any{
202+
"id":orgID,
203+
"new_name":data.Name.ValueString(),
204+
"new_display_name":data.DisplayName.ValueString(),
205+
"new_description":data.Description.ValueString(),
206+
"new_icon":data.Icon.ValueString(),
207+
})
208+
org,err:=r.Client.UpdateOrganization(ctx,orgID.String(), codersdk.UpdateOrganizationRequest{
209+
Name:data.Name.ValueString(),
210+
DisplayName:data.DisplayName.ValueString(),
211+
Description:data.Description.ValueStringPointer(),
212+
Icon:data.Icon.ValueStringPointer(),
213+
})
214+
iferr!=nil {
215+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to update organization %s, got error: %s",orgID,err))
216+
return
217+
}
218+
tflog.Trace(ctx,"successfully updated organization",map[string]any{
219+
"id":orgID,
220+
"name":org.Name,
221+
"display_name":org.DisplayName,
222+
"description":org.Description,
223+
"icon":org.Icon,
224+
})
225+
226+
// Save updated data into Terraform state
227+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
228+
}
229+
230+
func (r*OrganizationResource)Delete(ctx context.Context,req resource.DeleteRequest,resp*resource.DeleteResponse) {
231+
// Read Terraform prior state data into the model
232+
vardataOrganizationResourceModel
233+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
234+
ifresp.Diagnostics.HasError() {
235+
return
236+
}
237+
238+
orgID:=data.ID.ValueUUID()
239+
240+
tflog.Trace(ctx,"deleting organization",map[string]any{
241+
"id":orgID,
242+
"name":data.Name.ValueString(),
243+
})
244+
err:=r.Client.DeleteOrganization(ctx,orgID.String())
245+
iferr!=nil {
246+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to delete organization %s, got error: %s",orgID,err))
247+
return
248+
}
249+
tflog.Trace(ctx,"successfully deleted organization",map[string]any{
250+
"id":orgID,
251+
"name":data.Name.ValueString(),
252+
})
253+
254+
// Read Terraform prior state data into the model
255+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
256+
}
257+
258+
func (r*OrganizationResource)ImportState(ctx context.Context,req resource.ImportStateRequest,resp*resource.ImportStateResponse) {
259+
// Terraform will eventually `Read` in the rest of the fields after we have
260+
// set the `name` attribute.
261+
resource.ImportStatePassthroughID(ctx,path.Root("name"),req,resp)
262+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp