resources: aws: ec2: Add method to make sns topic
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user