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

Commit9a7dc67

Browse files
committed
feat: add license resource
1 parentbf558f5 commit9a7dc67

File tree

4 files changed

+299
-0
lines changed

4 files changed

+299
-0
lines changed

‎docs/resources/license.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title:"coderd_license Resource - terraform-provider-coderd"
4+
subcategory:""
5+
description:|-
6+
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.
8+
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.
9+
---
10+
11+
#coderd_license (Resource)
12+
13+
A license for a Coder deployment.
14+
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.
16+
17+
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.
18+
19+
20+
21+
<!-- schema generated by tfplugindocs-->
22+
##Schema
23+
24+
###Required
25+
26+
-`license` (String, Sensitive) A license key for Coder.
27+
28+
###Read-Only
29+
30+
-`expires_at` (Number) Unix timestamp of when the license expires.
31+
-`id` (Number) Integer ID of the license.

‎internal/provider/license_resource.go

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
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/int32planmodifier"
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=&LicenseResource{}
19+
20+
funcNewLicenseResource() resource.Resource {
21+
return&LicenseResource{}
22+
}
23+
24+
// LicenseResource defines the resource implementation.
25+
typeLicenseResourcestruct {
26+
data*CoderdProviderData
27+
}
28+
29+
// LicenseResourceModel describes the resource data model.
30+
typeLicenseResourceModelstruct {
31+
ID types.Int32`tfsdk:"id"`
32+
ExpiresAt types.Int64`tfsdk:"expires_at"`
33+
License types.String`tfsdk:"license"`
34+
}
35+
36+
func (r*LicenseResource)Metadata(ctx context.Context,req resource.MetadataRequest,resp*resource.MetadataResponse) {
37+
resp.TypeName=req.ProviderTypeName+"_license"
38+
}
39+
40+
func (r*LicenseResource)Schema(ctx context.Context,req resource.SchemaRequest,resp*resource.SchemaResponse) {
41+
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"+
45+
"Terraform does not guarantee this resource "+
46+
"will be created before other resources or attributes that require a licensed deployment. "+
47+
"The `depends_on` meta-argument is instead recommended.",
48+
49+
Attributes:map[string]schema.Attribute{
50+
"id": schema.Int32Attribute{
51+
MarkdownDescription:"Integer ID of the license.",
52+
Computed:true,
53+
PlanModifiers: []planmodifier.Int32{
54+
int32planmodifier.UseStateForUnknown(),
55+
},
56+
},
57+
"expires_at": schema.Int64Attribute{
58+
MarkdownDescription:"Unix timestamp of when the license expires.",
59+
Computed:true,
60+
},
61+
"license": schema.StringAttribute{
62+
MarkdownDescription:"A license key for Coder.",
63+
Required:true,
64+
Sensitive:true,
65+
PlanModifiers: []planmodifier.String{
66+
stringplanmodifier.RequiresReplace(),
67+
},
68+
},
69+
},
70+
}
71+
}
72+
73+
func (r*LicenseResource)Configure(ctx context.Context,req resource.ConfigureRequest,resp*resource.ConfigureResponse) {
74+
// Prevent panic if the provider has not been configured.
75+
ifreq.ProviderData==nil {
76+
return
77+
}
78+
79+
data,ok:=req.ProviderData.(*CoderdProviderData)
80+
81+
if!ok {
82+
resp.Diagnostics.AddError(
83+
"Unexpected Resource Configure Type",
84+
fmt.Sprintf("Expected *CoderdProviderData, got: %T. Please report this issue to the provider developers.",req.ProviderData),
85+
)
86+
87+
return
88+
}
89+
90+
r.data=data
91+
}
92+
93+
func (r*LicenseResource)Create(ctx context.Context,req resource.CreateRequest,resp*resource.CreateResponse) {
94+
vardataLicenseResourceModel
95+
96+
// Read Terraform plan data into the model
97+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
98+
99+
ifresp.Diagnostics.HasError() {
100+
return
101+
}
102+
103+
client:=r.data.Client
104+
105+
license,err:=client.AddLicense(ctx, codersdk.AddLicenseRequest{
106+
License:data.License.ValueString(),
107+
})
108+
iferr!=nil {
109+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to add license, got error: %s",err))
110+
return
111+
}
112+
data.ID=types.Int32Value(license.ID)
113+
expiresAt,err:=license.ExpiresAt()
114+
iferr!=nil {
115+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to parse license expiration, got error: %s",err))
116+
return
117+
}
118+
data.ExpiresAt=types.Int64Value(expiresAt.Unix())
119+
120+
// Save data into Terraform state
121+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
122+
}
123+
124+
func (r*LicenseResource)Read(ctx context.Context,req resource.ReadRequest,resp*resource.ReadResponse) {
125+
vardataLicenseResourceModel
126+
127+
// Read Terraform prior state data into the model
128+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
129+
130+
ifresp.Diagnostics.HasError() {
131+
return
132+
}
133+
134+
licenses,err:=r.data.Client.Licenses(ctx)
135+
iferr!=nil {
136+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to list licenses, got error: %s",err))
137+
return
138+
}
139+
140+
found:=false
141+
for_,license:=rangelicenses {
142+
iflicense.ID==data.ID.ValueInt32() {
143+
found=true
144+
expiresAt,err:=license.ExpiresAt()
145+
iferr!=nil {
146+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to parse license expiration, got error: %s",err))
147+
return
148+
}
149+
data.ExpiresAt=types.Int64Value(expiresAt.Unix())
150+
}
151+
}
152+
if!found {
153+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("License with ID %d not found",data.ID.ValueInt32()))
154+
}
155+
156+
// Save updated data into Terraform state
157+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
158+
}
159+
160+
func (r*LicenseResource)Update(ctx context.Context,req resource.UpdateRequest,resp*resource.UpdateResponse) {
161+
vardataLicenseResourceModel
162+
163+
// Read Terraform plan data into the model
164+
resp.Diagnostics.Append(req.Plan.Get(ctx,&data)...)
165+
166+
ifresp.Diagnostics.HasError() {
167+
return
168+
}
169+
170+
// Update is handled by replacement
171+
172+
// Save updated data into Terraform state
173+
resp.Diagnostics.Append(resp.State.Set(ctx,&data)...)
174+
}
175+
176+
func (r*LicenseResource)Delete(ctx context.Context,req resource.DeleteRequest,resp*resource.DeleteResponse) {
177+
vardataLicenseResourceModel
178+
179+
// Read Terraform prior state data into the model
180+
resp.Diagnostics.Append(req.State.Get(ctx,&data)...)
181+
182+
ifresp.Diagnostics.HasError() {
183+
return
184+
}
185+
186+
client:=r.data.Client
187+
188+
err:=client.DeleteLicense(ctx,data.ID.ValueInt32())
189+
iferr!=nil {
190+
resp.Diagnostics.AddError("Client Error",fmt.Sprintf("Unable to delete license, got error: %s",err))
191+
return
192+
}
193+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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/hashicorp/terraform-plugin-testing/helper/resource"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
funcTestAccLicenseResource(t*testing.T) {
16+
ifos.Getenv("TF_ACC")=="" {
17+
t.Skip("Acceptance tests are disabled.")
18+
}
19+
ctx:=context.Background()
20+
client:=integration.StartCoder(ctx,t,"license_acc",false)
21+
22+
license:=os.Getenv("CODER_ENTERPRISE_LICENSE")
23+
iflicense=="" {
24+
t.Skip("No license found for license resource tests, skipping")
25+
}
26+
27+
cfg1:=testAccLicenseResourceconfig{
28+
URL:client.URL.String(),
29+
Token:client.SessionToken(),
30+
License:license,
31+
}
32+
33+
resource.Test(t, resource.TestCase{
34+
IsUnitTest:true,
35+
PreCheck:func() {testAccPreCheck(t) },
36+
ProtoV6ProviderFactories:testAccProtoV6ProviderFactories,
37+
Steps: []resource.TestStep{
38+
{
39+
Config:cfg1.String(t),
40+
},
41+
},
42+
})
43+
}
44+
45+
typetestAccLicenseResourceconfigstruct {
46+
URLstring
47+
Tokenstring
48+
Licensestring
49+
}
50+
51+
func (ctestAccLicenseResourceconfig)String(t*testing.T)string {
52+
t.Helper()
53+
tpl:=`
54+
provider coderd {
55+
url = "{{.URL}}"
56+
token = "{{.Token}}"
57+
}
58+
59+
resource "coderd_license" "test" {
60+
license = "{{.License}}"
61+
}
62+
`
63+
funcMap:= template.FuncMap{
64+
"orNull":PrintOrNull,
65+
}
66+
67+
buf:= strings.Builder{}
68+
tmpl,err:=template.New("licenseResource").Funcs(funcMap).Parse(tpl)
69+
require.NoError(t,err)
70+
71+
err=tmpl.Execute(&buf,c)
72+
require.NoError(t,err)
73+
returnbuf.String()
74+
}

‎internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ func (p *CoderdProvider) Resources(ctx context.Context) []func() resource.Resour
138138
NewGroupResource,
139139
NewTemplateResource,
140140
NewWorkspaceProxyResource,
141+
NewLicenseResource,
141142
}
142143
}
143144

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp