Skip to content

Commit cefab48

Browse files
authored
Merge pull request #45360 from hashicorp/f-s3-meridian
S3 Tables replication
2 parents 24a6443 + fb7dd84 commit cefab48

18 files changed

+2094
-11
lines changed

.changelog/45360.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:new-resource
2+
aws_s3tables_table_bucket_replication
3+
```
4+
5+
```release-note:new-resource
6+
aws_s3tables_table_replication
7+
```

internal/service/s3tables/exports_test.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@
44
package s3tables
55

66
var (
7-
ResourceNamespace = newNamespaceResource
8-
ResourceTable = newTableResource
9-
ResourceTableBucket = newTableBucketResource
10-
ResourceTableBucketPolicy = newTableBucketPolicyResource
11-
ResourceTablePolicy = newTablePolicyResource
7+
ResourceNamespace = newNamespaceResource
8+
ResourceTable = newTableResource
9+
ResourceTableBucket = newTableBucketResource
10+
ResourceTableBucketPolicy = newTableBucketPolicyResource
11+
ResourceTableBucketReplication = newTableBucketReplicationResource
12+
ResourceTablePolicy = newTablePolicyResource
13+
ResourceTableReplication = newTableReplicationResource
1214

13-
FindNamespaceByTwoPartKey = findNamespaceByTwoPartKey
14-
FindTableByThreePartKey = findTableByThreePartKey
15-
FindTableBucketByARN = findTableBucketByARN
16-
FindTableBucketPolicyByARN = findTableBucketPolicyByARN
17-
FindTablePolicyByThreePartKey = findTablePolicyByThreePartKey
15+
FindNamespaceByTwoPartKey = findNamespaceByTwoPartKey
16+
FindTableByThreePartKey = findTableByThreePartKey
17+
FindTableBucketByARN = findTableBucketByARN
18+
FindTableBucketPolicyByARN = findTableBucketPolicyByARN
19+
FindTableBucketReplicationByARN = findTableBucketReplicationByARN
20+
FindTablePolicyByThreePartKey = findTablePolicyByThreePartKey
21+
FindTableReplicationByARN = findTableReplicationByARN
1822

1923
TableIDFromTableARN = tableIDFromTableARN
2024
)

internal/service/s3tables/service_package_gen.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package s3tables
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/aws/aws-sdk-go-v2/aws"
11+
"github.com/aws/aws-sdk-go-v2/service/s3tables"
12+
awstypes "github.com/aws/aws-sdk-go-v2/service/s3tables/types"
13+
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
14+
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
15+
"github.com/hashicorp/terraform-plugin-framework/resource"
16+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
17+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
18+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
19+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
20+
"github.com/hashicorp/terraform-plugin-framework/types"
21+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
22+
"github.com/hashicorp/terraform-provider-aws/internal/errs"
23+
"github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag"
24+
"github.com/hashicorp/terraform-provider-aws/internal/framework"
25+
fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
26+
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
27+
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
28+
"github.com/hashicorp/terraform-provider-aws/names"
29+
)
30+
31+
// @FrameworkResource("aws_s3tables_table_bucket_replication", name="Table Bucket Replication")
32+
// @ArnIdentity("table_bucket_arn")
33+
// @Testing(existsType="github.com/aws/aws-sdk-go-v2/service/s3tables;s3tables.GetTableBucketReplicationOutput")
34+
// @Testing(preCheck="testAccPreCheck")
35+
// @Testing(hasNoPreExistingResource=true)
36+
// @Testing(importIgnore="version_token")
37+
// @Testing(plannableImportAction="NoOp")
38+
func newTableBucketReplicationResource(_ context.Context) (resource.ResourceWithConfigure, error) {
39+
return &tableBucketReplicationResource{}, nil
40+
}
41+
42+
type tableBucketReplicationResource struct {
43+
framework.ResourceWithModel[tableBucketReplicationResourceModel]
44+
framework.WithImportByIdentity
45+
}
46+
47+
func (r *tableBucketReplicationResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) {
48+
response.Schema = schema.Schema{
49+
Attributes: map[string]schema.Attribute{
50+
names.AttrRole: schema.StringAttribute{
51+
CustomType: fwtypes.ARNType,
52+
Required: true,
53+
},
54+
"table_bucket_arn": schema.StringAttribute{
55+
CustomType: fwtypes.ARNType,
56+
Required: true,
57+
PlanModifiers: []planmodifier.String{
58+
stringplanmodifier.RequiresReplace(),
59+
},
60+
},
61+
"version_token": schema.StringAttribute{
62+
Computed: true,
63+
},
64+
},
65+
Blocks: map[string]schema.Block{
66+
names.AttrRule: schema.ListNestedBlock{
67+
CustomType: fwtypes.NewListNestedObjectTypeOf[bucketReplicationRuleModel](ctx),
68+
Validators: []validator.List{
69+
listvalidator.SizeAtMost(1),
70+
},
71+
NestedObject: schema.NestedBlockObject{
72+
Blocks: map[string]schema.Block{
73+
names.AttrDestination: schema.SetNestedBlock{
74+
CustomType: fwtypes.NewSetNestedObjectTypeOf[replicationDestinationModel](ctx),
75+
Validators: []validator.Set{
76+
setvalidator.SizeAtLeast(1),
77+
setvalidator.SizeAtMost(5),
78+
setvalidator.IsRequired(),
79+
},
80+
NestedObject: schema.NestedBlockObject{
81+
Attributes: map[string]schema.Attribute{
82+
"destination_table_bucket_arn": schema.StringAttribute{
83+
CustomType: fwtypes.ARNType,
84+
Required: true,
85+
},
86+
},
87+
},
88+
},
89+
},
90+
},
91+
},
92+
},
93+
}
94+
}
95+
96+
func (r *tableBucketReplicationResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
97+
var data tableBucketReplicationResourceModel
98+
response.Diagnostics.Append(request.Plan.Get(ctx, &data)...)
99+
if response.Diagnostics.HasError() {
100+
return
101+
}
102+
103+
conn := r.Meta().S3TablesClient(ctx)
104+
105+
var configuration awstypes.TableBucketReplicationConfiguration
106+
response.Diagnostics.Append(fwflex.Expand(ctx, data, &configuration)...)
107+
if response.Diagnostics.HasError() {
108+
return
109+
}
110+
111+
tableBucketARN := fwflex.StringValueFromFramework(ctx, data.TableBucketARN)
112+
input := s3tables.PutTableBucketReplicationInput{
113+
Configuration: &configuration,
114+
TableBucketARN: aws.String(tableBucketARN),
115+
}
116+
117+
output, err := conn.PutTableBucketReplication(ctx, &input)
118+
119+
if err != nil {
120+
response.Diagnostics.AddError(fmt.Sprintf("creating S3 Tables Table Bucket Replication (%s)", tableBucketARN), err.Error())
121+
122+
return
123+
}
124+
125+
// Set values for unknowns.
126+
data.VersionToken = fwflex.StringToFramework(ctx, output.VersionToken)
127+
128+
response.Diagnostics.Append(response.State.Set(ctx, data)...)
129+
}
130+
131+
func (r *tableBucketReplicationResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
132+
var data tableBucketReplicationResourceModel
133+
response.Diagnostics.Append(request.State.Get(ctx, &data)...)
134+
if response.Diagnostics.HasError() {
135+
return
136+
}
137+
138+
conn := r.Meta().S3TablesClient(ctx)
139+
140+
tableBucketARN := fwflex.StringValueFromFramework(ctx, data.TableBucketARN)
141+
output, err := findTableBucketReplicationByARN(ctx, conn, tableBucketARN)
142+
143+
if tfresource.NotFound(err) {
144+
response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err))
145+
response.State.RemoveResource(ctx)
146+
147+
return
148+
}
149+
150+
if err != nil {
151+
response.Diagnostics.AddError(fmt.Sprintf("reading S3 Tables Table Bucket Replication (%s)", tableBucketARN), err.Error())
152+
153+
return
154+
}
155+
156+
// Set attributes for import.
157+
response.Diagnostics.Append(fwflex.Flatten(ctx, output.Configuration, &data)...)
158+
if response.Diagnostics.HasError() {
159+
return
160+
}
161+
162+
response.Diagnostics.Append(response.State.Set(ctx, &data)...)
163+
}
164+
165+
func (r *tableBucketReplicationResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
166+
var old, new tableBucketReplicationResourceModel
167+
response.Diagnostics.Append(request.Plan.Get(ctx, &new)...)
168+
if response.Diagnostics.HasError() {
169+
return
170+
}
171+
response.Diagnostics.Append(request.State.Get(ctx, &old)...)
172+
if response.Diagnostics.HasError() {
173+
return
174+
}
175+
176+
conn := r.Meta().S3TablesClient(ctx)
177+
178+
var configuration awstypes.TableBucketReplicationConfiguration
179+
response.Diagnostics.Append(fwflex.Expand(ctx, new, &configuration)...)
180+
if response.Diagnostics.HasError() {
181+
return
182+
}
183+
184+
tableBucketARN := fwflex.StringValueFromFramework(ctx, new.TableBucketARN)
185+
input := s3tables.PutTableBucketReplicationInput{
186+
Configuration: &configuration,
187+
TableBucketARN: aws.String(tableBucketARN),
188+
VersionToken: fwflex.StringFromFramework(ctx, old.VersionToken),
189+
}
190+
191+
output, err := conn.PutTableBucketReplication(ctx, &input)
192+
193+
if err != nil {
194+
response.Diagnostics.AddError(fmt.Sprintf("updating S3 Tables Table Bucket Replication (%s)", tableBucketARN), err.Error())
195+
196+
return
197+
}
198+
199+
// Set values for unknowns.
200+
new.VersionToken = fwflex.StringToFramework(ctx, output.VersionToken)
201+
202+
response.Diagnostics.Append(response.State.Set(ctx, new)...)
203+
}
204+
205+
func (r *tableBucketReplicationResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) {
206+
var data tableBucketReplicationResourceModel
207+
response.Diagnostics.Append(request.State.Get(ctx, &data)...)
208+
if response.Diagnostics.HasError() {
209+
return
210+
}
211+
212+
conn := r.Meta().S3TablesClient(ctx)
213+
214+
tableBucketARN := fwflex.StringValueFromFramework(ctx, data.TableBucketARN)
215+
input := s3tables.DeleteTableBucketReplicationInput{
216+
TableBucketARN: aws.String(tableBucketARN),
217+
VersionToken: fwflex.StringFromFramework(ctx, data.VersionToken),
218+
}
219+
_, err := conn.DeleteTableBucketReplication(ctx, &input)
220+
221+
if errs.IsA[*awstypes.NotFoundException](err) {
222+
return
223+
}
224+
225+
if err != nil {
226+
response.Diagnostics.AddError(fmt.Sprintf("deleting S3 Tables Table Replication (%s)", tableBucketARN), err.Error())
227+
228+
return
229+
}
230+
}
231+
232+
func findTableBucketReplicationByARN(ctx context.Context, conn *s3tables.Client, tableBucketARN string) (*s3tables.GetTableBucketReplicationOutput, error) {
233+
input := s3tables.GetTableBucketReplicationInput{
234+
TableBucketARN: aws.String(tableBucketARN),
235+
}
236+
237+
return findTableBucketReplication(ctx, conn, &input)
238+
}
239+
240+
func findTableBucketReplication(ctx context.Context, conn *s3tables.Client, input *s3tables.GetTableBucketReplicationInput) (*s3tables.GetTableBucketReplicationOutput, error) {
241+
output, err := conn.GetTableBucketReplication(ctx, input)
242+
243+
if errs.IsA[*awstypes.NotFoundException](err) {
244+
return nil, &retry.NotFoundError{
245+
LastError: err,
246+
}
247+
}
248+
249+
if err != nil {
250+
return nil, err
251+
}
252+
253+
if output == nil || output.Configuration == nil {
254+
return nil, tfresource.NewEmptyResultError(input)
255+
}
256+
257+
return output, nil
258+
}
259+
260+
type tableBucketReplicationResourceModel struct {
261+
framework.WithRegionModel
262+
Role fwtypes.ARN `tfsdk:"role"`
263+
Rules fwtypes.ListNestedObjectValueOf[bucketReplicationRuleModel] `tfsdk:"rule"`
264+
TableBucketARN fwtypes.ARN `tfsdk:"table_bucket_arn"`
265+
VersionToken types.String `tfsdk:"version_token"`
266+
}
267+
268+
type bucketReplicationRuleModel struct {
269+
Destinations fwtypes.SetNestedObjectValueOf[replicationDestinationModel] `tfsdk:"destination"`
270+
}
271+
272+
type replicationDestinationModel struct {
273+
DestinationTableBucketARN fwtypes.ARN `tfsdk:"destination_table_bucket_arn"`
274+
}

0 commit comments

Comments
 (0)