Skip to content

Commit 476091d

Browse files
committed
fix: normalize policy action data-type
1 parent 6bb4627 commit 476091d

File tree

4 files changed

+98
-33
lines changed

4 files changed

+98
-33
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)
55

66
## [Unreleased]
77

8+
### Fixed
9+
10+
- objsto_bucket_policy: when comparing policy documents, treat string value in `Action` field as equal to list containing that string as its only item, e.g. `"s3:PutObject"` vs. `["s3:PutObject"]`.
11+
812
## [0.2.0]
913

1014
### Added

internal/provider/bucket_policy_resource.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,15 @@ func normalizePolicyDocument(document string) (string, diag.Diagnostics) {
197197
delete(unmarshaled, "ID")
198198
}
199199

200-
// Sort statement actions (Minio)
201200
if statements, ok := unmarshaled["Statement"].([]interface{}); ok {
202201
for _, statement := range statements {
203202
if statement, ok := statement.(map[string]interface{}); ok {
203+
// Always use array type for Action (Minio)
204+
if action, ok := statement["Action"].(string); ok {
205+
statement["Action"] = []string{action}
206+
}
207+
208+
// Sort statement actions (Minio)
204209
if actions, ok := statement["Action"].([]interface{}); ok {
205210
sort.Slice(actions, func(i, j int) bool {
206211
a, aOk := actions[i].(string)

internal/provider/bucket_policy_resource_test.go

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -103,38 +103,63 @@ func TestAccBucketPolicyResource(t *testing.T) {
103103
})
104104
}
105105

106-
func TestAccBucketPolicyResource_NoId(t *testing.T) {
107-
bucket_name := withSuffix("bucket-policy-no-id")
108-
variables := func(allow_get_object bool) map[string]config.Variable {
109-
return map[string]config.Variable{
110-
"bucket_name": config.StringVariable(bucket_name),
111-
"allow_get_object": config.BoolVariable(allow_get_object),
112-
}
106+
func TestAccBucketPolicyResource_Normalization(t *testing.T) {
107+
tests := []struct {
108+
configName string
109+
testImport bool
110+
}{
111+
{
112+
configName: "bucket_policy_str_action",
113+
testImport: false,
114+
},
115+
{
116+
configName: "bucket_policy_no_id",
117+
testImport: true,
118+
},
113119
}
114120

115-
resource.Test(t, resource.TestCase{
116-
PreCheck: func() { testAccPreCheck(t) },
117-
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
118-
Steps: []resource.TestStep{
119-
{
120-
ConfigFile: config.StaticFile("testdata/bucket_policy_no_id.tf"),
121-
ConfigVariables: variables(false),
122-
Check: resource.ComposeAggregateTestCheckFunc(),
123-
},
124-
{
125-
ConfigFile: config.StaticFile("testdata/bucket_policy_no_id.tf"),
126-
ConfigVariables: variables(true),
127-
Check: resource.ComposeAggregateTestCheckFunc(),
128-
},
129-
{
130-
ConfigFile: config.StaticFile("testdata/bucket_policy_no_id.tf"),
131-
ConfigVariables: variables(true),
132-
ResourceName: "objsto_bucket_policy.this",
133-
ImportState: true,
134-
ImportStateId: bucket_name,
135-
ImportStateVerifyIdentifierAttribute: "bucket",
136-
ImportStateVerify: true,
137-
},
138-
},
139-
})
121+
for _, test := range tests {
122+
t.Run(test.configName, func(t *testing.T) {
123+
configPath := fmt.Sprintf("testdata/%s.tf", test.configName)
124+
125+
bucket_name := withSuffix("bucket-policy-no-id")
126+
variables := func(allow_get_object bool) map[string]config.Variable {
127+
return map[string]config.Variable{
128+
"bucket_name": config.StringVariable(bucket_name),
129+
"allow_get_object": config.BoolVariable(allow_get_object),
130+
}
131+
}
132+
133+
steps := []resource.TestStep{
134+
{
135+
ConfigFile: config.StaticFile(configPath),
136+
ConfigVariables: variables(false),
137+
Check: resource.ComposeAggregateTestCheckFunc(),
138+
},
139+
{
140+
ConfigFile: config.StaticFile(configPath),
141+
ConfigVariables: variables(true),
142+
Check: resource.ComposeAggregateTestCheckFunc(),
143+
},
144+
}
145+
146+
if test.testImport {
147+
steps = append(steps, resource.TestStep{
148+
ConfigFile: config.StaticFile(configPath),
149+
ConfigVariables: variables(true),
150+
ResourceName: "objsto_bucket_policy.this",
151+
ImportState: true,
152+
ImportStateId: bucket_name,
153+
ImportStateVerifyIdentifierAttribute: "bucket",
154+
ImportStateVerify: true,
155+
})
156+
}
157+
158+
resource.Test(t, resource.TestCase{
159+
PreCheck: func() { testAccPreCheck(t) },
160+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
161+
Steps: steps,
162+
})
163+
})
164+
}
140165
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
variable "bucket_name" {
2+
type = string
3+
default = "objsto-acc-test"
4+
}
5+
6+
variable "allow_get_object" {
7+
type = bool
8+
default = false
9+
}
10+
11+
resource "objsto_bucket" "this" {
12+
bucket = var.bucket_name
13+
}
14+
15+
resource "objsto_bucket_policy" "this" {
16+
bucket = objsto_bucket.this.bucket
17+
policy = jsonencode({
18+
Version = "2012-10-17",
19+
Statement = [
20+
{
21+
Principal = {
22+
"AWS" = ["*"]
23+
}
24+
Effect = var.allow_get_object ? "Allow" : "Deny"
25+
Action = "s3:GetObject"
26+
Resource = [
27+
"${objsto_bucket.this.arn}/*",
28+
]
29+
},
30+
] })
31+
}

0 commit comments

Comments
 (0)