Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Adding some more route53 resources #556

Merged
merged 8 commits into from
Sep 25, 2020
Merged
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
7 changes: 6 additions & 1 deletion resources/iam-role-policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package resources

import (
"fmt"
"github.com/sirupsen/logrus"
"strings"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -39,7 +40,11 @@ func ListIAMRolePolicies(sess *session.Session) ([]Resource, error) {
for {
policies, err := svc.ListRolePolicies(polParams)
if err != nil {
return nil, err
logrus.
WithError(err).
WithField("roleName", *role.RoleName).
Error("Failed to list policies")
break
}

for _, policyName := range policies.PolicyNames {
Expand Down
8 changes: 7 additions & 1 deletion resources/iam-roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/rebuy-de/aws-nuke/pkg/types"
"github.com/sirupsen/logrus"
)

type IAMRole struct {
Expand Down Expand Up @@ -37,8 +38,13 @@ func ListIAMRoles(sess *session.Session) ([]Resource, error) {
}
getroleOutput, err := svc.GetRole(getroleParams)
if err != nil {
return nil, err
logrus.
WithError(err).
WithField("roleName", *out.RoleName).
Error("Failed to get listed role")
continue
}

resources = append(resources, &IAMRole{
svc: svc,
role: getroleOutput.Role,
Expand Down
81 changes: 81 additions & 0 deletions resources/route53-resolver-endpoints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package resources

import (
"fmt"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/rebuy-de/aws-nuke/pkg/types"
)

// Route53ResolverEndpoint is the resource type for nuking
type Route53ResolverEndpoint struct {
svc *route53resolver.Route53Resolver
id *string
name *string
}

func init() {
register("Route53ResolverEndpoint", ListRoute53ResolverEndpoints)
}

// ListRoute53ResolverEndpoints produces the resources to be nuked
func ListRoute53ResolverEndpoints(sess *session.Session) ([]Resource, error) {
svc := route53resolver.New(sess)

params := &route53resolver.ListResolverEndpointsInput{}

var resources []Resource

for {
resp, err := svc.ListResolverEndpoints(params)

if err != nil {
return nil, err
}

for _, endpoint := range resp.ResolverEndpoints {
resolverEndpoint := &Route53ResolverEndpoint{
svc: svc,
id: endpoint.Id,
name: endpoint.Name,
}

resources = append(resources, resolverEndpoint)
}

if resp.NextToken == nil {
break
}

params.NextToken = resp.NextToken
}

return resources, nil
}

// Remove implements Resource
func (r *Route53ResolverEndpoint) Remove() error {
_, err := r.svc.DeleteResolverEndpoint(
&route53resolver.DeleteResolverEndpointInput{
ResolverEndpointId: r.id,
})

if err != nil {
return err
}

return nil
}

// Properties provides debugging output
func (r *Route53ResolverEndpoint) Properties() types.Properties {
return types.NewProperties().
Set("EndpointID", r.id).
Set("Name", r.name)
}

// String implements Stringer
func (r *Route53ResolverEndpoint) String() string {
return fmt.Sprintf("%s (%s)", *r.id, *r.name)
}
140 changes: 140 additions & 0 deletions resources/route53-resolver-rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package resources

import (
"fmt"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/rebuy-de/aws-nuke/pkg/types"
)

type (
// Route53ResolverRule is the resource type
Route53ResolverRule struct {
svc *route53resolver.Route53Resolver
id *string
name *string
domainName *string
vpcIds []*string
}
)

func init() {
register("Route53ResolverRule", ListRoute53ResolverRules)
}

// ListRoute53ResolverRules produces the resources to be nuked.
func ListRoute53ResolverRules(sess *session.Session) ([]Resource, error) {
svc := route53resolver.New(sess)

vpcAssociations, err := resolverRulesToVpcIDs(svc)
if err != nil {
return nil, err
}

var resources []Resource

params := &route53resolver.ListResolverRulesInput{}
for {
resp, err := svc.ListResolverRules(params)

if err != nil {
return nil, err
}

for _, rule := range resp.ResolverRules {
resources = append(resources, &Route53ResolverRule{
svc: svc,
id: rule.Id,
name: rule.Name,
domainName: rule.DomainName,
vpcIds: vpcAssociations[*rule.Id],
})
}

if resp.NextToken == nil {
break
}

params.NextToken = resp.NextToken
}

return resources, nil
}

// Associate all the vpcIDs to their resolver rule ID to be disassociated before deleting the rule.
func resolverRulesToVpcIDs(svc *route53resolver.Route53Resolver) (map[string][]*string, error) {
vpcAssociations := map[string][]*string{}

params := &route53resolver.ListResolverRuleAssociationsInput{}

for {
resp, err := svc.ListResolverRuleAssociations(params)

if err != nil {
return nil, err
}

for _, ruleAssociation := range resp.ResolverRuleAssociations {
vpcID := ruleAssociation.VPCId
if vpcID != nil {
resolverRuleID := *ruleAssociation.ResolverRuleId

if _, ok := vpcAssociations[resolverRuleID]; !ok {
vpcAssociations[resolverRuleID] = []*string{vpcID}
} else {
vpcAssociations[resolverRuleID] = append(vpcAssociations[resolverRuleID], vpcID)
}
}
}

if resp.NextToken == nil {
break
}

params.NextToken = resp.NextToken
}

return vpcAssociations, nil
}

// Filter removes resources automatically from being nuked
func (r *Route53ResolverRule) Filter() error {
if *r.domainName == "." {
return fmt.Errorf(`Filtering DomainName "."`)
}

return nil
}

// Remove implements Resource
func (r *Route53ResolverRule) Remove() error {
for _, vpcID := range r.vpcIds {
_, err := r.svc.DisassociateResolverRule(&route53resolver.DisassociateResolverRuleInput{
ResolverRuleId: r.id,
VPCId: vpcID,
})

if err != nil {
return err
}
}

_, err := r.svc.DeleteResolverRule(&route53resolver.DeleteResolverRuleInput{
ResolverRuleId: r.id,
})

return err
}

// Properties provides debugging output
func (r *Route53ResolverRule) Properties() types.Properties {
return types.NewProperties().
Set("ID", r.id).
Set("Name", r.name)
}

// String implements Stringer
func (r *Route53ResolverRule) String() string {
return fmt.Sprintf("%s (%s)", *r.id, *r.name)
}
113 changes: 113 additions & 0 deletions resources/route53-traffic-policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package resources

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53"
"github.com/rebuy-de/aws-nuke/pkg/types"
)

type Route53TrafficPolicy struct {
svc *route53.Route53
id *string
name *string
version *int64
instances []*route53.TrafficPolicyInstance
}

func init() {
register("Route53TrafficPolicy", ListRoute53TrafficPolicies)
}

func ListRoute53TrafficPolicies(sess *session.Session) ([]Resource, error) {
svc := route53.New(sess)
params := &route53.ListTrafficPoliciesInput{}
resources := make([]Resource, 0)

for {
resp, err := svc.ListTrafficPolicies(params)
if err != nil {
return nil, err
}

for _, trafficPolicy := range resp.TrafficPolicySummaries {
instances, err := instancesForPolicy(svc, trafficPolicy.Id, trafficPolicy.LatestVersion)

if err != nil {
return nil, fmt.Errorf("failed to get instance for policy %s %w", *trafficPolicy.Id, err)
}

resources = append(resources, &Route53TrafficPolicy{
svc: svc,
id: trafficPolicy.Id,
name: trafficPolicy.Name,
version: trafficPolicy.LatestVersion,
instances: instances,
})
}

if aws.BoolValue(resp.IsTruncated) == false {
break
}
params.TrafficPolicyIdMarker = resp.TrafficPolicyIdMarker
}

return resources, nil
}

func instancesForPolicy(svc *route53.Route53, policyID *string, version *int64) ([]*route53.TrafficPolicyInstance, error) {
var instances []*route53.TrafficPolicyInstance
params := &route53.ListTrafficPolicyInstancesByPolicyInput{
TrafficPolicyId: policyID,
TrafficPolicyVersion: version,
}

for {
resp, err := svc.ListTrafficPolicyInstancesByPolicy(params)

if err != nil {
return nil, err
}

for _, instance := range resp.TrafficPolicyInstances {
instances = append(instances, instance)
}

if aws.BoolValue(resp.IsTruncated) == false {
break
}

params.TrafficPolicyInstanceTypeMarker = resp.TrafficPolicyInstanceTypeMarker
params.TrafficPolicyInstanceNameMarker = resp.TrafficPolicyInstanceNameMarker
}
return instances, nil
}

func (tp *Route53TrafficPolicy) Remove() error {
for _, instance := range tp.instances {
_, err := tp.svc.DeleteTrafficPolicyInstance(&route53.DeleteTrafficPolicyInstanceInput{
Id: instance.Id,
})

if err != nil {
return fmt.Errorf("failed to delete instance %s %w", *instance.Id, err)
}
}

params := &route53.DeleteTrafficPolicyInput{
Id: tp.id,
Version: tp.version,
}

_, err := tp.svc.DeleteTrafficPolicy(params)

return err
}

func (tp *Route53TrafficPolicy) Properties() types.Properties {
return types.NewProperties().
Set("ID", *tp.id).
Set("Name", *tp.name)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, completely missed this the first time. Could you please add a String() function for traffic policies?