add support for aws_sns_topic_subscription

main
Martin Guibert 2021-02-05 11:03:45 +01:00
parent b9613f34ec
commit 18f7ad6bb8
26 changed files with 687625 additions and 2 deletions

View File

@ -132,7 +132,10 @@ As AWS documentation recommends, the below policy is granting only the permissio
"sqs:ListQueues"
"sns:ListTopics",
"sns:GetTopicAttributes",
"sns:ListTagsForResource"
"sns:ListTagsForResource",
"sns:ListSubscriptions",
"sns:ListSubscriptionsByTopic",
"sns:GetSubscriptionAttributes"
]
}
]
@ -252,6 +255,6 @@ As AWS documentation recommends, the below policy is granting only the permissio
## SNS
- [x] aws_sns_topic
- [x] aws_sns_topic_policy
- [ ] aws_sns_topic_subscription
- [x] aws_sns_topic_subscription
- [ ] aws_sns_platform_application
- [ ] aws_sns_sms_preferences

View File

@ -13,6 +13,29 @@ type SNSRepository struct {
mock.Mock
}
// ListAllSubscriptions provides a mock function with given fields:
func (_m *SNSRepository) ListAllSubscriptions() ([]*sns.Subscription, error) {
ret := _m.Called()
var r0 []*sns.Subscription
if rf, ok := ret.Get(0).(func() []*sns.Subscription); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*sns.Subscription)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllTopics provides a mock function with given fields:
func (_m *SNSRepository) ListAllTopics() ([]*sns.Topic, error) {
ret := _m.Called()

View File

@ -51,5 +51,6 @@ func Deserializers() []deserializer.CTYDeserializer {
awsdeserializer.NewSqsQueuePolicyDeserializer(),
awsdeserializer.NewSNSTopicDeserializer(),
awsdeserializer.NewSNSTopicPolicyDeserializer(),
awsdeserializer.NewSNSTopicSubscriptionDeserializer(),
}
}

View File

@ -78,6 +78,7 @@ func TestTerraformStateReader_Resources(t *testing.T) {
{name: "SQS queue policy", dirName: "sqs_queue_policy", wantErr: false},
{name: "SNS Topic", dirName: "sns_topic", wantErr: false},
{name: "SNS Topic Policy", dirName: "sns_topic_policy", wantErr: false},
{name: "SNS Topic Subscription", dirName: "sns_topic_subscription", wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -0,0 +1,26 @@
[
{
"Arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"ConfirmationTimeoutInMinutes": 1,
"DeliveryPolicy": "",
"Endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"EndpointAutoConfirms": false,
"FilterPolicy": "",
"Id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"Protocol": "sqs",
"RawMessageDelivery": false,
"TopicArn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic"
},
{
"Arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"ConfirmationTimeoutInMinutes": 1,
"DeliveryPolicy": "",
"Endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"EndpointAutoConfirms": false,
"FilterPolicy": "",
"Id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"Protocol": "sqs",
"RawMessageDelivery": false,
"TopicArn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
{
"version": 4,
"terraform_version": "0.14.5",
"serial": 32,
"lineage": "30081725-54a2-ce02-6ff5-45c4d961c652",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_sns_topic_subscription",
"name": "user_updates_sqs_target",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"confirmation_timeout_in_minutes": 1,
"delivery_policy": "",
"endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"endpoint_auto_confirms": false,
"filter_policy": "",
"id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"protocol": "sqs",
"raw_message_delivery": false,
"topic_arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_sns_topic.user_updates",
"aws_sqs_queue.user_updates_queue"
]
}
]
},
{
"mode": "managed",
"type": "aws_sns_topic_subscription",
"name": "user_updates_sqs_target2",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"confirmation_timeout_in_minutes": 1,
"delivery_policy": "",
"endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"endpoint_auto_confirms": false,
"filter_policy": "",
"id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"protocol": "sqs",
"raw_message_delivery": false,
"topic_arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_sns_topic.user_updates2",
"aws_sqs_queue.user_updates_queue"
]
}
]
}
]
}

View File

@ -61,6 +61,7 @@ func Init(alerter *alerter.Alerter, providerLibrary *terraform.ProviderLibrary,
supplierLibrary.AddSupplier(NewSqsQueuePolicySupplier(provider))
supplierLibrary.AddSupplier(NewSNSTopicSupplier(provider))
supplierLibrary.AddSupplier(NewSNSTopicPolicySupplier(provider))
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider))
return nil
}

View File

@ -8,6 +8,7 @@ import (
type SNSRepository interface {
ListAllTopics() ([]*sns.Topic, error)
ListAllSubscriptions() ([]*sns.Subscription, error)
}
type snsRepository struct {
@ -32,3 +33,16 @@ func (r *snsRepository) ListAllTopics() ([]*sns.Topic, error) {
}
return topics, nil
}
func (r *snsRepository) ListAllSubscriptions() ([]*sns.Subscription, error) {
var subscriptions []*sns.Subscription
input := &sns.ListSubscriptionsInput{}
err := r.client.ListSubscriptionsPages(input, func(res *sns.ListSubscriptionsOutput, lastPage bool) bool {
subscriptions = append(subscriptions, res.Subscriptions...)
return !lastPage
})
if err != nil {
return nil, err
}
return subscriptions, nil
}

View File

@ -76,3 +76,64 @@ func Test_snsRepository_ListAllTopics(t *testing.T) {
})
}
}
func Test_snsRepository_ListAllSubscriptions(t *testing.T) {
tests := []struct {
name string
mocks func(client *mocks.SNSClient)
want []*sns.Subscription
wantErr error
}{
{
name: "List with 2 pages",
mocks: func(client *mocks.SNSClient) {
client.On("ListSubscriptionsPages",
&sns.ListSubscriptionsInput{},
mock.MatchedBy(func(callback func(res *sns.ListSubscriptionsOutput, lastPage bool) bool) bool {
callback(&sns.ListSubscriptionsOutput{
Subscriptions: []*sns.Subscription{
{TopicArn: aws.String("arn1"), SubscriptionArn: aws.String("SubArn1")},
{TopicArn: aws.String("arn2"), SubscriptionArn: aws.String("SubArn2")},
{TopicArn: aws.String("arn3"), SubscriptionArn: aws.String("SubArn3")},
},
}, false)
callback(&sns.ListSubscriptionsOutput{
Subscriptions: []*sns.Subscription{
{TopicArn: aws.String("arn4"), SubscriptionArn: aws.String("SubArn4")},
{TopicArn: aws.String("arn5"), SubscriptionArn: aws.String("SubArn5")},
{TopicArn: aws.String("arn6"), SubscriptionArn: aws.String("SubArn6")},
},
}, true)
return true
})).Return(nil)
},
want: []*sns.Subscription{
{TopicArn: aws.String("arn1"), SubscriptionArn: aws.String("SubArn1")},
{TopicArn: aws.String("arn2"), SubscriptionArn: aws.String("SubArn2")},
{TopicArn: aws.String("arn3"), SubscriptionArn: aws.String("SubArn3")},
{TopicArn: aws.String("arn4"), SubscriptionArn: aws.String("SubArn4")},
{TopicArn: aws.String("arn5"), SubscriptionArn: aws.String("SubArn5")},
{TopicArn: aws.String("arn6"), SubscriptionArn: aws.String("SubArn6")},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &mocks.SNSClient{}
tt.mocks(client)
r := &snsRepository{
client: client,
}
got, err := r.ListAllSubscriptions()
assert.Equal(t, tt.wantErr, err)
changelog, err := diff.Diff(got, tt.want)
assert.Nil(t, err)
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
}
t.Fail()
}
})
}
}

View File

@ -0,0 +1,66 @@
package aws
import (
"github.com/aws/aws-sdk-go/service/sns"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/aws"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/pkg/terraform"
)
type SNSTopicSubscriptionSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client repository.SNSRepository
runner *terraform.ParallelResourceReader
}
func NewSNSTopicSubscriptionSupplier(provider *TerraformProvider) *SNSTopicSubscriptionSupplier {
return &SNSTopicSubscriptionSupplier{
provider,
awsdeserializer.NewSNSTopicSubscriptionDeserializer(),
repository.NewSNSClient(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s SNSTopicSubscriptionSupplier) Resources() ([]resource.Resource, error) {
subscriptions, err := s.client.ListAllSubscriptions()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, aws.AwsSnsTopicSubscriptionResourceType)
}
for _, subscription := range subscriptions {
subscription := subscription
s.runner.Run(func() (cty.Value, error) {
return s.readTopicSubscription(subscription)
})
}
retrieve, err := s.runner.Wait()
if err != nil {
return nil, err
}
return s.deserializer.Deserialize(retrieve)
}
func (s SNSTopicSubscriptionSupplier) readTopicSubscription(subscription *sns.Subscription) (cty.Value, error) {
val, err := s.reader.ReadResource(terraform.ReadResourceArgs{
ID: *subscription.SubscriptionArn,
Ty: aws.AwsSnsTopicSubscriptionResourceType,
Attributes: map[string]string{
"SubscriptionId": *subscription.SubscriptionArn,
},
})
if err != nil {
logrus.Error(err)
return cty.NilVal, err
}
return *val, nil
}

View File

@ -0,0 +1,102 @@
package aws
import (
"context"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/sns"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/cloudskiff/driftctl/pkg/parallel"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/test/goldenfile"
mocks2 "github.com/cloudskiff/driftctl/test/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/cloudskiff/driftctl/mocks"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/cloudskiff/driftctl/test"
)
func TestSNSTopicSubscriptionSupplier_Resources(t *testing.T) {
cases := []struct {
test string
dirName string
mocks func(client *mocks.SNSRepository)
err error
}{
{
test: "no SNS Topic Subscription",
dirName: "sns_topic_subscription_empty",
mocks: func(client *mocks.SNSRepository) {
client.On("ListAllSubscriptions").Return([]*sns.Subscription{}, nil)
},
err: nil,
},
{
test: "Multiple SNSTopic Subscription",
dirName: "sns_topic_subscription_multiple",
mocks: func(client *mocks.SNSRepository) {
client.On("ListAllSubscriptions").Return([]*sns.Subscription{
{SubscriptionArn: aws.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa")},
{SubscriptionArn: aws.String("arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e")},
}, nil)
},
err: nil,
},
{
test: "cannot list SNSTopic subscription",
dirName: "sns_topic_subscription_list",
mocks: func(client *mocks.SNSRepository) {
client.On("ListAllSubscriptions").Return(nil, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsSnsTopicSubscriptionResourceType),
},
}
for _, c := range cases {
shouldUpdate := c.dirName == *goldenfile.Update
providerLibrary := terraform.NewProviderLibrary()
supplierLibrary := resource.NewSupplierLibrary()
if shouldUpdate {
provider, err := NewTerraFormProvider()
if err != nil {
t.Fatal(err)
}
providerLibrary.AddProvider(terraform.AWS, provider)
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider))
}
t.Run(c.test, func(tt *testing.T) {
fakeClient := mocks.SNSRepository{}
c.mocks(&fakeClient)
provider := mocks2.NewMockedGoldenTFProvider(c.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
topicSubscriptionDeserializer := awsdeserializer.NewSNSTopicSubscriptionDeserializer()
s := &SNSTopicSubscriptionSupplier{
provider,
topicSubscriptionDeserializer,
&fakeClient,
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
}
got, err := s.Resources()
assert.Equal(tt, c.err, err)
mock.AssertExpectationsForObjects(tt)
test.CtyTestDiff(got, c.dirName, provider, topicSubscriptionDeserializer, shouldUpdate, tt)
})
}
}

View File

@ -0,0 +1 @@
[]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
[]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
{
"Typ": "WyJvYmplY3QiLHsiYXJuIjoic3RyaW5nIiwiY29uZmlybWF0aW9uX3RpbWVvdXRfaW5fbWludXRlcyI6Im51bWJlciIsImRlbGl2ZXJ5X3BvbGljeSI6InN0cmluZyIsImVuZHBvaW50Ijoic3RyaW5nIiwiZW5kcG9pbnRfYXV0b19jb25maXJtcyI6ImJvb2wiLCJmaWx0ZXJfcG9saWN5Ijoic3RyaW5nIiwiaWQiOiJzdHJpbmciLCJwcm90b2NvbCI6InN0cmluZyIsInJhd19tZXNzYWdlX2RlbGl2ZXJ5IjoiYm9vbCIsInRvcGljX2FybiI6InN0cmluZyJ9XQ==",
"Val": "eyJhcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOnVzZXItdXBkYXRlcy10b3BpYzI6YzBmNzk0YzUtYTAwOS00ZGI0LTkxNDctNGM1NTk1OTc4N2ZhIiwiY29uZmlybWF0aW9uX3RpbWVvdXRfaW5fbWludXRlcyI6bnVsbCwiZGVsaXZlcnlfcG9saWN5IjoiIiwiZW5kcG9pbnQiOiJhcm46YXdzOnNxczp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOnVzZXItdXBkYXRlcy1xdWV1ZSIsImVuZHBvaW50X2F1dG9fY29uZmlybXMiOm51bGwsImZpbHRlcl9wb2xpY3kiOiIiLCJpZCI6ImFybjphd3M6c25zOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dXNlci11cGRhdGVzLXRvcGljMjpjMGY3OTRjNS1hMDA5LTRkYjQtOTE0Ny00YzU1OTU5Nzg3ZmEiLCJwcm90b2NvbCI6InNxcyIsInJhd19tZXNzYWdlX2RlbGl2ZXJ5IjpmYWxzZSwidG9waWNfYXJuIjoiYXJuOmF3czpzbnM6dXMtZWFzdC0xOjUyNjk1NDkyOTkyMzp1c2VyLXVwZGF0ZXMtdG9waWMyIn0=",
"Err": null
}

View File

@ -0,0 +1,5 @@
{
"Typ": "WyJvYmplY3QiLHsiYXJuIjoic3RyaW5nIiwiY29uZmlybWF0aW9uX3RpbWVvdXRfaW5fbWludXRlcyI6Im51bWJlciIsImRlbGl2ZXJ5X3BvbGljeSI6InN0cmluZyIsImVuZHBvaW50Ijoic3RyaW5nIiwiZW5kcG9pbnRfYXV0b19jb25maXJtcyI6ImJvb2wiLCJmaWx0ZXJfcG9saWN5Ijoic3RyaW5nIiwiaWQiOiJzdHJpbmciLCJwcm90b2NvbCI6InN0cmluZyIsInJhd19tZXNzYWdlX2RlbGl2ZXJ5IjoiYm9vbCIsInRvcGljX2FybiI6InN0cmluZyJ9XQ==",
"Val": "eyJhcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOnVzZXItdXBkYXRlcy10b3BpYzpiNmU2NjE0Ny0yYjMxLTQ0ODYtOGQ0Yi0yYTIyNzIyNjRjOGUiLCJjb25maXJtYXRpb25fdGltZW91dF9pbl9taW51dGVzIjpudWxsLCJkZWxpdmVyeV9wb2xpY3kiOiIiLCJlbmRwb2ludCI6ImFybjphd3M6c3FzOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dXNlci11cGRhdGVzLXF1ZXVlIiwiZW5kcG9pbnRfYXV0b19jb25maXJtcyI6bnVsbCwiZmlsdGVyX3BvbGljeSI6IiIsImlkIjoiYXJuOmF3czpzbnM6dXMtZWFzdC0xOjUyNjk1NDkyOTkyMzp1c2VyLXVwZGF0ZXMtdG9waWM6YjZlNjYxNDctMmIzMS00NDg2LThkNGItMmEyMjcyMjY0YzhlIiwicHJvdG9jb2wiOiJzcXMiLCJyYXdfbWVzc2FnZV9kZWxpdmVyeSI6ZmFsc2UsInRvcGljX2FybiI6ImFybjphd3M6c25zOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dXNlci11cGRhdGVzLXRvcGljIn0=",
"Err": null
}

View File

@ -0,0 +1,27 @@
provider "aws" {
region = "us-east-1"
}
resource "aws_sns_topic" "user_updates" {
name = "user-updates-topic"
}
resource "aws_sns_topic" "user_updates2" {
name = "user-updates-topic2"
}
resource "aws_sqs_queue" "user_updates_queue" {
name = "user-updates-queue"
}
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
filter_policy = ""
topic_arn = aws_sns_topic.user_updates.arn
protocol = "sqs"
endpoint = aws_sqs_queue.user_updates_queue.arn
}
resource "aws_sns_topic_subscription" "user_updates_sqs_target2" {
topic_arn = aws_sns_topic.user_updates2.arn
protocol = "sqs"
endpoint = aws_sqs_queue.user_updates_queue.arn
}

View File

@ -0,0 +1,26 @@
[
{
"arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"confirmation_timeout_in_minutes": null,
"delivery_policy": "",
"endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"endpoint_auto_confirms": null,
"filter_policy": "",
"id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2:c0f794c5-a009-4db4-9147-4c55959787fa",
"protocol": "sqs",
"raw_message_delivery": false,
"topic_arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic2"
},
{
"arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"confirmation_timeout_in_minutes": null,
"delivery_policy": "",
"endpoint": "arn:aws:sqs:us-east-1:526954929923:user-updates-queue",
"endpoint_auto_confirms": null,
"filter_policy": "",
"id": "arn:aws:sns:us-east-1:526954929923:user-updates-topic:b6e66147-2b31-4486-8d4b-2a2272264c8e",
"protocol": "sqs",
"raw_message_delivery": false,
"topic_arn": "arn:aws:sns:us-east-1:526954929923:user-updates-topic"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
// GENERATED, DO NOT EDIT THIS FILE
package aws
const AwsSnsTopicSubscriptionResourceType = "aws_sns_topic_subscription"
type AwsSnsTopicSubscription struct {
Arn *string `cty:"arn" computed:"true"`
ConfirmationTimeoutInMinutes *int `cty:"confirmation_timeout_in_minutes"`
DeliveryPolicy *string `cty:"delivery_policy"`
Endpoint *string `cty:"endpoint"`
EndpointAutoConfirms *bool `cty:"endpoint_auto_confirms"`
FilterPolicy *string `cty:"filter_policy"`
Id string `cty:"id" computed:"true"`
Protocol *string `cty:"protocol"`
RawMessageDelivery *bool `cty:"raw_message_delivery"`
TopicArn *string `cty:"topic_arn"`
}
func (r *AwsSnsTopicSubscription) TerraformId() string {
return r.Id
}
func (r *AwsSnsTopicSubscription) TerraformType() string {
return AwsSnsTopicSubscriptionResourceType
}

View File

@ -0,0 +1,44 @@
package aws
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/cloudskiff/driftctl/pkg/helpers"
"github.com/cloudskiff/driftctl/pkg/resource"
)
func (r *AwsSnsTopicSubscription) NormalizeForState() (resource.Resource, error) {
err := r.normalizePolicies()
return r, err
}
func (r *AwsSnsTopicSubscription) NormalizeForProvider() (resource.Resource, error) {
err := r.normalizePolicies()
if r.ConfirmationTimeoutInMinutes == nil {
r.ConfirmationTimeoutInMinutes = aws.Int(1)
}
if r.EndpointAutoConfirms == nil {
r.EndpointAutoConfirms = aws.Bool(false)
}
return r, err
}
func (r *AwsSnsTopicSubscription) normalizePolicies() error {
if r.FilterPolicy != nil {
jsonString, err := helpers.NormalizeJsonString(*r.FilterPolicy)
if err != nil {
return err
}
r.FilterPolicy = &jsonString
}
if r.DeliveryPolicy != nil {
jsonString, err := helpers.NormalizeJsonString(*r.DeliveryPolicy)
if err != nil {
return err
}
r.DeliveryPolicy = &jsonString
}
return nil
}

View File

@ -0,0 +1,29 @@
package aws_test
import (
"testing"
"github.com/cloudskiff/driftctl/test/acceptance"
)
func TestAcc_AwsSNSTopicSubscription(t *testing.T) {
acceptance.Run(t, acceptance.AccTestCase{
Path: "./testdata/acc/aws_sns_topic_subscription",
Args: []string{"scan", "--filter", "Type=='aws_sns_topic_subscription'"},
Checks: []acceptance.AccCheck{
{
Env: map[string]string{
"AWS_REGION": "us-east-1",
},
Check: func(result *acceptance.ScanResult, stdout string, err error) {
if err != nil {
t.Fatal(err)
}
result.AssertDriftCountTotal(0)
result.AssertDeletedCount(0)
result.AssertManagedCount(2)
},
},
},
})
}

View File

@ -0,0 +1,40 @@
package deserializer
import (
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
)
type SNSTopicSubscriptionDeserializer struct {
}
func NewSNSTopicSubscriptionDeserializer() *SNSTopicSubscriptionDeserializer {
return &SNSTopicSubscriptionDeserializer{}
}
func (s *SNSTopicSubscriptionDeserializer) HandledType() resource.ResourceType {
return aws.AwsSnsTopicSubscriptionResourceType
}
func (s SNSTopicSubscriptionDeserializer) Deserialize(subscriptionsList []cty.Value) ([]resource.Resource, error) {
subscriptions := make([]resource.Resource, 0)
for _, value := range subscriptionsList {
value := value
subscription, err := decodeSNSTopicSubscription(value)
if err != nil {
return nil, err
}
subscriptions = append(subscriptions, subscription)
}
return subscriptions, nil
}
func decodeSNSTopicSubscription(value cty.Value) (resource.Resource, error) {
var subscription aws.AwsSnsTopicSubscription
err := gocty.FromCtyValue(value, &subscription)
return &subscription, err
}

View File

@ -0,0 +1,27 @@
provider "aws" {
region = "us-east-1"
}
resource "aws_sns_topic" "user_updates" {
name = "user-updates-topic"
}
resource "aws_sns_topic" "user_updates2" {
name = "user-updates-topic2"
}
resource "aws_sqs_queue" "user_updates_queue" {
name = "user-updates-queue"
}
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
filter_policy = ""
topic_arn = aws_sns_topic.user_updates.arn
protocol = "sqs"
endpoint = aws_sqs_queue.user_updates_queue.arn
}
resource "aws_sns_topic_subscription" "user_updates_sqs_target2" {
topic_arn = aws_sns_topic.user_updates2.arn
protocol = "sqs"
endpoint = aws_sqs_queue.user_updates_queue.arn
}