Skip to content

Commit 5088537

Browse files
committed
Adding resource to replicate the resource generated through the usage of DataSourceResourceShim in the SDKv2 version of the provider (#112)
1 parent 8391959 commit 5088537

File tree

4 files changed

+666
-1
lines changed

4 files changed

+666
-1
lines changed

internal/provider/data_source_archive_file_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ func testTempDir(t *testing.T) string {
395395
return tmp
396396
}
397397

398+
//nolint:unparam
398399
func testExtractResourceAttr(resourceName string, attributeName string, attributeValue *string) r.TestCheckFunc {
399400
return func(s *terraform.State) error {
400401
rs, ok := s.RootModule().Resources[resourceName]

internal/provider/provider.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ func (p *archiveProvider) Configure(context.Context, provider.ConfigureRequest,
2626
}
2727

2828
func (p *archiveProvider) Resources(context.Context) []func() resource.Resource {
29-
return nil
29+
return []func() resource.Resource{
30+
NewArchiveFileResource,
31+
}
3032
}
3133

3234
func (p *archiveProvider) DataSources(context.Context) []func() datasource.DataSource {
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
package archive
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path"
8+
9+
"github.com/hashicorp/terraform-plugin-framework-validators/schemavalidator"
10+
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
fwpath "github.com/hashicorp/terraform-plugin-framework/path"
12+
"github.com/hashicorp/terraform-plugin-framework/resource"
13+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
14+
"github.com/hashicorp/terraform-plugin-framework/types"
15+
)
16+
17+
var _ resource.Resource = (*archiveFileResource)(nil)
18+
19+
func NewArchiveFileResource() resource.Resource {
20+
return &archiveFileResource{}
21+
}
22+
23+
type archiveFileResource struct{}
24+
25+
func (d *archiveFileResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
26+
return tfsdk.Schema{
27+
DeprecationMessage: "**NOTE**: Using archive_file as a resource is deprecated, use archive_file data source instead.",
28+
Blocks: map[string]tfsdk.Block{
29+
"source": {
30+
Description: "Specifies attributes of a single source file to include into the archive.",
31+
Attributes: map[string]tfsdk.Attribute{
32+
"content": {
33+
Description: "Add this content to the archive with `filename` as the filename.",
34+
Type: types.StringType,
35+
Required: true,
36+
Validators: []tfsdk.AttributeValidator{
37+
schemavalidator.ConflictsWith(
38+
fwpath.MatchRoot("source_file"),
39+
fwpath.MatchRoot("source_dir"),
40+
fwpath.MatchRoot("source_content"),
41+
fwpath.MatchRoot("source_content_filename"),
42+
),
43+
},
44+
PlanModifiers: []tfsdk.AttributePlanModifier{
45+
resource.RequiresReplace(),
46+
},
47+
},
48+
"filename": {
49+
Description: "Set this as the filename when declaring a `source`.",
50+
Type: types.StringType,
51+
Required: true,
52+
PlanModifiers: []tfsdk.AttributePlanModifier{
53+
resource.RequiresReplace(),
54+
},
55+
},
56+
},
57+
NestingMode: tfsdk.BlockNestingModeSet,
58+
},
59+
},
60+
Attributes: map[string]tfsdk.Attribute{
61+
"id": {
62+
Description: "The sha1 checksum hash of the output.",
63+
Type: types.StringType,
64+
Computed: true,
65+
},
66+
"type": {
67+
Description: "The type of archive to generate. NOTE: `zip` is supported.",
68+
Type: types.StringType,
69+
Required: true,
70+
PlanModifiers: []tfsdk.AttributePlanModifier{
71+
resource.RequiresReplace(),
72+
},
73+
},
74+
"source_content": {
75+
Description: "Add only this content to the archive with `source_content_filename` as the filename.",
76+
Type: types.StringType,
77+
Optional: true,
78+
Validators: []tfsdk.AttributeValidator{
79+
schemavalidator.ConflictsWith(
80+
fwpath.MatchRoot("source_file"),
81+
fwpath.MatchRoot("source_dir"),
82+
),
83+
},
84+
PlanModifiers: []tfsdk.AttributePlanModifier{
85+
resource.RequiresReplace(),
86+
},
87+
},
88+
"source_content_filename": {
89+
Description: "Set this as the filename when using `source_content`.",
90+
Type: types.StringType,
91+
Optional: true,
92+
Validators: []tfsdk.AttributeValidator{
93+
schemavalidator.ConflictsWith(
94+
fwpath.MatchRoot("source_file"),
95+
fwpath.MatchRoot("source_dir"),
96+
),
97+
},
98+
PlanModifiers: []tfsdk.AttributePlanModifier{
99+
resource.RequiresReplace(),
100+
},
101+
},
102+
"source_file": {
103+
Description: "Package this file into the archive.",
104+
Type: types.StringType,
105+
Optional: true,
106+
Validators: []tfsdk.AttributeValidator{
107+
schemavalidator.ConflictsWith(
108+
fwpath.MatchRoot("source_dir"),
109+
fwpath.MatchRoot("source_content"),
110+
fwpath.MatchRoot("source_content_filename"),
111+
),
112+
},
113+
PlanModifiers: []tfsdk.AttributePlanModifier{
114+
resource.RequiresReplace(),
115+
},
116+
},
117+
"source_dir": {
118+
Description: "Package entire contents of this directory into the archive.",
119+
Type: types.StringType,
120+
Optional: true,
121+
Validators: []tfsdk.AttributeValidator{
122+
schemavalidator.ConflictsWith(
123+
fwpath.MatchRoot("source_file"),
124+
fwpath.MatchRoot("source_content"),
125+
fwpath.MatchRoot("source_content_filename"),
126+
),
127+
},
128+
PlanModifiers: []tfsdk.AttributePlanModifier{
129+
resource.RequiresReplace(),
130+
},
131+
},
132+
"excludes": {
133+
Description: "Specify files to ignore when reading the `source_dir`.",
134+
Type: types.SetType{
135+
ElemType: types.StringType,
136+
},
137+
Optional: true,
138+
Validators: []tfsdk.AttributeValidator{
139+
schemavalidator.ConflictsWith(
140+
fwpath.MatchRoot("source_file"),
141+
fwpath.MatchRoot("source_content"),
142+
fwpath.MatchRoot("source_content_filename"),
143+
),
144+
},
145+
PlanModifiers: []tfsdk.AttributePlanModifier{
146+
resource.RequiresReplace(),
147+
},
148+
},
149+
"output_path": {
150+
Description: "The output of the archive file.",
151+
Type: types.StringType,
152+
Required: true,
153+
PlanModifiers: []tfsdk.AttributePlanModifier{
154+
resource.RequiresReplace(),
155+
},
156+
},
157+
"output_size": {
158+
Description: "The byte size of the output archive file.",
159+
Type: types.Int64Type,
160+
Computed: true,
161+
},
162+
"output_sha": {
163+
Description: "The SHA1 checksum of output archive file.",
164+
Type: types.StringType,
165+
Computed: true,
166+
},
167+
"output_base64sha256": {
168+
Description: "The base64-encoded SHA256 checksum of output archive file.",
169+
Type: types.StringType,
170+
Computed: true,
171+
},
172+
"output_md5": {
173+
Description: "The MD5 checksum of output archive file.",
174+
Type: types.StringType,
175+
Computed: true,
176+
},
177+
"output_file_mode": {
178+
Description: "String that specifies the octal file mode for all archived files. For example: `\"0666\"`. " +
179+
"Setting this will ensure that cross platform usage of this module will not vary the modes of archived " +
180+
"files (and ultimately checksums) resulting in more deterministic behavior.",
181+
Type: types.StringType,
182+
Optional: true,
183+
PlanModifiers: []tfsdk.AttributePlanModifier{
184+
resource.RequiresReplace(),
185+
},
186+
},
187+
},
188+
}, nil
189+
}
190+
191+
func (d *archiveFileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
192+
var model fileModel
193+
diags := req.Plan.Get(ctx, &model)
194+
resp.Diagnostics.Append(diags...)
195+
if resp.Diagnostics.HasError() {
196+
return
197+
}
198+
199+
outputPath := model.OutputPath.ValueString()
200+
201+
outputDirectory := path.Dir(outputPath)
202+
if outputDirectory != "" {
203+
if _, err := os.Stat(outputDirectory); err != nil {
204+
if err := os.MkdirAll(outputDirectory, 0755); err != nil {
205+
resp.Diagnostics.AddError(
206+
"Output path error",
207+
fmt.Sprintf("error creating output path: %s", err),
208+
)
209+
return
210+
}
211+
}
212+
}
213+
214+
if err := archive(ctx, model); err != nil {
215+
resp.Diagnostics.AddError(
216+
"Archive creation error",
217+
fmt.Sprintf("error creating archive: %s", err),
218+
)
219+
return
220+
}
221+
222+
// Generate archived file stats
223+
fi, err := os.Stat(outputPath)
224+
if err != nil {
225+
resp.Diagnostics.AddError(
226+
"Archive output error",
227+
fmt.Sprintf("error reading output: %s", err),
228+
)
229+
return
230+
}
231+
232+
sha1, base64sha256, md5, err := genFileShas(outputPath)
233+
if err != nil {
234+
resp.Diagnostics.AddError(
235+
"Hash generation error",
236+
fmt.Sprintf("error generating hashed: %s", err),
237+
)
238+
}
239+
240+
model.OutputSha = types.StringValue(sha1)
241+
model.OutputBase64Sha256 = types.StringValue(base64sha256)
242+
model.OutputMd5 = types.StringValue(md5)
243+
model.OutputSize = types.Int64Value(fi.Size())
244+
245+
model.ID = types.StringValue(sha1)
246+
247+
diags = resp.State.Set(ctx, model)
248+
resp.Diagnostics.Append(diags...)
249+
}
250+
251+
func (d *archiveFileResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {
252+
}
253+
254+
func (d *archiveFileResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {
255+
}
256+
257+
func (d *archiveFileResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {
258+
}
259+
260+
func (d *archiveFileResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
261+
resp.TypeName = req.ProviderTypeName + "_file"
262+
}

0 commit comments

Comments
 (0)