Skip to content

Commit a018ade

Browse files
authored
Merge pull request #70 from jetstack/firefly_subca
Add Firefly SubCA Provider resource
2 parents 952d544 + de9d5fc commit a018ade

File tree

5 files changed

+412
-0
lines changed

5 files changed

+412
-0
lines changed

docs/resources/firefly_subca.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "tlspc_firefly_subca Resource - tlspc"
4+
subcategory: ""
5+
description: |-
6+
7+
---
8+
9+
# tlspc_firefly_subca (Resource)
10+
11+
12+
13+
## Example Usage
14+
15+
```terraform
16+
resource "tlspc_firefly_subca" "subca" {
17+
name = "Firefly Sub CA"
18+
ca_type = data.tlspc_ca_product.built_in_ca.type
19+
ca_account_id = data.tlspc_ca_product.built_in_ca.account_id
20+
ca_product_option_id = data.tlspc_ca_product.built_in_ca.id
21+
common_name = "firefly-subca.com"
22+
key_algorithm = "RSA_2048"
23+
validity_period = "P30D"
24+
}
25+
```
26+
27+
<!-- schema generated by tfplugindocs -->
28+
## Schema
29+
30+
### Required
31+
32+
- `ca_account_id` (String) The ID of the Certificate Authority Account
33+
- `ca_product_option_id` (String) The ID of the Certificate Authority Product Option
34+
- `ca_type` (String) The type of Certificate Authority
35+
- `common_name` (String) Common Name
36+
- `key_algorithm` (String) Key Algorithm. Valid options include:
37+
* RSA_2048
38+
* RSA_3072
39+
* RSA_4096
40+
* EC_P256
41+
* EC_P384
42+
* EC_P521
43+
* EC_ED25519
44+
- `name` (String) The name of the Firefly Sub CA Provider
45+
- `validity_period` (String) Validity Period in ISO8601 Period Format. e.g. P30D
46+
47+
### Read-Only
48+
49+
- `id` (String) The ID of this resource
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "tlspc_firefly_subca" "subca" {
2+
name = "Firefly Sub CA"
3+
ca_type = data.tlspc_ca_product.built_in_ca.type
4+
ca_account_id = data.tlspc_ca_product.built_in_ca.account_id
5+
ca_product_option_id = data.tlspc_ca_product.built_in_ca.id
6+
common_name = "firefly-subca.com"
7+
key_algorithm = "RSA_2048"
8+
validity_period = "P30D"
9+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Copyright (c) Venafi, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"terraform-provider-tlspc/internal/tlspc"
11+
12+
"github.com/hashicorp/terraform-plugin-framework/path"
13+
"github.com/hashicorp/terraform-plugin-framework/resource"
14+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
15+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
16+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
17+
"github.com/hashicorp/terraform-plugin-framework/types"
18+
)
19+
20+
var (
21+
_ resource.Resource = &fireflySubCAResource{}
22+
_ resource.ResourceWithConfigure = &fireflySubCAResource{}
23+
_ resource.ResourceWithImportState = &fireflySubCAResource{}
24+
)
25+
26+
type fireflySubCAResource struct {
27+
client *tlspc.Client
28+
}
29+
30+
func NewFireflySubCAResource() resource.Resource {
31+
return &fireflySubCAResource{}
32+
}
33+
34+
func (r *fireflySubCAResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
35+
resp.TypeName = req.ProviderTypeName + "_firefly_subca"
36+
}
37+
38+
func (r *fireflySubCAResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
39+
resp.Schema = schema.Schema{
40+
Attributes: map[string]schema.Attribute{
41+
"id": schema.StringAttribute{
42+
Computed: true,
43+
PlanModifiers: []planmodifier.String{
44+
stringplanmodifier.UseStateForUnknown(),
45+
},
46+
MarkdownDescription: "The ID of this resource",
47+
},
48+
"name": schema.StringAttribute{
49+
Required: true,
50+
MarkdownDescription: "The name of the Firefly Sub CA Provider",
51+
},
52+
"ca_type": schema.StringAttribute{
53+
Required: true,
54+
MarkdownDescription: "The type of Certificate Authority",
55+
},
56+
"ca_account_id": schema.StringAttribute{
57+
Required: true,
58+
MarkdownDescription: "The ID of the Certificate Authority Account",
59+
},
60+
"ca_product_option_id": schema.StringAttribute{
61+
Required: true,
62+
MarkdownDescription: "The ID of the Certificate Authority Product Option",
63+
},
64+
"common_name": schema.StringAttribute{
65+
Required: true,
66+
MarkdownDescription: "Common Name",
67+
},
68+
"key_algorithm": schema.StringAttribute{
69+
Required: true,
70+
MarkdownDescription: `Key Algorithm. Valid options include:
71+
* RSA_2048
72+
* RSA_3072
73+
* RSA_4096
74+
* EC_P256
75+
* EC_P384
76+
* EC_P521
77+
* EC_ED25519
78+
`,
79+
},
80+
"validity_period": schema.StringAttribute{
81+
Required: true,
82+
MarkdownDescription: "Validity Period in ISO8601 Period Format. e.g. P30D",
83+
},
84+
},
85+
}
86+
}
87+
88+
func (r *fireflySubCAResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
89+
if req.ProviderData == nil {
90+
return
91+
}
92+
93+
client, ok := req.ProviderData.(*tlspc.Client)
94+
95+
if !ok {
96+
resp.Diagnostics.AddError(
97+
"Unexpected Data Source Configure Type",
98+
fmt.Sprintf("Expected *tlspc.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
99+
)
100+
101+
return
102+
}
103+
104+
r.client = client
105+
}
106+
107+
type fireflySubCAResourceModel struct {
108+
ID types.String `tfsdk:"id"`
109+
Name types.String `tfsdk:"name"`
110+
CAType types.String `tfsdk:"ca_type"`
111+
CAAccountID types.String `tfsdk:"ca_account_id"`
112+
CAProductOptionID types.String `tfsdk:"ca_product_option_id"`
113+
CommonName types.String `tfsdk:"common_name"`
114+
KeyAlgorithm types.String `tfsdk:"key_algorithm"`
115+
ValidityPeriod types.String `tfsdk:"validity_period"`
116+
}
117+
118+
func (r *fireflySubCAResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
119+
var plan fireflySubCAResourceModel
120+
diags := req.Plan.Get(ctx, &plan)
121+
resp.Diagnostics.Append(diags...)
122+
if resp.Diagnostics.HasError() {
123+
return
124+
}
125+
126+
ff := tlspc.FireflySubCAProvider{
127+
Name: plan.Name.ValueString(),
128+
CAType: plan.CAType.ValueString(),
129+
CAAccountID: plan.CAAccountID.ValueString(),
130+
CAProductOptionID: plan.CAProductOptionID.ValueString(),
131+
CommonName: plan.CommonName.ValueString(),
132+
KeyAlgorithm: plan.KeyAlgorithm.ValueString(),
133+
ValidityPeriod: plan.ValidityPeriod.ValueString(),
134+
}
135+
created, err := r.client.CreateFireflySubCAProvider(ff)
136+
if err != nil {
137+
resp.Diagnostics.AddError(
138+
"Error creating Firefly SubCA Provider",
139+
"Could not create Firefly SubCA Provider, unexpected error: "+err.Error(),
140+
)
141+
return
142+
}
143+
plan.ID = types.StringValue(created.ID)
144+
diags = resp.State.Set(ctx, plan)
145+
resp.Diagnostics.Append(diags...)
146+
}
147+
148+
func (r *fireflySubCAResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
149+
var state fireflySubCAResourceModel
150+
151+
diags := req.State.Get(ctx, &state)
152+
resp.Diagnostics.Append(diags...)
153+
if resp.Diagnostics.HasError() {
154+
return
155+
}
156+
157+
ff, err := r.client.GetFireflySubCAProvider(state.ID.ValueString())
158+
if err != nil {
159+
resp.Diagnostics.AddError(
160+
"Error Reading FireflyConfig",
161+
"Could not read FireflyConfig ID "+state.ID.ValueString()+": "+err.Error(),
162+
)
163+
return
164+
}
165+
166+
state.ID = types.StringValue(ff.ID)
167+
state.Name = types.StringValue(ff.Name)
168+
state.CAType = types.StringValue(ff.CAType)
169+
state.CAAccountID = types.StringValue(ff.CAAccountID)
170+
state.CAProductOptionID = types.StringValue(ff.CAProductOptionID)
171+
state.CommonName = types.StringValue(ff.CommonName)
172+
state.KeyAlgorithm = types.StringValue(ff.KeyAlgorithm)
173+
state.ValidityPeriod = types.StringValue(ff.ValidityPeriod)
174+
175+
diags = resp.State.Set(ctx, state)
176+
resp.Diagnostics.Append(diags...)
177+
}
178+
179+
func (r *fireflySubCAResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
180+
var plan, state fireflySubCAResourceModel
181+
182+
diags := req.State.Get(ctx, &state)
183+
resp.Diagnostics.Append(diags...)
184+
if resp.Diagnostics.HasError() {
185+
return
186+
}
187+
diags = req.Plan.Get(ctx, &plan)
188+
resp.Diagnostics.Append(diags...)
189+
if resp.Diagnostics.HasError() {
190+
return
191+
}
192+
193+
ff := tlspc.FireflySubCAProvider{
194+
ID: state.ID.ValueString(),
195+
Name: plan.Name.ValueString(),
196+
CAType: plan.CAType.ValueString(),
197+
CAAccountID: plan.CAAccountID.ValueString(),
198+
CAProductOptionID: plan.CAProductOptionID.ValueString(),
199+
CommonName: plan.CommonName.ValueString(),
200+
KeyAlgorithm: plan.KeyAlgorithm.ValueString(),
201+
ValidityPeriod: plan.ValidityPeriod.ValueString(),
202+
}
203+
204+
updated, err := r.client.UpdateFireflySubCAProvider(ff)
205+
if err != nil {
206+
resp.Diagnostics.AddError(
207+
"Error updating Firefly SubCA Provider",
208+
"Could not update Firefly SubCA Provider, unexpected error: "+err.Error(),
209+
)
210+
return
211+
}
212+
plan.ID = types.StringValue(updated.ID)
213+
diags = resp.State.Set(ctx, plan)
214+
resp.Diagnostics.Append(diags...)
215+
}
216+
217+
func (r *fireflySubCAResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
218+
var state fireflySubCAResourceModel
219+
220+
diags := req.State.Get(ctx, &state)
221+
resp.Diagnostics.Append(diags...)
222+
if resp.Diagnostics.HasError() {
223+
return
224+
}
225+
226+
err := r.client.DeleteFireflyConfig(state.ID.ValueString())
227+
if err != nil {
228+
resp.Diagnostics.AddError(
229+
"Error Deleting FireflyConfig",
230+
"Could not delete FireflyConfig ID "+state.ID.ValueString()+": "+err.Error(),
231+
)
232+
return
233+
}
234+
}
235+
236+
func (r *fireflySubCAResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
237+
// Retrieve import ID and save to id attribute
238+
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
239+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func (p *tlspcProvider) Resources(ctx context.Context) []func() resource.Resourc
100100
NewCertificateTemplateResource,
101101
NewApplicationResource,
102102
NewFireflyConfigResource,
103+
NewFireflySubCAResource,
103104
}
104105
}
105106

0 commit comments

Comments
 (0)