Merge pull request #345 from cloudskiff/fix/sns_sub_pending
when sns subscription is pending prevent crash and show an alertmain
commit
c24ce3cfe8
|
@ -68,7 +68,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))
|
||||
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider, alerter))
|
||||
supplierLibrary.AddSupplier(NewDynamoDBTableSupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewRoute53HealthCheckSupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewCloudfrontDistributionSupplier(provider))
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
awssdk "github.com/aws/aws-sdk-go/aws"
|
||||
"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/alerter"
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
|
@ -14,19 +19,35 @@ import (
|
|||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||
)
|
||||
|
||||
type pendingTopicAlert struct {
|
||||
endpoint *string
|
||||
}
|
||||
|
||||
func (p *pendingTopicAlert) Message() string {
|
||||
return fmt.Sprintf("%s with pending confirmation status for endpoint \"%s\" will be ignored",
|
||||
aws.AwsSnsTopicSubscriptionResourceType,
|
||||
awssdk.StringValue(p.endpoint))
|
||||
}
|
||||
|
||||
func (p *pendingTopicAlert) ShouldIgnoreResource() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type SNSTopicSubscriptionSupplier struct {
|
||||
reader terraform.ResourceReader
|
||||
deserializer deserializer.CTYDeserializer
|
||||
client repository.SNSRepository
|
||||
runner *terraform.ParallelResourceReader
|
||||
alerter alerter.AlerterInterface
|
||||
}
|
||||
|
||||
func NewSNSTopicSubscriptionSupplier(provider *AWSTerraformProvider) *SNSTopicSubscriptionSupplier {
|
||||
func NewSNSTopicSubscriptionSupplier(provider *AWSTerraformProvider, a alerter.AlerterInterface) *SNSTopicSubscriptionSupplier {
|
||||
return &SNSTopicSubscriptionSupplier{
|
||||
provider,
|
||||
awsdeserializer.NewSNSTopicSubscriptionDeserializer(),
|
||||
repository.NewSNSClient(provider.session),
|
||||
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
||||
a,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +59,7 @@ func (s *SNSTopicSubscriptionSupplier) Resources() ([]resource.Resource, error)
|
|||
for _, subscription := range subscriptions {
|
||||
subscription := subscription
|
||||
s.runner.Run(func() (cty.Value, error) {
|
||||
return s.readTopicSubscription(subscription)
|
||||
return s.readTopicSubscription(subscription, s.alerter)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -50,7 +71,15 @@ func (s *SNSTopicSubscriptionSupplier) Resources() ([]resource.Resource, error)
|
|||
return s.deserializer.Deserialize(retrieve)
|
||||
}
|
||||
|
||||
func (s *SNSTopicSubscriptionSupplier) readTopicSubscription(subscription *sns.Subscription) (cty.Value, error) {
|
||||
func (s *SNSTopicSubscriptionSupplier) readTopicSubscription(subscription *sns.Subscription, alertr alerter.AlerterInterface) (cty.Value, error) {
|
||||
if subscription.SubscriptionArn != nil && *subscription.SubscriptionArn == "PendingConfirmation" {
|
||||
alertr.SendAlert(
|
||||
fmt.Sprintf("%s.%s", aws.AwsSnsTopicSubscriptionResourceType, *subscription.SubscriptionArn),
|
||||
&pendingTopicAlert{subscription.Endpoint},
|
||||
)
|
||||
return cty.NilVal, nil
|
||||
}
|
||||
|
||||
val, err := s.reader.ReadResource(terraform.ReadResourceArgs{
|
||||
ID: *subscription.SubscriptionArn,
|
||||
Ty: aws.AwsSnsTopicSubscriptionResourceType,
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/sns"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/alerter"
|
||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||
|
||||
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
|
@ -35,6 +36,7 @@ func TestSNSTopicSubscriptionSupplier_Resources(t *testing.T) {
|
|||
test string
|
||||
dirName string
|
||||
mocks func(client *mocks.SNSRepository)
|
||||
alerts alerter.Alerts
|
||||
err error
|
||||
}{
|
||||
{
|
||||
|
@ -56,6 +58,23 @@ func TestSNSTopicSubscriptionSupplier_Resources(t *testing.T) {
|
|||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
test: "Multiple SNSTopic Subscription with one pending",
|
||||
dirName: "sns_topic_subscription_multiple",
|
||||
mocks: func(client *mocks.SNSRepository) {
|
||||
client.On("ListAllSubscriptions").Return([]*sns.Subscription{
|
||||
{SubscriptionArn: aws.String("PendingConfirmation"), Endpoint: aws.String("TEST")},
|
||||
{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)
|
||||
},
|
||||
alerts: map[string][]alerter.Alert{
|
||||
"aws_sns_topic_subscription.PendingConfirmation": []alerter.Alert{
|
||||
&pendingTopicAlert{aws.String("TEST")},
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
test: "cannot list SNSTopic subscription",
|
||||
dirName: "sns_topic_subscription_list",
|
||||
|
@ -72,14 +91,16 @@ func TestSNSTopicSubscriptionSupplier_Resources(t *testing.T) {
|
|||
supplierLibrary := resource.NewSupplierLibrary()
|
||||
|
||||
if shouldUpdate {
|
||||
a := alerter.NewAlerter()
|
||||
provider, err := InitTestAwsProvider(providerLibrary)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider, a))
|
||||
}
|
||||
|
||||
t.Run(c.test, func(tt *testing.T) {
|
||||
a := alerter.NewAlerter()
|
||||
fakeClient := mocks.SNSRepository{}
|
||||
c.mocks(&fakeClient)
|
||||
provider := mocks2.NewMockedGoldenTFProvider(c.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
||||
|
@ -89,10 +110,15 @@ func TestSNSTopicSubscriptionSupplier_Resources(t *testing.T) {
|
|||
topicSubscriptionDeserializer,
|
||||
&fakeClient,
|
||||
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
|
||||
a,
|
||||
}
|
||||
got, err := s.Resources()
|
||||
assert.Equal(tt, c.err, err)
|
||||
|
||||
if c.alerts == nil {
|
||||
c.alerts = map[string][]alerter.Alert{}
|
||||
}
|
||||
assert.Equal(tt, c.alerts, a.Retrieve())
|
||||
mock.AssertExpectationsForObjects(tt)
|
||||
test.CtyTestDiff(got, c.dirName, provider, topicSubscriptionDeserializer, shouldUpdate, tt)
|
||||
})
|
||||
|
|
|
@ -23,6 +23,7 @@ func (s SNSTopicSubscriptionDeserializer) Deserialize(subscriptionsList []cty.Va
|
|||
subscriptions := make([]resource.Resource, 0)
|
||||
|
||||
for _, value := range subscriptionsList {
|
||||
|
||||
value := value
|
||||
subscription, err := decodeSNSTopicSubscription(value)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue