resources: aws: ec2: Add method to make sns topic

This commit is contained in:
Jonathan Gold
2017-11-09 02:28:39 -05:00
parent 91a9edb322
commit 91eff75288

View File

@@ -33,6 +33,8 @@ import (
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/sns"
multierr "github.com/hashicorp/go-multierror"
errwrap "github.com/pkg/errors" errwrap "github.com/pkg/errors"
) )
@@ -44,6 +46,12 @@ const (
// AwsPrefix is a const which gets prepended onto object names. We can only use // AwsPrefix is a const which gets prepended onto object names. We can only use
// alphanumeric chars, underscores and hyphens for sns topics and cloud watch rules. // alphanumeric chars, underscores and hyphens for sns topics and cloud watch rules.
AwsPrefix = "_mgmt-" AwsPrefix = "_mgmt-"
// Ec2Prefix is added to the names of sns and cloudwatch objects.
Ec2Prefix = AwsPrefix + "ec2-"
// SnsPrefix gets prepended onto the sns topic.
SnsPrefix = Ec2Prefix + "sns-"
// SnsTopicName is the name of the sns topic created by snsMakeTopic.
SnsTopicName = SnsPrefix + "events"
// waitTimeout is the duration in seconds of the timeout context in CheckApply. // waitTimeout is the duration in seconds of the timeout context in CheckApply.
waitTimeout = 400 waitTimeout = 400
) )
@@ -88,6 +96,11 @@ type AwsEc2Res struct {
client *ec2.EC2 // client session for AWS API calls client *ec2.EC2 // client session for AWS API calls
snsClient *sns.SNS // client for AWS SNS API calls
// snsTopicArn requires looping through every topic to get,
// so we save it here when we create the topic instead.
snsTopicArn string
awsChan chan *chanStruct // channel used to send events and errors to Watch() awsChan chan *chanStruct // channel used to send events and errors to Watch()
closeChan chan struct{} // channel used to cancel context when it's time to shut down closeChan chan struct{} // channel used to cancel context when it's time to shut down
wg *sync.WaitGroup // waitgroup for goroutines in Watch() wg *sync.WaitGroup // waitgroup for goroutines in Watch()
@@ -175,6 +188,25 @@ func (obj *AwsEc2Res) Init() error {
obj.closeChan = make(chan struct{}) obj.closeChan = make(chan struct{})
obj.wg = &sync.WaitGroup{} obj.wg = &sync.WaitGroup{}
// if we are using sns watch
if obj.WatchListenAddr != "" {
// make sns client
snsSess, err := session.NewSession(&aws.Config{
Region: aws.String(obj.Region),
})
if err != nil {
return errwrap.Wrapf(err, "error creating sns session")
}
obj.snsClient = sns.New(snsSess)
// make the sns topic
snsTopicArn, err := obj.snsMakeTopic()
if err != nil {
return errwrap.Wrapf(err, "error making sns topic")
}
// save the topicArn for later use
obj.snsTopicArn = snsTopicArn
}
return obj.BaseRes.Init() // call base init, b/c we're overriding return obj.BaseRes.Init() // call base init, b/c we're overriding
} }
@@ -656,6 +688,9 @@ func (obj *AwsEc2Res) Compare(r Res) bool {
if obj.UserData != res.UserData { if obj.UserData != res.UserData {
return false return false
} }
if obj.WatchListenAddr != res.WatchListenAddr {
return false
}
return true return true
} }
@@ -708,3 +743,50 @@ func (obj *AwsEc2Res) snsPostHandler(w http.ResponseWriter, req *http.Request) {
log.Printf("%s: Post: %s", obj, string(post)) log.Printf("%s: Post: %s", obj, string(post))
} }
} }
// snsMakeTopic creates a topic on aws sns.
func (obj *AwsEc2Res) snsMakeTopic() (string, error) {
// make topic
topicInput := &sns.CreateTopicInput{
Name: aws.String(SnsTopicName),
}
topic, err := obj.snsClient.CreateTopic(topicInput)
if err != nil {
return "", err
}
log.Printf("%s: Created SNS Topic", obj)
if topic.TopicArn == nil {
return "", fmt.Errorf("TopicArn is nil")
}
return *topic.TopicArn, nil
}
// snsDeleteTopic deletes the sns topic.
func (obj *AwsEc2Res) snsDeleteTopic(topicArn string) error {
// delete the topic
dtInput := &sns.DeleteTopicInput{
TopicArn: aws.String(topicArn),
}
if _, err := obj.snsClient.DeleteTopic(dtInput); err != nil {
return err
}
log.Printf("%s: Deleted SNS Topic", obj)
return nil
}
// Close cleans up when we're done. This is needed to delete some of the AWS
// objects created for the SNS endpoint.
func (obj *AwsEc2Res) Close() error {
var errList error
// clean up sns objects created by Init/snsWatch
if obj.snsClient != nil {
// delete the topic
if err := obj.snsDeleteTopic(obj.snsTopicArn); err != nil {
errList = multierr.Append(errList, err)
}
}
if err := obj.BaseRes.Close(); err != nil {
errList = multierr.Append(errList, err) // list of errors
}
return errList
}