Skip to content

Commit 4fcc1cd

Browse files
committed
storage profile resource additions
1 parent 228adb3 commit 4fcc1cd

File tree

9 files changed

+155
-17
lines changed

9 files changed

+155
-17
lines changed

GNUmakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ default: testacc
33
# Run acceptance tests
44
.PHONY: testacc
55
testacc:
6-
TF_ACC=1 go test ./... -v $(DBSNAPPER_AUTHTOKEN) $(DBSNAPPER_BASE_URL) -timeout 120m
6+
TF_ACC=1 go test -count=1 ./... -v $(DBSNAPPER_AUTHTOKEN) $(DBSNAPPER_BASE_URL) -timeout 120m
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
resource "dbsnapper_storage_profile" "tfex" {
2+
name = "tf_sp_tfex"
3+
sp_provider = "s3"
4+
region = "us-east-1"
5+
account_id = ""
6+
access_key = "AKIAxxxxxxxx"
7+
secret_key = "xxxxxxxxxxxxxxxxxxxx"
8+
bucket = "dbsnapper-test-s3"
9+
prefix = "terraform"
10+
}
11+
12+
resource "dbsnapper_target" "tfex" {
13+
name = "tf_target_sp_tfex"
14+
snapshot = {
15+
src_url = "postgres://user:pass@localhost:5432/tf_example"
16+
dst_url = "postgres://user:pass@localhost:5432/tf_example_snap"
17+
storage_profile = {
18+
id = dbsnapper_storage_profile.tfex.id
19+
}
20+
}
21+
sanitize = {
22+
dst_url = "postgres://user:pass@localhost:5432/tf_example_snap_sanitized"
23+
query = <<EOT
24+
DROP TABLE IF EXISTS dbsnapper_info;
25+
CREATE TABLE dbsnapper_info (created_at timestamp, tags text []);
26+
INSERT INTO dbsnapper_info (created_at, tags)
27+
VALUES (NOW(), '{target:tf-example, src:terraform}');
28+
EOT
29+
storage_profile = {
30+
id = dbsnapper_storage_profile.tfex.id
31+
}
32+
}
33+
share = {
34+
sso_groups = ["group1", "group2", "group3"]
35+
}
36+
}
37+
38+
output "target" {
39+
value = dbsnapper_target.tfex
40+
}
41+
42+
output "sp_id" {
43+
value = dbsnapper_storage_profile.tfex.id
44+
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/hashicorp/terraform-plugin-go v0.23.0
1010
github.com/hashicorp/terraform-plugin-log v0.9.0
1111
github.com/hashicorp/terraform-plugin-testing v1.8.0
12-
github.com/joescharf/dbsnapper/v2 v2.7.2
12+
github.com/joescharf/dbsnapper/v2 v2.7.3
1313
)
1414

1515
require (
@@ -181,4 +181,4 @@ require (
181181
gopkg.in/yaml.v3 v3.0.1 // indirect
182182
)
183183

184-
replace github.com/joescharf/dbsnapper/v2 v2.7.2 => /Users/joescharf/app/dbsnapper/agent
184+
// replace github.com/joescharf/dbsnapper/v2 v2.7.2 => /Users/joescharf/app/dbsnapper/agent

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
22
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
33
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
44
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
5-
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
6-
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
5+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
6+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
77
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
88
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
99
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA=
@@ -261,6 +261,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
261261
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
262262
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
263263
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
264+
github.com/joescharf/dbsnapper/v2 v2.7.3 h1:l/33/U1Aguu4PbJP853lzJgpMAyqev6wJR2kGVPvwfA=
265+
github.com/joescharf/dbsnapper/v2 v2.7.3/go.mod h1:3BkEHh0p9LxCTnxqow7ubCvr6YDh+sIQc++OktBZsAc=
264266
github.com/joescharf/go-datapipe v0.0.2 h1:KPIE5d9Z0h0rwQdqHpIy6J4zqhnPfff02X4yaQo/Jwg=
265267
github.com/joescharf/go-datapipe v0.0.2/go.mod h1:NUzn7qmljZ34PqXferGM0NegowHomIg4XBEYJ5DP7TM=
266268
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=

internal/provider/storage_profile_resource.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,33 +78,33 @@ func (r *storageProfileResource) Schema(ctx context.Context, req resource.Schema
7878
Required: true,
7979
},
8080
"sp_provider": schema.StringAttribute{
81-
Description: "The provider of the storage profile",
81+
Description: "The provider for the storage profile, one of the following: ['s3', 'r2']",
8282
Required: true,
8383
},
8484
"region": schema.StringAttribute{
8585
Description: "The region of the storage profile",
8686
Optional: true,
8787
},
8888
"account_id": schema.StringAttribute{
89-
Description: "The account ID of the storage provider - Required for Cloudflare",
89+
Description: "The account ID at the storage provider - Required for Cloudflare",
9090
Optional: true,
9191
},
9292
"access_key": schema.StringAttribute{
93-
Description: "The access key of the storage provider",
93+
Description: "The access key of the storage profile",
9494
Required: true,
9595
Sensitive: true,
9696
},
9797
"secret_key": schema.StringAttribute{
98-
Description: "The secret key of the storage provider",
98+
Description: "The secret key of the storage profile",
9999
Required: true,
100100
Sensitive: true,
101101
},
102102
"bucket": schema.StringAttribute{
103-
Description: "The bucket of the storage provider",
103+
Description: "The bucket of the storage profile",
104104
Required: true,
105105
},
106106
"prefix": schema.StringAttribute{
107-
Description: "The prefix of the storage provider",
107+
Description: "The prefix of the storage profile",
108108
Optional: true,
109109
},
110110
"status": schema.StringAttribute{

internal/provider/common.go renamed to internal/provider/target_common.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/hashicorp/terraform-plugin-framework/types"
99
"github.com/hashicorp/terraform-plugin-log/tflog"
1010
dbsTargetModel "github.com/joescharf/dbsnapper/v2/models/target"
11+
"github.com/joescharf/dbsnapper/v2/storage"
1112
)
1213

1314
func TFToResourceModel(ctx context.Context, tf *TargetResourceModel) (*TargetResourceModel, error) {
@@ -40,20 +41,30 @@ func TFToResourceModel(ctx context.Context, tf *TargetResourceModel) (*TargetRes
4041

4142
func ResourceModelToAPIRequest(ctx context.Context, resourceModel *TargetResourceModel) (*dbsTargetModel.Target, error) {
4243
targetRequest := new(dbsTargetModel.Target)
43-
targetRequest.Sanitize = dbsTargetModel.SanitizeCfg{}
44+
targetRequest.Sanitize = dbsTargetModel.SanitizeCfg{
45+
StorageProfile: &storage.StorageProfile{},
46+
}
4447
targetRequest.Share = dbsTargetModel.ShareCfg{}
4548

4649
// Copy Snapshot fields
4750
if resourceModel.Snapshot != nil {
4851
targetRequest.Snapshot.SrcURL = resourceModel.Snapshot.SrcURL.ValueString()
4952
targetRequest.Snapshot.DstURL = resourceModel.Snapshot.DstURL.ValueString()
5053
targetRequest.Snapshot.SrcBytes = resourceModel.Snapshot.SrcBytes.ValueInt64()
54+
if resourceModel.Snapshot.StorageProfile != nil {
55+
uid, _ := uuid.Parse(resourceModel.Snapshot.StorageProfile.ID.ValueString())
56+
targetRequest.Snapshot.StorageProfile.ID = uid
57+
}
5158
}
5259

5360
// Copy the optional Sanitize fields
5461
if resourceModel.Sanitize != nil {
5562
targetRequest.Sanitize.DstURL = resourceModel.Sanitize.DstURL.ValueString()
5663
targetRequest.Sanitize.Query = resourceModel.Sanitize.Query.ValueString()
64+
if resourceModel.Sanitize.StorageProfile != nil {
65+
uid, _ := uuid.Parse(resourceModel.Sanitize.StorageProfile.ID.ValueString())
66+
targetRequest.Sanitize.StorageProfile.ID = uid
67+
}
5768
}
5869

5970
// Copy the optional Share fields
@@ -94,11 +105,17 @@ func APIResponseToResourceModel(ctx context.Context, targetApiResponse *dbsTarge
94105
resourceModel.Snapshot.SrcURL = types.StringValue(targetApiResponse.Snapshot.SrcURL)
95106
resourceModel.Snapshot.DstURL = types.StringValue(targetApiResponse.Snapshot.DstURL)
96107
resourceModel.Snapshot.SrcBytes = types.Int64Value(targetApiResponse.Snapshot.SrcBytes)
108+
if targetApiResponse.Snapshot.StorageProfile != (storage.StorageProfile{}) {
109+
resourceModel.Snapshot.StorageProfile.ID = types.StringValue(targetApiResponse.Snapshot.StorageProfile.ID.String())
110+
}
97111

98112
// Sanitize
99113
if targetApiResponse.Sanitize != (dbsTargetModel.SanitizeCfg{}) {
100114
resourceModel.Sanitize.DstURL = types.StringValue(targetApiResponse.Sanitize.DstURL)
101115
resourceModel.Sanitize.Query = types.StringValue(targetApiResponse.Sanitize.Query)
116+
if targetApiResponse.Sanitize.StorageProfile != nil {
117+
resourceModel.Sanitize.StorageProfile.ID = types.StringValue(targetApiResponse.Sanitize.StorageProfile.ID.String())
118+
}
102119
}
103120
// Share
104121
if targetApiResponse.Share.SsoGroups != nil {

internal/provider/target_resource.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,28 @@ type TargetResourceModel struct {
4747

4848
// targetSnapshotModel maps snapshot data.
4949
type targetSnapshotModel struct {
50-
SrcURL types.String `tfsdk:"src_url"`
51-
DstURL types.String `tfsdk:"dst_url"`
52-
SrcBytes types.Int64 `tfsdk:"src_bytes"`
50+
SrcURL types.String `tfsdk:"src_url"`
51+
DstURL types.String `tfsdk:"dst_url"`
52+
SrcBytes types.Int64 `tfsdk:"src_bytes"`
53+
StorageProfile *targetStorageProfileModel `tfsdk:"storage_profile"`
5354
}
5455

5556
// targetSanitizeModel maps sanitization data.
5657
type targetSanitizeModel struct {
57-
DstURL types.String `tfsdk:"dst_url"`
58-
Query types.String `tfsdk:"query"`
58+
DstURL types.String `tfsdk:"dst_url"`
59+
Query types.String `tfsdk:"query"`
60+
StorageProfile *targetStorageProfileModel `tfsdk:"storage_profile"`
5961
}
6062

6163
// targetShareModel maps share data.
6264
type targetShareModel struct {
6365
SSOGroups types.List `tfsdk:"sso_groups"`
6466
}
6567

68+
type targetStorageProfileModel struct {
69+
ID types.String `tfsdk:"id"`
70+
}
71+
6672
func (r *targetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
6773
resp.TypeName = req.ProviderTypeName + "_target"
6874
}
@@ -116,6 +122,16 @@ func (r *targetResource) Schema(ctx context.Context, req resource.SchemaRequest,
116122
Description: "The size of the source database in bytes",
117123
Computed: true,
118124
},
125+
"storage_profile": schema.SingleNestedAttribute{
126+
Description: "Storage provider configuration for Snapshots",
127+
Optional: true,
128+
Attributes: map[string]schema.Attribute{
129+
"id": schema.StringAttribute{
130+
Description: "The unique identifier for the storage profile",
131+
Optional: true,
132+
},
133+
},
134+
},
119135
},
120136
},
121137

@@ -131,6 +147,16 @@ func (r *targetResource) Schema(ctx context.Context, req resource.SchemaRequest,
131147
Description: "The query used to sanitize the snapshot",
132148
Optional: true,
133149
},
150+
"storage_profile": schema.SingleNestedAttribute{
151+
Description: "Storage provider configuration for Sanitized Snapshots",
152+
Optional: true,
153+
Attributes: map[string]schema.Attribute{
154+
"id": schema.StringAttribute{
155+
Description: "The unique identifier for the storage profile",
156+
Optional: true,
157+
},
158+
},
159+
},
134160
},
135161
},
136162

internal/provider/target_resource_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
package provider
22

33
import (
4+
"log"
45
"testing"
56

67
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
78
)
89

10+
func setupSuite(t *testing.T) func(t *testing.T) {
11+
log.Println("setup suite")
12+
13+
// Return a function to teardown the test
14+
return func(t *testing.T) {
15+
log.Println("teardown suite")
16+
}
17+
}
18+
919
func TestAccTargetResource(t *testing.T) {
20+
21+
teardownSuite := setupSuite(t)
22+
defer teardownSuite(t)
23+
1024
resource.Test(t, resource.TestCase{
1125
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
1226
Steps: []resource.TestStep{

internal/provider/targets_data_source.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/hashicorp/terraform-plugin-framework/datasource"
99
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1010
"github.com/hashicorp/terraform-plugin-framework/types"
11+
"github.com/joescharf/dbsnapper/v2/storage"
1112
)
1213

1314
// Ensure the implementation satisfies the expected interfaces.
@@ -88,6 +89,16 @@ func (d *TargetsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
8889
Description: "The size of the source database in bytes",
8990
Computed: true,
9091
},
92+
"storage_profile": schema.SingleNestedAttribute{
93+
Description: "Storage provider configuration for Snapshots",
94+
Optional: true,
95+
Attributes: map[string]schema.Attribute{
96+
"id": schema.StringAttribute{
97+
Description: "The unique identifier for the storage profile",
98+
Optional: true,
99+
},
100+
},
101+
},
91102
},
92103
},
93104

@@ -103,6 +114,16 @@ func (d *TargetsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
103114
Description: "The query used to sanitize the snapshot",
104115
Computed: true,
105116
},
117+
"storage_profile": schema.SingleNestedAttribute{
118+
Description: "Storage provider configuration for Sanitized Snapshots",
119+
Optional: true,
120+
Attributes: map[string]schema.Attribute{
121+
"id": schema.StringAttribute{
122+
Description: "The unique identifier for the storage profile",
123+
Optional: true,
124+
},
125+
},
126+
},
106127
},
107128
},
108129
"share": schema.SingleNestedAttribute{
@@ -135,6 +156,14 @@ func (d *TargetsDataSource) Read(ctx context.Context, req datasource.ReadRequest
135156
// }
136157
for _, target := range targets {
137158
idstr := target.ID.String()
159+
snapStorageProfile := ""
160+
sanStorageProfile := ""
161+
if target.Snapshot.StorageProfile != (storage.StorageProfile{}) {
162+
snapStorageProfile = target.Snapshot.StorageProfile.ID.String()
163+
}
164+
if target.Sanitize.StorageProfile != nil {
165+
sanStorageProfile = target.Sanitize.StorageProfile.ID.String()
166+
}
138167
targetState := TargetResourceModel{
139168

140169
ID: types.StringValue(idstr),
@@ -145,10 +174,16 @@ func (d *TargetsDataSource) Read(ctx context.Context, req datasource.ReadRequest
145174
SrcURL: types.StringValue(target.Snapshot.SrcURL),
146175
DstURL: types.StringValue(target.Snapshot.DstURL),
147176
// SrcBytes: types.Int64Value(target.Snapshot.SrcBytes),
177+
StorageProfile: &targetStorageProfileModel{
178+
ID: types.StringValue(snapStorageProfile),
179+
},
148180
},
149181
Sanitize: &targetSanitizeModel{
150182
DstURL: types.StringValue(target.Sanitize.DstURL),
151183
Query: types.StringValue(target.Sanitize.Query),
184+
StorageProfile: &targetStorageProfileModel{
185+
ID: types.StringValue(sanStorageProfile),
186+
},
152187
},
153188
}
154189
// Share

0 commit comments

Comments
 (0)