Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Commit

Permalink
Add RDS event subscriptions (#322)
Browse files Browse the repository at this point in the history
* Add RDS event subscriptions
  • Loading branch information
irmatov authored Dec 3, 2021
1 parent 4e4634e commit 415d59d
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 7 deletions.
40 changes: 40 additions & 0 deletions client/mocks/mock_rds.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions client/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ type RdsClient interface {
DescribeDBSnapshotAttributes(ctx context.Context, params *rds.DescribeDBSnapshotAttributesInput, optFns ...func(*rds.Options)) (*rds.DescribeDBSnapshotAttributesOutput, error)
DescribeDBSnapshots(ctx context.Context, params *rds.DescribeDBSnapshotsInput, optFns ...func(*rds.Options)) (*rds.DescribeDBSnapshotsOutput, error)
DescribeDBSubnetGroups(ctx context.Context, params *rds.DescribeDBSubnetGroupsInput, optFns ...func(*rds.Options)) (*rds.DescribeDBSubnetGroupsOutput, error)
DescribeEventSubscriptions(ctx context.Context, params *rds.DescribeEventSubscriptionsInput, optFns ...func(*rds.Options)) (*rds.DescribeEventSubscriptionsOutput, error)
ListTagsForResource(ctx context.Context, params *rds.ListTagsForResourceInput, optFns ...func(*rds.Options)) (*rds.ListTagsForResourceOutput, error)
}

//go:generate mockgen -package=mocks -destination=./mocks/mock_s3Control.go . S3ControlClient
Expand Down
19 changes: 19 additions & 0 deletions docs/tables/aws_rds_event_subscriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

# Table: aws_rds_event_subscriptions
Contains the results of a successful invocation of the DescribeEventSubscriptions action.
## Columns
| Name | Type | Description |
| ------------- | ------------- | ----- |
|account_id|text|The AWS Account ID of the resource.|
|region|text|The AWS Region of the resource.|
|cust_subscription_id|text|The RDS event notification subscription Id.|
|customer_aws_id|text|The AWS customer account associated with the RDS event notification subscription.|
|enabled|boolean|A Boolean value indicating if the subscription is enabled|
|event_categories_list|text[]|A list of event categories for the RDS event notification subscription.|
|arn|text|The Amazon Resource Name (ARN) for the event subscription.|
|sns_topic_arn|text|The topic ARN of the RDS event notification subscription.|
|source_ids_list|text[]|A list of source IDs for the RDS event notification subscription.|
|source_type|text|The source type for the RDS event notification subscription.|
|status|text|The status of the RDS event notification subscription|
|subscription_creation_time|text|The time the RDS event notification subscription was created.|
|tags|jsonb|List of tags|
5 changes: 0 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ github.com/aws/aws-sdk-go-v2 v1.6.0/go.mod h1:tI4KhsR5VkzlUa2DZAdwx7wCAYGwkZZ1H3
github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.11.0/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ=
github.com/aws/aws-sdk-go-v2 v1.11.1 h1:GzvOVAdTbWxhEMRK4FfiblkGverOkAT0UodDxC1jHQM=
github.com/aws/aws-sdk-go-v2 v1.11.1/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ=
github.com/aws/aws-sdk-go-v2 v1.11.2 h1:SDiCYqxdIYi6HgQfAWRhgdZrdnOuGyLDJVRSWLeHWvs=
github.com/aws/aws-sdk-go-v2 v1.11.2/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ=
Expand All @@ -156,12 +155,10 @@ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.1.2/go.mod h1:Azf567f5wBUfUbw
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.2.1 h1:ZZs6209e+yocx7jnT+TySOjt6/jk1LKdAPtT1fAPuio=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.2.1/go.mod h1:2JOqaBP3I6TEm27NLb11UiD9j4HZsJ+EW4N7vCf8WGQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.0/go.mod h1:NO3Q5ZTTQtO2xIg2+xTXYDiT7knSejfeDm7WGDaOo0U=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.1 h1:LZwqhOyqQ2w64PZk04V0Om9AEExtW8WMkCRoE1h9/94=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.1/go.mod h1:22SEiBSQm5AyKEjoPcG1hzpeTI+m9CXfE6yt1h49wBE=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2 h1:XJLnluKuUxQG255zPNe+04izXl7GSyUVafIsgfv9aw4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2/go.mod h1:SgKKNBIoDC/E1ZCDhhMW3yalWjwuLjMcpLzsM/QQnWo=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.0/go.mod h1:anlUzBoEWglcUxUQwZA7HQOEVEnQALVZsizAapB2hq8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.1 h1:ObMfGNk0xjOWduPxsrRWVwZZia3e9fOcO6zlKCkt38s=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.1/go.mod h1:1xvCD+I5BcDuQUc+psZr7LI1a9pclAWZs3S3Gce5+lg=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2 h1:EauRoYZVNPlidZSZJDscjJBQ22JhVF2+tdteatax2Ak=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2/go.mod h1:xT4XX6w5Sa3dhg50JrYyy3e4WPYo/+WjY/BXtqXVunU=
Expand Down Expand Up @@ -261,8 +258,6 @@ github.com/aws/aws-sdk-go-v2/service/s3control v1.14.1 h1:Nmcb6pxJtjJof+mmF9TJvy
github.com/aws/aws-sdk-go-v2/service/s3control v1.14.1/go.mod h1:dTnxIRqR69JUZobQDUh47rlbYe8PzTd0k4o+gDkHeV4=
github.com/aws/aws-sdk-go-v2/service/sagemaker v1.19.1 h1:cy6fUlP94vzD/0VUD3SWGUBfYrOr+zP+ChsTxUtZydQ=
github.com/aws/aws-sdk-go-v2/service/sagemaker v1.19.1/go.mod h1:G9AcXDbGtZVA8XBdmpbVQv1lvmiuk4I9n2MQlp1FJ9k=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.10.1 h1:e0gg30cCKsNHV+WD17zbzipx5nYRrnb+4Y5wO5pap80=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.10.1/go.mod h1:vUIn46AiFjPEm4/ALXV1weLTEWu37mF6OfLMw5vxG2Q=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.10.2 h1:v+mZVbY9IBYPFFFWNwuwfpUwmwD37AoQFW7sa//hNvY=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.10.2/go.mod h1:Lo6aZ+bIbBYL6LyElc7tWEcotGHrEUOqMK7uhkYQfoA=
github.com/aws/aws-sdk-go-v2/service/sns v1.1.2 h1:1U/FujyBEkNwrvANUcZFuVnAQqy0EAUEGToso5Dcijs=
Expand Down
34 changes: 34 additions & 0 deletions resources/integration_tests/aws_rds_event_subscriptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package integration_tests

import (
"fmt"
"testing"

"github.com/cloudquery/cq-provider-aws/resources"
providertest "github.com/cloudquery/cq-provider-sdk/provider/testing"
)

func TestIntegrationRdsEventSubscriptions(t *testing.T) {
table := resources.RdsEventSubscriptions()
awsTestIntegrationHelper(t, table, []string{"aws_rds_event_subscriptions.tf", "aws_sns.tf", "aws_rds_instances.tf"}, func(res *providertest.ResourceIntegrationTestData) providertest.ResourceIntegrationVerification {
return providertest.ResourceIntegrationVerification{
Name: table.Name,
ExpectedValues: []providertest.ExpectedValue{
{
Count: 1,
Data: map[string]interface{}{
"cust_subscription_id": fmt.Sprintf("rds-event-sub-%s-%s", res.Prefix, res.Suffix),
"enabled": true,
"event_categories_list": []interface{}{"failure"},
"source_type": "db-instance",
"status": "active",
"tags": map[string]interface{}{
"Type": "integration_test",
"TestId": res.Suffix,
},
},
},
},
}
})
}
13 changes: 12 additions & 1 deletion resources/integration_tests/aws_sns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,22 @@ func TestIntegrationSnsTopics(t *testing.T) {
Count: 1,
Data: map[string]interface{}{
"content_based_deduplication": true,
"display_name": fmt.Sprintf("%s-%s", res.Prefix, res.Suffix),
},
},
{
Count: 1,
Data: map[string]interface{}{
"content_based_deduplication": false,
"display_name": fmt.Sprintf("sns-test2-%s-%s", res.Prefix, res.Suffix),
},
},
},
Filter: func(sb squirrel.SelectBuilder, res *providertest.ResourceIntegrationTestData) squirrel.SelectBuilder {
return sb.Where(squirrel.Eq{"display_name": fmt.Sprintf("%s-%s", res.Prefix, res.Suffix)})
return sb.Where(squirrel.Or{
squirrel.Eq{"display_name": fmt.Sprintf("%s-%s", res.Prefix, res.Suffix)},
squirrel.Eq{"display_name": fmt.Sprintf("sns-test2-%s-%s", res.Prefix, res.Suffix)},
})
},
}
})
Expand Down
11 changes: 11 additions & 0 deletions resources/integration_tests/infra/aws_rds_event_subscriptions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "aws_db_event_subscription" "rds_event_subscription" {
name = "rds-event-sub-${var.test_prefix}-${var.test_suffix}"
sns_topic = aws_sns_topic.sns_test2.arn

source_type = "db-instance"
source_ids = [aws_db_instance.rds_db_instance.id]

event_categories = [
"failure",
]
}
7 changes: 6 additions & 1 deletion resources/integration_tests/infra/aws_sns.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ resource "aws_sns_topic_subscription" "sns_test_subscription" {
topic_arn = aws_sns_topic.sns_test.arn
protocol = "sqs"
endpoint = aws_sqs_queue.sns_test_queue.arn
}
}

resource "aws_sns_topic" "sns_test2" {
name = "sns-test2-${var.test_prefix}-${var.test_suffix}"
display_name = "sns-test2-${var.test_prefix}-${var.test_suffix}"
}
1 change: 1 addition & 0 deletions resources/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func Provider() *provider.Provider {
"lambda.layers": LambdaLayers(),
"mq.brokers": MqBrokers(),
"organizations.accounts": OrganizationsAccounts(),
"rds.event_subscriptions": RdsEventSubscriptions(),
"rds.certificates": RdsCertificates(),
"rds.clusters": RdsClusters(),
"rds.cluster_snapshots": RdsClusterSnapshots(),
Expand Down
138 changes: 138 additions & 0 deletions resources/rds_event_subscriptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package resources

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/aws/aws-sdk-go-v2/service/rds/types"
"github.com/cloudquery/cq-provider-aws/client"
"github.com/cloudquery/cq-provider-sdk/provider/schema"
)

func RdsEventSubscriptions() *schema.Table {
return &schema.Table{
Name: "aws_rds_event_subscriptions",
Description: "Contains the results of a successful invocation of the DescribeEventSubscriptions action.",
Resolver: fetchRdsEventSubscriptions,
Multiplex: client.AccountRegionMultiplex,
IgnoreError: client.IgnoreAccessDeniedServiceDisabled,
DeleteFilter: client.DeleteAccountRegionFilter,
Options: schema.TableCreationOptions{PrimaryKeys: []string{"arn"}},
Columns: []schema.Column{
{
Name: "account_id",
Description: "The AWS Account ID of the resource.",
Type: schema.TypeString,
Resolver: client.ResolveAWSAccount,
},
{
Name: "region",
Description: "The AWS Region of the resource.",
Type: schema.TypeString,
Resolver: client.ResolveAWSRegion,
},
{
Name: "cust_subscription_id",
Description: "The RDS event notification subscription Id.",
Type: schema.TypeString,
},
{
Name: "customer_aws_id",
Description: "The AWS customer account associated with the RDS event notification subscription.",
Type: schema.TypeString,
},
{
Name: "enabled",
Description: "A Boolean value indicating if the subscription is enabled",
Type: schema.TypeBool,
},
{
Name: "event_categories_list",
Description: "A list of event categories for the RDS event notification subscription.",
Type: schema.TypeStringArray,
},
{
Name: "arn",
Description: "The Amazon Resource Name (ARN) for the event subscription.",
Type: schema.TypeString,
Resolver: schema.PathResolver("EventSubscriptionArn"),
},
{
Name: "sns_topic_arn",
Description: "The topic ARN of the RDS event notification subscription.",
Type: schema.TypeString,
},
{
Name: "source_ids_list",
Description: "A list of source IDs for the RDS event notification subscription.",
Type: schema.TypeStringArray,
},
{
Name: "source_type",
Description: "The source type for the RDS event notification subscription.",
Type: schema.TypeString,
},
{
Name: "status",
Description: "The status of the RDS event notification subscription",
Type: schema.TypeString,
},
{
Name: "subscription_creation_time",
Description: "The time the RDS event notification subscription was created.",
Type: schema.TypeString,
},
{
Name: "tags",
Description: "List of tags",
Type: schema.TypeJSON,
Resolver: resolveRDSEventSubscriptionTags,
},
},
}
}

// ====================================================================================================================
// Table Resolver Functions
// ====================================================================================================================
func fetchRdsEventSubscriptions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan interface{}) error {
cl := meta.(*client.Client)
svc := cl.Services().RDS
var input rds.DescribeEventSubscriptionsInput
for {
out, err := svc.DescribeEventSubscriptions(ctx, &input, func(o *rds.Options) {
o.Region = cl.Region
})
if err != nil {
return err
}
res <- out.EventSubscriptionsList
if aws.ToString(out.Marker) == "" {
break
}
input.Marker = out.Marker
}
return nil
}

func resolveRDSEventSubscriptionTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error {
s, ok := resource.Item.(types.EventSubscription)
if !ok {
return fmt.Errorf("not a %T: %T", s, resource.Item)
}
cl := meta.(*client.Client)
svc := cl.Services().RDS
out, err := svc.ListTagsForResource(ctx, &rds.ListTagsForResourceInput{ResourceName: s.EventSubscriptionArn}, func(o *rds.Options) {
o.Region = cl.Region
})
if err != nil {
return err
}
tags := make(map[string]string, len(out.TagList))
for _, t := range out.TagList {
tags[aws.ToString(t.Key)] = aws.ToString(t.Value)
}
return resource.Set(c.Name, tags)
}
41 changes: 41 additions & 0 deletions resources/rds_event_subscriptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package resources

import (
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/aws/aws-sdk-go-v2/service/rds/types"
"github.com/cloudquery/cq-provider-aws/client"
"github.com/cloudquery/cq-provider-aws/client/mocks"
"github.com/cloudquery/faker/v3"
"github.com/golang/mock/gomock"
)

func buildRDSEventSubscriptions(t *testing.T, ctrl *gomock.Controller) client.Services {
mock := mocks.NewMockRdsClient(ctrl)
var s types.EventSubscription
if err := faker.FakeData(&s); err != nil {
t.Fatal(err)
}
mock.EXPECT().DescribeEventSubscriptions(gomock.Any(), &rds.DescribeEventSubscriptionsInput{}, gomock.Any()).Return(
&rds.DescribeEventSubscriptionsOutput{EventSubscriptionsList: []types.EventSubscription{s}},
nil,
)

mock.EXPECT().ListTagsForResource(
gomock.Any(),
&rds.ListTagsForResourceInput{ResourceName: s.EventSubscriptionArn},
gomock.Any(),
).Return(
&rds.ListTagsForResourceOutput{
TagList: []types.Tag{{Key: aws.String("key"), Value: aws.String("value")}},
},
nil,
)
return client.Services{RDS: mock}
}

func TestRDSEventSubscriptions(t *testing.T) {
awsTestHelper(t, RdsEventSubscriptions(), buildRDSEventSubscriptions, TestOptions{})
}

0 comments on commit 415d59d

Please sign in to comment.