Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 39da842

Browse files
committedNov 25, 2024·
Merge branch 'main' into lilac/idp-sync
2 parents 93f476b + e90acf0 commit 39da842

File tree

15 files changed

+380
-38
lines changed

15 files changed

+380
-38
lines changed
 

‎.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
with:
2727
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
2828
- name: Run GoReleaser
29-
uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
29+
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
3030
with:
3131
version: latest
3232
args: release --clean

‎.github/workflows/test.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ jobs:
5454

5555
- name: git diff
5656
run: |
57-
git diff --compact-summary --exit-code || \
58-
(echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1)
57+
if [[ -n $(git ls-files --other --modified --exclude-standard) ]]; then
58+
echo "Unexpected difference in directories after code generation. Run 'make gen' and include the output in the commit."
59+
exit 1
60+
fi
5961
6062
# Run acceptance tests in a matrix with Terraform CLI versions
6163
test:

‎docs/resources/license.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,29 @@ page_title: "coderd_license Resource - terraform-provider-coderd"
44
subcategory: ""
55
description: |-
66
A license for a Coder deployment.
7-
It's recommended to create multiple instances of this resource when updating a license. Modifying an existing license will cause the resource to be replaced, which may result in a brief unlicensed period.
7+
It's recommended to set create_before_destroy https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#create_before_destroy on license resources. Without setting this, Terraform will remove the old license before adding the updated license. This will result in a temporary disruption to your users; during which they may be unable to use features that require a license.
88
Terraform does not guarantee this resource will be created before other resources or attributes that require a licensed deployment. The depends_on meta-argument is instead recommended.
99
---
1010

1111
# coderd_license (Resource)
1212

1313
A license for a Coder deployment.
1414

15-
It's recommended to create multiple instances of this resource when updating a license. Modifying an existing license will cause the resource to be replaced, which may result in a brief unlicensed period.
15+
It's recommended to set [`create_before_destroy`](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#create_before_destroy) on license resources. Without setting this, Terraform will remove the old license before adding the updated license. This will result in a temporary disruption to your users; during which they may be unable to use features that require a license.
1616

1717
Terraform does not guarantee this resource will be created before other resources or attributes that require a licensed deployment. The `depends_on` meta-argument is instead recommended.
1818

19+
## Example Usage
1920

21+
```terraform
22+
resource "coderd_license" "license" {
23+
license = "<…>"
24+
25+
lifecycle {
26+
create_before_destroy = true
27+
}
28+
}
29+
```
2030

2131
<!-- schema generated by tfplugindocs -->
2232
## Schema

‎docs/resources/provisioner_key.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "coderd_provisioner_key Resource - terraform-provider-coderd"
4+
subcategory: ""
5+
description: |-
6+
A provisioner key for a Coder deployment.
7+
---
8+
9+
# coderd_provisioner_key (Resource)
10+
11+
A provisioner key for a Coder deployment.
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `name` (String) The name of the key.
21+
- `organization_id` (String) The organization that provisioners connected with this key will be connected to.
22+
23+
### Optional
24+
25+
- `tags` (Map of String) The tags that provisioners connected with this key will accept jobs for.
26+
27+
### Read-Only
28+
29+
- `key` (String, Sensitive) The acquired provisioner key
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
resource "coderd_license" "license" {
2+
license = "<…>"
3+
4+
lifecycle {
5+
create_before_destroy = true
6+
}
7+
}

‎go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/docker/docker v27.2.1+incompatible
99
github.com/docker/go-connections v0.5.0
1010
github.com/google/uuid v1.6.0
11-
github.com/hashicorp/terraform-plugin-docs v0.19.4
11+
github.com/hashicorp/terraform-plugin-docs v0.20.0
1212
github.com/hashicorp/terraform-plugin-framework v1.13.0
1313
github.com/hashicorp/terraform-plugin-framework-validators v0.15.0
1414
github.com/hashicorp/terraform-plugin-go v0.25.0
@@ -40,7 +40,7 @@ require (
4040
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
4141
github.com/beorn7/perks v1.0.1 // indirect
4242
github.com/bgentry/speakeasy v0.2.0 // indirect
43-
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
43+
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
4444
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
4545
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4646
github.com/cloudflare/circl v1.3.7 // indirect
@@ -83,7 +83,7 @@ require (
8383
github.com/hashicorp/hcl/v2 v2.22.0 // indirect
8484
github.com/hashicorp/logutils v1.0.0 // indirect
8585
github.com/hashicorp/terraform-exec v0.21.0 // indirect
86-
github.com/hashicorp/terraform-json v0.22.1 // indirect
86+
github.com/hashicorp/terraform-json v0.23.0 // indirect
8787
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect
8888
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
8989
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
@@ -133,7 +133,7 @@ require (
133133
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
134134
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
135135
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
136-
github.com/yuin/goldmark v1.7.4 // indirect
136+
github.com/yuin/goldmark v1.7.7 // indirect
137137
github.com/yuin/goldmark-meta v1.1.0 // indirect
138138
github.com/zclconf/go-cty v1.15.0 // indirect
139139
github.com/zeebo/errs v1.3.0 // indirect

‎go.sum

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
6262
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
6363
github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E=
6464
github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
65-
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
66-
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
65+
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
66+
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
6767
github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E=
6868
github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs=
6969
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@@ -249,10 +249,10 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
249249
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
250250
github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ=
251251
github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg=
252-
github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec=
253-
github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A=
254-
github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c=
255-
github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA=
252+
github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI=
253+
github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c=
254+
github.com/hashicorp/terraform-plugin-docs v0.20.0 h1:ox7rm1FN0dVZaJBUzkVVh10R1r3+FeMQWL0QopQ9d7o=
255+
github.com/hashicorp/terraform-plugin-docs v0.20.0/go.mod h1:A/+4SVMdAkQYtIBtaxV0H7AU862TxVZk/hhKaMDQB6Y=
256256
github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw=
257257
github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU=
258258
github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 h1:RXMmu7JgpFjnI1a5QjMCBb11usrW2OtAG+iOTIj5c9Y=
@@ -413,8 +413,8 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
413413
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
414414
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
415415
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
416-
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
417-
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
416+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
417+
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
418418
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
419419
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
420420
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
@@ -489,8 +489,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
489489
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
490490
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
491491
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
492-
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
493-
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
492+
github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU=
493+
github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
494494
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
495495
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
496496
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=

‎internal/provider/license_resource.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ func (r *LicenseResource) Metadata(ctx context.Context, req resource.MetadataReq
3939

4040
func (r *LicenseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
4141
resp.Schema = schema.Schema{
42-
MarkdownDescription: "A license for a Coder deployment.\n\nIt's recommended to create multiple instances of this " +
43-
"resource when updating a license. Modifying an existing license will cause the resource to be replaced, " +
44-
"which may result in a brief unlicensed period.\n\n" +
42+
MarkdownDescription: "A license for a Coder deployment.\n\nIt's recommended to set " +
43+
"[`create_before_destroy`](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#create_before_destroy) " +
44+
"on license resources. Without setting this, Terraform will remove the old " +
45+
"license before adding the updated license. This will result in a temporary " +
46+
"disruption to your users; during which they may be unable to use features " +
47+
"that require a license.\n\n" +
4548
"Terraform does not guarantee this resource " +
4649
"will be created before other resources or attributes that require a licensed deployment. " +
4750
"The `depends_on` meta-argument is instead recommended.",

‎internal/provider/license_resource_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestAccLicenseResource(t *testing.T) {
2424
t.Skip("No license found for license resource tests, skipping")
2525
}
2626

27-
cfg1 := testAccLicenseResourceconfig{
27+
cfg1 := testAccLicenseResourceConfig{
2828
URL: client.URL.String(),
2929
Token: client.SessionToken(),
3030
License: license,
@@ -42,13 +42,13 @@ func TestAccLicenseResource(t *testing.T) {
4242
})
4343
}
4444

45-
type testAccLicenseResourceconfig struct {
45+
type testAccLicenseResourceConfig struct {
4646
URL string
4747
Token string
4848
License string
4949
}
5050

51-
func (c testAccLicenseResourceconfig) String(t *testing.T) string {
51+
func (c testAccLicenseResourceConfig) String(t *testing.T) string {
5252
t.Helper()
5353
tpl := `
5454
provider coderd {

‎internal/provider/organization_resource.go

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,13 @@ func (r *OrganizationResource) Create(ctx context.Context, req resource.CreateRe
165165
return
166166
}
167167

168-
tflog.Trace(ctx, "creating organization")
168+
tflog.Trace(ctx, "creating organization", map[string]any{
169+
"id": data.ID.ValueUUID(),
170+
"name": data.Name.ValueString(),
171+
"display_name": data.DisplayName.ValueString(),
172+
"description": data.Description.ValueString(),
173+
"icon": data.Icon.ValueString(),
174+
})
169175
org, err := r.Client.CreateOrganization(ctx, codersdk.CreateOrganizationRequest{
170176
Name: data.Name.ValueString(),
171177
DisplayName: data.DisplayName.ValueString(),
@@ -177,7 +183,11 @@ func (r *OrganizationResource) Create(ctx context.Context, req resource.CreateRe
177183
return
178184
}
179185
tflog.Trace(ctx, "successfully created organization", map[string]any{
180-
"id": org.ID,
186+
"id": org.ID,
187+
"name": org.Name,
188+
"display_name": org.DisplayName,
189+
"description": org.Description,
190+
"icon": org.Icon,
181191
})
182192
// Fill in `ID` since it must be "computed".
183193
data.ID = UUIDValue(org.ID)
@@ -202,12 +212,12 @@ func (r *OrganizationResource) Update(ctx context.Context, req resource.UpdateRe
202212
// Update the organization metadata
203213
tflog.Trace(ctx, "updating organization", map[string]any{
204214
"id": orgID,
205-
"new_name": data.Name,
206-
"new_display_name": data.DisplayName,
207-
"new_description": data.Description,
208-
"new_icon": data.Icon,
215+
"new_name": data.Name.ValueString(),
216+
"new_display_name": data.DisplayName.ValueString(),
217+
"new_description": data.Description.ValueString(),
218+
"new_icon": data.Icon.ValueString(),
209219
})
210-
_, err := r.Client.UpdateOrganization(ctx, orgID.String(), codersdk.UpdateOrganizationRequest{
220+
org, err := r.Client.UpdateOrganization(ctx, orgID.String(), codersdk.UpdateOrganizationRequest{
211221
Name: data.Name.ValueString(),
212222
DisplayName: data.DisplayName.ValueString(),
213223
Description: data.Description.ValueStringPointer(),
@@ -217,7 +227,14 @@ func (r *OrganizationResource) Update(ctx context.Context, req resource.UpdateRe
217227
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update organization %s, got error: %s", orgID, err))
218228
return
219229
}
220-
tflog.Trace(ctx, "successfully updated organization")
230+
231+
tflog.Trace(ctx, "successfully updated organization", map[string]any{
232+
"id": orgID,
233+
"name": org.Name,
234+
"display_name": org.DisplayName,
235+
"description": org.Description,
236+
"icon": org.Icon,
237+
})
221238

222239
if data.GroupSync.IsNull() {
223240
err = r.patchGroupSync(ctx, orgID, data.GroupSync)
@@ -242,14 +259,18 @@ func (r *OrganizationResource) Delete(ctx context.Context, req resource.DeleteRe
242259
orgID := data.ID.ValueUUID()
243260

244261
tflog.Trace(ctx, "deleting organization", map[string]any{
245-
"id": orgID,
262+
"id": orgID,
263+
"name": data.Name.ValueString(),
246264
})
247265
err := r.Client.DeleteOrganization(ctx, orgID.String())
248266
if err != nil {
249267
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete organization %s, got error: %s", orgID, err))
250268
return
251269
}
252-
tflog.Trace(ctx, "successfully deleted organization")
270+
tflog.Trace(ctx, "successfully deleted organization", map[string]any{
271+
"id": orgID,
272+
"name": data.Name.ValueString(),
273+
})
253274

254275
// Read Terraform prior state data into the model
255276
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

‎internal/provider/organization_resource_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func TestAccOrganizationResource(t *testing.T) {
6161
ResourceName: "coderd_organization.test",
6262
ImportState: true,
6363
ImportStateVerify: true,
64+
ImportStateId: *cfg1.Name,
6465
},
6566
// Update and Read
6667
{

‎internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func (p *CoderdProvider) Resources(ctx context.Context) []func() resource.Resour
139139
NewWorkspaceProxyResource,
140140
NewLicenseResource,
141141
NewOrganizationResource,
142+
NewProvisionerKeyResource,
142143
}
143144
}
144145

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/mapplanmodifier"
10+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
14+
"github.com/coder/coder/v2/codersdk"
15+
)
16+
17+
// Ensure provider defined types fully satisfy framework interfaces.
18+
var _ resource.Resource = &ProvisionerKeyResource{}
19+
20+
func NewProvisionerKeyResource() resource.Resource {
21+
return &ProvisionerKeyResource{}
22+
}
23+
24+
// ProvisionerKeyResource defines the resource implementation.
25+
type ProvisionerKeyResource struct {
26+
*CoderdProviderData
27+
}
28+
29+
// ProvisionerKeyResourceModel describes the resource data model.
30+
type ProvisionerKeyResourceModel struct {
31+
OrganizationID UUID `tfsdk:"organization_id"`
32+
Name types.String `tfsdk:"name"`
33+
Tags types.Map `tfsdk:"tags"`
34+
Key types.String `tfsdk:"key"`
35+
}
36+
37+
func (r *ProvisionerKeyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
38+
resp.TypeName = req.ProviderTypeName + "_provisioner_key"
39+
}
40+
41+
func (r *ProvisionerKeyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
42+
resp.Schema = schema.Schema{
43+
MarkdownDescription: "A provisioner key for a Coder deployment.",
44+
45+
Attributes: map[string]schema.Attribute{
46+
"organization_id": schema.StringAttribute{
47+
CustomType: UUIDType,
48+
MarkdownDescription: "The organization that provisioners connected with this key will be connected to.",
49+
Required: true,
50+
PlanModifiers: []planmodifier.String{
51+
stringplanmodifier.RequiresReplace(),
52+
},
53+
},
54+
"name": schema.StringAttribute{
55+
MarkdownDescription: "The name of the key.",
56+
Required: true,
57+
PlanModifiers: []planmodifier.String{
58+
stringplanmodifier.RequiresReplace(),
59+
},
60+
},
61+
"tags": schema.MapAttribute{
62+
MarkdownDescription: "The tags that provisioners connected with this key will accept jobs for.",
63+
ElementType: types.StringType,
64+
Optional: true,
65+
PlanModifiers: []planmodifier.Map{
66+
mapplanmodifier.RequiresReplace(),
67+
},
68+
},
69+
"key": schema.StringAttribute{
70+
MarkdownDescription: "The acquired provisioner key",
71+
Computed: true,
72+
Sensitive: true,
73+
},
74+
},
75+
}
76+
}
77+
78+
func (r *ProvisionerKeyResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
79+
// Prevent panic if the provider has not been configured.
80+
if req.ProviderData == nil {
81+
return
82+
}
83+
84+
data, ok := req.ProviderData.(*CoderdProviderData)
85+
86+
if !ok {
87+
resp.Diagnostics.AddError(
88+
"Unexpected Resource Configure Type",
89+
fmt.Sprintf("Expected *CoderdProviderData, got: %T. Please report this issue to the provider developers.", req.ProviderData),
90+
)
91+
92+
return
93+
}
94+
95+
r.CoderdProviderData = data
96+
}
97+
98+
func (r *ProvisionerKeyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
99+
// Read Terraform plan data into the model
100+
var data ProvisionerKeyResourceModel
101+
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
102+
if resp.Diagnostics.HasError() {
103+
return
104+
}
105+
106+
var tags map[string]string
107+
resp.Diagnostics.Append(data.Tags.ElementsAs(ctx, &tags, false)...)
108+
createKeyResult, err := r.Client.CreateProvisionerKey(ctx, data.OrganizationID.ValueUUID(), codersdk.CreateProvisionerKeyRequest{
109+
Name: data.Name.ValueString(),
110+
Tags: tags,
111+
})
112+
if err != nil {
113+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create provisioner_key, got error: %s", err))
114+
return
115+
}
116+
117+
data.Key = types.StringValue(createKeyResult.Key)
118+
// Save data into Terraform state
119+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
120+
}
121+
122+
func (r *ProvisionerKeyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
123+
// Read Terraform prior state data into the model
124+
var data ProvisionerKeyResourceModel
125+
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
126+
if resp.Diagnostics.HasError() {
127+
return
128+
}
129+
130+
// Provisioner keys are immutable, no reading necessary.
131+
132+
// Save updated data into Terraform state
133+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
134+
}
135+
136+
func (r *ProvisionerKeyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
137+
// Provisioner keys are immutable, updating is always invalid.
138+
resp.Diagnostics.AddError("Invalid Update", "Terraform is attempting to update a resource which must be replaced")
139+
}
140+
141+
func (r *ProvisionerKeyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
142+
// Read Terraform prior state data into the model
143+
var data ProvisionerKeyResourceModel
144+
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
145+
if resp.Diagnostics.HasError() {
146+
return
147+
}
148+
149+
err := r.Client.DeleteProvisionerKey(ctx, data.OrganizationID.ValueUUID(), data.Name.ValueString())
150+
if err != nil {
151+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete provisionerkey, got error: %s", err))
152+
return
153+
}
154+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"os"
6+
"strings"
7+
"testing"
8+
"text/template"
9+
10+
"github.com/coder/terraform-provider-coderd/integration"
11+
"github.com/google/uuid"
12+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
13+
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
14+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
15+
"github.com/hashicorp/terraform-plugin-testing/statecheck"
16+
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
17+
"github.com/stretchr/testify/require"
18+
)
19+
20+
func TestAccProvisionerKeyResource(t *testing.T) {
21+
if os.Getenv("TF_ACC") == "" {
22+
t.Skip("Acceptance tests are disabled.")
23+
}
24+
ctx := context.Background()
25+
client := integration.StartCoder(ctx, t, "provisioner_key_acc", true)
26+
orgs, err := client.Organizations(ctx)
27+
require.NoError(t, err)
28+
firstOrg := orgs[0].ID
29+
30+
cfg1 := testAccProvisionerKeyResourceConfig{
31+
URL: client.URL.String(),
32+
Token: client.SessionToken(),
33+
34+
OrganizationID: firstOrg,
35+
Name: "example-provisioner-key",
36+
}
37+
38+
cfg2 := cfg1
39+
cfg2.Tags = map[string]string{
40+
"wibble": "wobble",
41+
}
42+
43+
cfg3 := cfg2
44+
cfg3.Name = "different-provisioner-key"
45+
46+
resource.Test(t, resource.TestCase{
47+
IsUnitTest: true,
48+
PreCheck: func() { testAccPreCheck(t) },
49+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
50+
Steps: []resource.TestStep{
51+
{
52+
Config: cfg1.String(t),
53+
},
54+
{
55+
Config: cfg2.String(t),
56+
ConfigPlanChecks: resource.ConfigPlanChecks{
57+
PreApply: []plancheck.PlanCheck{
58+
plancheck.ExpectResourceAction("coderd_provisioner_key.test", plancheck.ResourceActionReplace),
59+
},
60+
},
61+
ConfigStateChecks: []statecheck.StateCheck{
62+
statecheck.ExpectKnownValue("coderd_provisioner_key.test", tfjsonpath.New("tags").AtMapKey("wibble"), knownvalue.StringExact("wobble")),
63+
},
64+
},
65+
{
66+
Config: cfg3.String(t),
67+
ConfigPlanChecks: resource.ConfigPlanChecks{
68+
PreApply: []plancheck.PlanCheck{
69+
plancheck.ExpectResourceAction("coderd_provisioner_key.test", plancheck.ResourceActionReplace),
70+
},
71+
},
72+
},
73+
},
74+
})
75+
}
76+
77+
type testAccProvisionerKeyResourceConfig struct {
78+
URL string
79+
Token string
80+
81+
OrganizationID uuid.UUID
82+
Name string
83+
Tags map[string]string
84+
}
85+
86+
func (c testAccProvisionerKeyResourceConfig) String(t *testing.T) string {
87+
t.Helper()
88+
89+
tpl := `
90+
provider coderd {
91+
url = "{{.URL}}"
92+
token = "{{.Token}}"
93+
}
94+
95+
resource "coderd_provisioner_key" "test" {
96+
organization_id = "{{.OrganizationID}}"
97+
name = "{{.Name}}"
98+
99+
tags = {
100+
{{- range $key, $value := .Tags}}
101+
{{$key}} = "{{$value}}"
102+
{{- end}}
103+
}
104+
}
105+
`
106+
107+
buf := strings.Builder{}
108+
tmpl, err := template.New("provisionerKeyResource").Parse(tpl)
109+
require.NoError(t, err)
110+
111+
err = tmpl.Execute(&buf, c)
112+
require.NoError(t, err)
113+
return buf.String()
114+
}

‎internal/provider/template_resource_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ func TestAccTemplateResourceEnterprise(t *testing.T) {
424424
t.Skip("Acceptance tests are disabled.")
425425
}
426426
ctx := context.Background()
427-
client := integration.StartCoder(ctx, t, "template_acc", true)
427+
client := integration.StartCoder(ctx, t, "template_resource_acc", true)
428428
firstUser, err := client.User(ctx, codersdk.Me)
429429
require.NoError(t, err)
430430

@@ -565,7 +565,7 @@ func TestAccTemplateResourceAGPL(t *testing.T) {
565565
t.Skip("Acceptance tests are disabled.")
566566
}
567567
ctx := context.Background()
568-
client := integration.StartCoder(ctx, t, "template_acc", false)
568+
client := integration.StartCoder(ctx, t, "template_resource_agpl_acc", false)
569569
firstUser, err := client.User(ctx, codersdk.Me)
570570
require.NoError(t, err)
571571

@@ -689,7 +689,7 @@ resource "coderd_template" "sample" {
689689
}`
690690

691691
ctx := context.Background()
692-
client := integration.StartCoder(ctx, t, "template_acc", false)
692+
client := integration.StartCoder(ctx, t, "template_resource_variables_acc", false)
693693

694694
cfg = fmt.Sprintf(cfg, client.URL.String(), client.SessionToken())
695695

0 commit comments

Comments
 (0)
Please sign in to comment.