Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proof of Concept] provider: default tags implementation #17941

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/17941.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
provider: Add `default_tags` argument (in public preview, see note above)
anGie44 marked this conversation as resolved.
Show resolved Hide resolved
```
9 changes: 6 additions & 3 deletions aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ type Config struct {
AllowedAccountIds []string
ForbiddenAccountIds []string

Endpoints map[string]string
IgnoreTagsConfig *keyvaluetags.IgnoreConfig
Insecure bool
DefaultTagsConfig *keyvaluetags.DefaultConfig
Endpoints map[string]string
IgnoreTagsConfig *keyvaluetags.IgnoreConfig
Insecure bool

SkipCredsValidation bool
SkipGetEC2Platforms bool
Expand Down Expand Up @@ -249,6 +250,7 @@ type AWSClient struct {
datapipelineconn *datapipeline.DataPipeline
datasyncconn *datasync.DataSync
daxconn *dax.DAX
DefaultTagsConfig *keyvaluetags.DefaultConfig
devicefarmconn *devicefarm.DeviceFarm
dlmconn *dlm.DLM
dmsconn *databasemigrationservice.DatabaseMigrationService
Expand Down Expand Up @@ -492,6 +494,7 @@ func (c *Config) Client() (interface{}, error) {
datapipelineconn: datapipeline.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["datapipeline"])})),
datasyncconn: datasync.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["datasync"])})),
daxconn: dax.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["dax"])})),
DefaultTagsConfig: c.DefaultTagsConfig,
devicefarmconn: devicefarm.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["devicefarm"])})),
dlmconn: dlm.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["dlm"])})),
dmsconn: databasemigrationservice.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["dms"])})),
Expand Down
76 changes: 76 additions & 0 deletions aws/internal/keyvaluetags/key_value_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ const (
ServerlessApplicationRepositoryTagKeyPrefix = `serverlessrepo:`
)

// DefaultConfig contains tags to default across all resources.
type DefaultConfig struct {
Tags KeyValueTags
}

// IgnoreConfig contains various options for removing resource tags.
type IgnoreConfig struct {
Keys KeyValueTags
Expand All @@ -50,6 +55,32 @@ func (tags KeyValueTags) IgnoreAws() KeyValueTags {
return result
}

// Merge calls keyvaluetags.Merge() on the given DefaultConfig.Tags, if any,
// with KeyValueTags provided as an argument, overriding the value
// of any tag with a matching key.
func (config *DefaultConfig) Merge(tags KeyValueTags) KeyValueTags {
anGie44 marked this conversation as resolved.
Show resolved Hide resolved
if len(config.Tags) == 0 {
return tags
}

return config.Tags.Merge(tags)
}

// TagsEqual returns true if the given configuration's Tags
// are equal to those passed in as an argument;
// otherwise returns false
func (config *DefaultConfig) TagsEqual(tags KeyValueTags) bool {
if len(config.Tags) == 0 {
return len(tags) == 0
}

if len(tags) == 0 {
return false
}

return config.Tags.ContainsAll(tags)
}

// IgnoreConfig returns any tags not removed by a given configuration.
func (tags KeyValueTags) IgnoreConfig(config *IgnoreConfig) KeyValueTags {
if config == nil {
Expand Down Expand Up @@ -401,6 +432,27 @@ func (tags KeyValueTags) Hash() int {
return hash
}

// RemoveDefaultConfig returns tags not present in a DefaultConfig object
// in addition to tags with key/value pairs that override those in a DefaultConfig;
// however, if all tags present in the DefaultConfig object are equivalent to those
// in the given KeyValueTags, then the KeyValueTags are returned, effectively
// bypassing the need to remove differing tags.
func (tags KeyValueTags) RemoveDefaultConfig(config *DefaultConfig) KeyValueTags {
if config == nil || len(config.Tags) == 0 {
return tags
}

result := make(KeyValueTags)

for k, v := range tags {
if defaultVal, ok := config.Tags[k]; !ok || !v.Equal(defaultVal) {
result[k] = v
}
}

return result
}

// String returns the default string representation of the KeyValueTags.
func (tags KeyValueTags) String() string {
var builder strings.Builder
Expand Down Expand Up @@ -435,6 +487,30 @@ func (tags KeyValueTags) UrlEncode() string {
return values.Encode()
}

// MergeConfigTags creates KeyValueTags by merging KeyValueTags nested in
// a configuration object with those represented as a map[string]interface{}.
// Currently only supports the DefaultConfig type when passed to the interface{} argument.
func MergeConfigTags(config interface{}, tags map[string]interface{}) KeyValueTags {
anGie44 marked this conversation as resolved.
Show resolved Hide resolved
kvTags := New(tags)

if config == nil {
return kvTags
}

var result KeyValueTags

switch t := config.(type) {
case *DefaultConfig:
if t == nil || len(t.Tags) == 0 {
result = kvTags
} else {
result = t.Merge(kvTags)
}
}

return result
}

// New creates KeyValueTags from common Terraform Provider SDK types.
// Supports map[string]string, map[string]*string, map[string]interface{}, and []interface{}.
// When passed []interface{}, all elements are treated as keys and assigned nil values.
Expand Down
Loading