Skip to content

Commit 321e8d4

Browse files
bfladtwitty-rival
authored andcommitted
provider: Update preview ignore tags handling to configuration block and shared struct type (hashicorp#12586)
Reference: hashicorp#10689 Based on feedback and for future extensibility. Output from acceptance testing: ``` --- PASS: TestAccAWSProvider_Endpoints (4.06s) --- PASS: TestAccAWSProvider_Endpoints_Deprecated (4.04s) --- PASS: TestAccAWSProvider_IgnoreTags_EmptyConfigurationBlock (3.99s) --- PASS: TestAccAWSProvider_IgnoreTags_KeyPrefixes_Multiple (4.01s) --- PASS: TestAccAWSProvider_IgnoreTags_KeyPrefixes_None (4.00s) --- PASS: TestAccAWSProvider_IgnoreTags_KeyPrefixes_One (4.02s) --- PASS: TestAccAWSProvider_IgnoreTags_Keys_Multiple (4.02s) --- PASS: TestAccAWSProvider_IgnoreTags_Keys_None (3.96s) --- PASS: TestAccAWSProvider_IgnoreTags_Keys_One (4.01s) --- PASS: TestAccAWSProvider_Region_AwsChina (3.83s) --- PASS: TestAccAWSProvider_Region_AwsCommercial (3.83s) --- PASS: TestAccAWSProvider_Region_AwsGovCloudUs (3.77s) --- PASS: TestAccAWSSubnet_availabilityZoneId (30.61s) --- PASS: TestAccAWSSubnet_basic (30.88s) --- PASS: TestAccAWSSubnet_enableIpv6 (49.79s) --- PASS: TestAccAWSSubnet_ignoreTags (57.70s) --- PASS: TestAccAWSSubnet_ipv6 (79.46s) --- PASS: TestAccAWSVpc_AssignGeneratedIpv6CidrBlock (70.48s) --- PASS: TestAccAWSVpc_basic (29.30s) --- PASS: TestAccAWSVpc_bothDnsOptionsSet (30.18s) --- PASS: TestAccAWSVpc_classiclinkDnsSupportOptionSet (31.10s) --- PASS: TestAccAWSVpc_classiclinkOptionSet (30.48s) --- PASS: TestAccAWSVpc_coreMismatchedDiffs (25.43s) --- PASS: TestAccAWSVpc_DisabledDnsSupport (29.98s) --- PASS: TestAccAWSVpc_disappears (15.64s) --- PASS: TestAccAWSVpc_ignoreTags (51.16s) --- PASS: TestAccAWSVpc_tags (48.55s) --- PASS: TestAccAWSVpc_Tenancy (70.60s) --- PASS: TestAccAWSVpc_update (44.36s) ```
1 parent 204ee6e commit 321e8d4

File tree

10 files changed

+417
-100
lines changed

10 files changed

+417
-100
lines changed

aws/config.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,9 @@ type Config struct {
167167
AllowedAccountIds []string
168168
ForbiddenAccountIds []string
169169

170-
Endpoints map[string]string
171-
IgnoreTagPrefixes []string
172-
IgnoreTags []string
173-
Insecure bool
170+
Endpoints map[string]string
171+
IgnoreTagsConfig *keyvaluetags.IgnoreConfig
172+
Insecure bool
174173

175174
SkipCredsValidation bool
176175
SkipGetEC2Platforms bool
@@ -254,8 +253,7 @@ type AWSClient struct {
254253
guarddutyconn *guardduty.GuardDuty
255254
greengrassconn *greengrass.Greengrass
256255
iamconn *iam.IAM
257-
ignoreTagPrefixes keyvaluetags.KeyValueTags
258-
ignoreTags keyvaluetags.KeyValueTags
256+
IgnoreTagsConfig *keyvaluetags.IgnoreConfig
259257
imagebuilderconn *imagebuilder.Imagebuilder
260258
inspectorconn *inspector.Inspector
261259
iotconn *iot.IoT
@@ -472,8 +470,7 @@ func (c *Config) Client() (interface{}, error) {
472470
guarddutyconn: guardduty.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["guardduty"])})),
473471
greengrassconn: greengrass.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["greengrass"])})),
474472
iamconn: iam.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["iam"])})),
475-
ignoreTagPrefixes: keyvaluetags.New(c.IgnoreTagPrefixes),
476-
ignoreTags: keyvaluetags.New(c.IgnoreTags),
473+
IgnoreTagsConfig: c.IgnoreTagsConfig,
477474
imagebuilderconn: imagebuilder.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["imagebuilder"])})),
478475
inspectorconn: inspector.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["inspector"])})),
479476
iotconn: iot.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["iot"])})),

aws/internal/keyvaluetags/key_value_tags.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ const (
1919
RdsTagKeyPrefix = `rds:`
2020
)
2121

22+
// IgnoreConfig contains various options for removing resource tags.
23+
type IgnoreConfig struct {
24+
Keys KeyValueTags
25+
KeyPrefixes KeyValueTags
26+
}
27+
2228
// KeyValueTags is a standard implementation for AWS key-value resource tags.
2329
// The AWS Go SDK is split into multiple service packages, each service with
2430
// its own Go struct type representing a resource tag. To standardize logic
@@ -38,6 +44,18 @@ func (tags KeyValueTags) IgnoreAws() KeyValueTags {
3844
return result
3945
}
4046

47+
// IgnoreConfig returns any tags not removed by a given configuration.
48+
func (tags KeyValueTags) IgnoreConfig(config *IgnoreConfig) KeyValueTags {
49+
if config == nil {
50+
return tags
51+
}
52+
53+
result := tags.IgnorePrefixes(config.KeyPrefixes)
54+
result = result.Ignore(config.Keys)
55+
56+
return result
57+
}
58+
4159
// IgnoreElasticbeanstalk returns non-AWS and non-Elasticbeanstalk tag keys.
4260
func (tags KeyValueTags) IgnoreElasticbeanstalk() KeyValueTags {
4361
result := make(KeyValueTags)

aws/internal/keyvaluetags/key_value_tags_test.go

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,203 @@ func TestKeyValueTagsIgnoreAws(t *testing.T) {
6060
}
6161
}
6262

63+
func TestKeyValueTagsIgnoreConfig(t *testing.T) {
64+
testCases := []struct {
65+
name string
66+
tags KeyValueTags
67+
ignoreConfig *IgnoreConfig
68+
want map[string]string
69+
}{
70+
{
71+
name: "empty config",
72+
tags: New(map[string]string{
73+
"key1": "value1",
74+
"key2": "value2",
75+
"key3": "value3",
76+
}),
77+
ignoreConfig: &IgnoreConfig{},
78+
want: map[string]string{
79+
"key1": "value1",
80+
"key2": "value2",
81+
"key3": "value3",
82+
},
83+
},
84+
{
85+
name: "no config",
86+
tags: New(map[string]string{
87+
"key1": "value1",
88+
"key2": "value2",
89+
"key3": "value3",
90+
}),
91+
ignoreConfig: nil,
92+
want: map[string]string{
93+
"key1": "value1",
94+
"key2": "value2",
95+
"key3": "value3",
96+
},
97+
},
98+
{
99+
name: "no tags",
100+
tags: New(map[string]string{}),
101+
ignoreConfig: &IgnoreConfig{
102+
KeyPrefixes: New([]string{
103+
"key1",
104+
"key2",
105+
"key3",
106+
}),
107+
},
108+
want: map[string]string{},
109+
},
110+
{
111+
name: "keys all matching",
112+
tags: New(map[string]string{
113+
"key1": "value1",
114+
"key2": "value2",
115+
"key3": "value3",
116+
}),
117+
ignoreConfig: &IgnoreConfig{
118+
Keys: New(map[string]string{
119+
"key1": "value1",
120+
"key2": "value2",
121+
"key3": "value3",
122+
}),
123+
},
124+
want: map[string]string{},
125+
},
126+
{
127+
name: "keys some matching",
128+
tags: New(map[string]string{
129+
"key1": "value1",
130+
"key2": "value2",
131+
"key3": "value3",
132+
}),
133+
ignoreConfig: &IgnoreConfig{
134+
Keys: New(map[string]string{
135+
"key1": "value1",
136+
}),
137+
},
138+
want: map[string]string{
139+
"key2": "value2",
140+
"key3": "value3",
141+
},
142+
},
143+
{
144+
name: "keys none matching",
145+
tags: New(map[string]string{
146+
"key1": "value1",
147+
"key2": "value2",
148+
"key3": "value3",
149+
}),
150+
ignoreConfig: &IgnoreConfig{
151+
Keys: New(map[string]string{
152+
"key4": "value4",
153+
"key5": "value5",
154+
"key6": "value6",
155+
}),
156+
},
157+
want: map[string]string{
158+
"key1": "value1",
159+
"key2": "value2",
160+
"key3": "value3",
161+
},
162+
},
163+
{
164+
name: "keys and key prefixes",
165+
tags: New(map[string]string{
166+
"key1": "value1",
167+
"key2": "value2",
168+
"key3": "value3",
169+
}),
170+
ignoreConfig: &IgnoreConfig{
171+
Keys: New([]string{
172+
"key1",
173+
}),
174+
KeyPrefixes: New([]string{
175+
"key2",
176+
}),
177+
},
178+
want: map[string]string{
179+
"key3": "value3",
180+
},
181+
},
182+
{
183+
name: "key prefixes all exact",
184+
tags: New(map[string]string{
185+
"key1": "value1",
186+
"key2": "value2",
187+
"key3": "value3",
188+
}),
189+
ignoreConfig: &IgnoreConfig{
190+
KeyPrefixes: New([]string{
191+
"key1",
192+
"key2",
193+
"key3",
194+
}),
195+
},
196+
want: map[string]string{},
197+
},
198+
{
199+
name: "key prefixes all prefixed",
200+
tags: New(map[string]string{
201+
"key1": "value1",
202+
"key2": "value2",
203+
"key3": "value3",
204+
}),
205+
ignoreConfig: &IgnoreConfig{
206+
KeyPrefixes: New([]string{
207+
"key",
208+
}),
209+
},
210+
want: map[string]string{},
211+
},
212+
{
213+
name: "key prefixes some prefixed",
214+
tags: New(map[string]string{
215+
"key1": "value1",
216+
"key2": "value2",
217+
"key3": "value3",
218+
}),
219+
ignoreConfig: &IgnoreConfig{
220+
KeyPrefixes: New([]string{
221+
"key1",
222+
}),
223+
},
224+
want: map[string]string{
225+
"key2": "value2",
226+
"key3": "value3",
227+
},
228+
},
229+
{
230+
name: "key prefixes none prefixed",
231+
tags: New(map[string]string{
232+
"key1": "value1",
233+
"key2": "value2",
234+
"key3": "value3",
235+
}),
236+
ignoreConfig: &IgnoreConfig{
237+
KeyPrefixes: New([]string{
238+
"key4",
239+
"key5",
240+
"key6",
241+
}),
242+
},
243+
want: map[string]string{
244+
"key1": "value1",
245+
"key2": "value2",
246+
"key3": "value3",
247+
},
248+
},
249+
}
250+
251+
for _, testCase := range testCases {
252+
t.Run(testCase.name, func(t *testing.T) {
253+
got := testCase.tags.IgnoreConfig(testCase.ignoreConfig)
254+
255+
testKeyValueTagsVerifyMap(t, got.Map(), testCase.want)
256+
})
257+
}
258+
}
259+
63260
func TestKeyValueTagsIgnoreElasticbeanstalk(t *testing.T) {
64261
testCases := []struct {
65262
name string

aws/provider.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
88
"github.com/hashicorp/terraform-plugin-sdk/terraform"
99
homedir "github.com/mitchellh/go-homedir"
10+
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
1011
)
1112

1213
// Provider returns a terraform.ResourceProvider.
@@ -90,20 +91,29 @@ func Provider() terraform.ResourceProvider {
9091

9192
"endpoints": endpointsSchema(),
9293

93-
"ignore_tag_prefixes": {
94-
Type: schema.TypeSet,
95-
Optional: true,
96-
Elem: &schema.Schema{Type: schema.TypeString},
97-
Set: schema.HashString,
98-
Description: "Resource tag key prefixes to ignore across all resources.",
99-
},
100-
10194
"ignore_tags": {
102-
Type: schema.TypeSet,
95+
Type: schema.TypeList,
10396
Optional: true,
104-
Elem: &schema.Schema{Type: schema.TypeString},
105-
Set: schema.HashString,
106-
Description: "Resource tag keys to ignore across all resources.",
97+
MaxItems: 1,
98+
Description: "Configuration block with settings to ignore resource tags across all resources.",
99+
Elem: &schema.Resource{
100+
Schema: map[string]*schema.Schema{
101+
"keys": {
102+
Type: schema.TypeSet,
103+
Optional: true,
104+
Elem: &schema.Schema{Type: schema.TypeString},
105+
Set: schema.HashString,
106+
Description: "Resource tag keys to ignore across all resources.",
107+
},
108+
"key_prefixes": {
109+
Type: schema.TypeSet,
110+
Optional: true,
111+
Elem: &schema.Schema{Type: schema.TypeString},
112+
Set: schema.HashString,
113+
Description: "Resource tag key prefixes to ignore across all resources.",
114+
},
115+
},
116+
},
107117
},
108118

109119
"insecure": {
@@ -1109,6 +1119,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa
11091119
Region: d.Get("region").(string),
11101120
Endpoints: make(map[string]string),
11111121
MaxRetries: d.Get("max_retries").(int),
1122+
IgnoreTagsConfig: expandProviderIgnoreTags(d.Get("ignore_tags").([]interface{})),
11121123
Insecure: d.Get("insecure").(bool),
11131124
SkipCredsValidation: d.Get("skip_credentials_validation").(bool),
11141125
SkipGetEC2Platforms: d.Get("skip_get_ec2_platforms").(bool),
@@ -1152,18 +1163,6 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa
11521163
}
11531164
}
11541165

1155-
if v, ok := d.GetOk("ignore_tag_prefixes"); ok {
1156-
for _, ignoreTagPrefixRaw := range v.(*schema.Set).List() {
1157-
config.IgnoreTagPrefixes = append(config.IgnoreTagPrefixes, ignoreTagPrefixRaw.(string))
1158-
}
1159-
}
1160-
1161-
if v, ok := d.GetOk("ignore_tags"); ok {
1162-
for _, ignoreTagRaw := range v.(*schema.Set).List() {
1163-
config.IgnoreTags = append(config.IgnoreTags, ignoreTagRaw.(string))
1164-
}
1165-
}
1166-
11671166
if v, ok := d.GetOk("allowed_account_ids"); ok {
11681167
for _, accountIDRaw := range v.(*schema.Set).List() {
11691168
config.AllowedAccountIds = append(config.AllowedAccountIds, accountIDRaw.(string))
@@ -1241,3 +1240,22 @@ func endpointsSchema() *schema.Schema {
12411240
},
12421241
}
12431242
}
1243+
1244+
func expandProviderIgnoreTags(l []interface{}) *keyvaluetags.IgnoreConfig {
1245+
if len(l) == 0 || l[0] == nil {
1246+
return nil
1247+
}
1248+
1249+
ignoreConfig := &keyvaluetags.IgnoreConfig{}
1250+
m := l[0].(map[string]interface{})
1251+
1252+
if v, ok := m["keys"].(*schema.Set); ok {
1253+
ignoreConfig.Keys = keyvaluetags.New(v.List())
1254+
}
1255+
1256+
if v, ok := m["key_prefixes"].(*schema.Set); ok {
1257+
ignoreConfig.KeyPrefixes = keyvaluetags.New(v.List())
1258+
}
1259+
1260+
return ignoreConfig
1261+
}

0 commit comments

Comments
 (0)