Skip to content

Commit

Permalink
Merge pull request #473 from ekristen/parent-tags
Browse files Browse the repository at this point in the history
feat: pass tags to related resources for kms and route53
  • Loading branch information
ekristen authored Dec 24, 2024
2 parents 9d839a8 + 74753ef commit d7a7494
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 23 deletions.
6 changes: 5 additions & 1 deletion docs/resources/kms-alias.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ KMSAlias
## Properties


- `Name`: No Description
- `CreationDate`: The creation date of the KMS alias
- `Name`: The name of the KMS alias
- `TargetKeyID`: The KMS Key ID that the alias points to
- `tag:<key>:`: This resource has tags with property `Tags`. These are key/value pairs that are
added as their own property with the prefix of `tag:` (e.g. [tag:example: "value"])

!!! note - Using Properties
Properties are what [Filters](../config-filtering.md) are written against in your configuration. You use the property
Expand Down
20 changes: 18 additions & 2 deletions resources/kms-alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/aws/aws-sdk-go/service/kms"
"github.com/aws/aws-sdk-go/service/kms/kmsiface"
Expand Down Expand Up @@ -43,9 +44,21 @@ func (l *KMSAliasLister) List(_ context.Context, o interface{}) ([]resource.Reso

err := svc.ListAliasesPages(nil, func(page *kms.ListAliasesOutput, lastPage bool) bool {
for _, alias := range page.Aliases {
var tags []*kms.Tag
if alias.TargetKeyId != nil {
keyTags, err := svc.ListResourceTags(&kms.ListResourceTagsInput{
KeyId: alias.TargetKeyId,
})
if err != nil {
opts.Logger.WithError(err).Error("failed to list tags for key")
}
tags = keyTags.Tags
}

resources = append(resources, &KMSAlias{
svc: svc,
Name: alias.AliasName,
Tags: tags,
})
}
return true
Expand All @@ -58,8 +71,11 @@ func (l *KMSAliasLister) List(_ context.Context, o interface{}) ([]resource.Reso
}

type KMSAlias struct {
svc kmsiface.KMSAPI
Name *string
svc kmsiface.KMSAPI
Name *string `description:"The name of the KMS alias"`
CreationDate *time.Time `description:"The creation date of the KMS alias"`
TargetKeyID *string `description:"The KMS Key ID that the alias points to"`
Tags []*kms.Tag `property:"tagPrefix=key:tag"`
}

func (r *KMSAlias) Filter() error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (l *Route53ResourceRecordSetLister) List(ctx context.Context, o interface{}

for _, r := range sub {
zone := r.(*Route53HostedZone)
rrs, err := ListResourceRecordsForZone(svc, zone.id, zone.name)
rrs, err := ListResourceRecordsForZone(svc, zone.id, zone.name, zone.tags)
if err != nil {
return nil, err
}
Expand All @@ -55,13 +55,13 @@ func (l *Route53ResourceRecordSetLister) List(ctx context.Context, o interface{}
return resources, nil
}

func ListResourceRecordsForZone(svc *route53.Route53, zoneID, zoneName *string) ([]resource.Resource, error) {
func ListResourceRecordsForZone(svc *route53.Route53, zoneID, zoneName *string, zoneTags []*route53.Tag) ([]resource.Resource, error) {
resources := make([]resource.Resource, 0)

params := &route53.ListResourceRecordSetsInput{
HostedZoneId: zoneID,
}

resources := make([]resource.Resource, 0)

for {
resp, err := svc.ListResourceRecordSets(params)
if err != nil {
Expand All @@ -70,10 +70,13 @@ func ListResourceRecordsForZone(svc *route53.Route53, zoneID, zoneName *string)

for _, rrs := range resp.ResourceRecordSets {
resources = append(resources, &Route53ResourceRecordSet{
svc: svc,
hostedZoneID: zoneID,
hostedZoneName: zoneName,
data: rrs,
svc: svc,
hostedZoneID: zoneID,
HostedZoneName: zoneName,
resourceRecordSet: rrs,
Name: rrs.Name,
Type: rrs.Type,
Tags: zoneTags,
})
}

Expand All @@ -90,19 +93,22 @@ func ListResourceRecordsForZone(svc *route53.Route53, zoneID, zoneName *string)
}

type Route53ResourceRecordSet struct {
svc *route53.Route53
hostedZoneID *string
hostedZoneName *string
data *route53.ResourceRecordSet
changeID *string
svc *route53.Route53
resourceRecordSet *route53.ResourceRecordSet // Note: this is required for the deletion
changeID *string
hostedZoneID *string
HostedZoneName *string `description:"The name of the zone to which the record belongs"`
Name *string `description:"The name of the record"`
Type *string `description:"The type of the record"`
Tags []*route53.Tag `property:"tagPrefix=zone:tag"`
}

func (r *Route53ResourceRecordSet) Filter() error {
if *r.data.Type == "NS" && *r.hostedZoneName == *r.data.Name {
if *r.Type == "NS" && *r.HostedZoneName == *r.Name {
return fmt.Errorf("cannot delete NS record")
}

if *r.data.Type == "SOA" {
if *r.Type == "SOA" {
return fmt.Errorf("cannot delete SOA record")
}

Expand All @@ -116,7 +122,7 @@ func (r *Route53ResourceRecordSet) Remove(_ context.Context) error {
Changes: []*route53.Change{
{
Action: aws.String("DELETE"),
ResourceRecordSet: r.data,
ResourceRecordSet: r.resourceRecordSet,
},
},
},
Expand All @@ -133,11 +139,9 @@ func (r *Route53ResourceRecordSet) Remove(_ context.Context) error {
}

func (r *Route53ResourceRecordSet) Properties() types.Properties {
return types.NewProperties().
Set("Name", r.data.Name).
Set("Type", r.data.Type)
return types.NewPropertiesFromStruct(r)
}

func (r *Route53ResourceRecordSet) String() string {
return ptr.ToString(r.data.Name)
return ptr.ToString(r.Name)
}
49 changes: 49 additions & 0 deletions resources/route53-resource-record_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package resources

import (
"testing"

"github.com/gotidy/ptr"
"github.com/stretchr/testify/assert"

"github.com/aws/aws-sdk-go/service/route53"
)

func TestRoute53ResourceRecordSet_Properties(t *testing.T) {
cases := []struct {
name string
recordType string
}{
{
name: "example.com",
recordType: "NS",
},
{
name: "example.com",
recordType: "SOA",
},
{
name: "subdomain.example.com",
recordType: "A",
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
r := &Route53ResourceRecordSet{
resourceRecordSet: &route53.ResourceRecordSet{
Name: ptr.String(tc.name),
Type: ptr.String(tc.recordType),
},
Name: ptr.String(tc.name),
Type: ptr.String(tc.recordType),
}

got := r.Properties()
assert.Equal(t, tc.name, got.Get("Name"))
assert.Equal(t, tc.recordType, got.Get("Type"))

assert.Equal(t, tc.name, r.String())
})
}
}

0 comments on commit d7a7494

Please sign in to comment.