Beispiel #1
0
// cloudformationResources returns a chan of CloudformationResources, sourced from the AWS API
// there is rate limiting in the AWS API for CloudformationResources, so we delay
// this is skippable with the CLI flag -withoutCloudformationResources
func cloudformationResources(region, id string) chan *cloudformation.StackResource {
	ch := make(chan *cloudformation.StackResource)

	if config.WithoutCloudformationResources {
		close(ch)
		return ch
	}

	api := cloudformation.New(sess, aws.NewConfig().WithRegion(region))
	go func() {
		<-timeout

		// this query can fail, so we retry
		didRetry := false
		input := &cloudformation.DescribeStackResourcesInput{StackName: &id}

		// initial query
		resp, err := api.DescribeStackResources(input)
		for err != nil {
			sleepTime := 2*time.Second + time.Duration(rand.Intn(2000))*time.Millisecond
			if err != nil {
				// this error is annoying and will come up all the time... so you can disable it
				if strings.Split(err.Error(), ":")[0] == "Throttling" && log.Extras() {
					log.Warning("StackResources: %s (retrying %s after %ds)", err.Error(), id, sleepTime*1.0/time.Second)
				} else if strings.Split(err.Error(), ":")[0] != "Throttling" {
					// any other errors
					log.Error(fmt.Sprintf("StackResources: %s (retrying %s after %ds)", err.Error(), id, sleepTime*1.0/time.Second))
				}
			}

			// wait a random amount of time... hopefully long enough to beat rate limiting
			time.Sleep(sleepTime)

			// retry query
			resp, err = api.DescribeStackResources(input)
			didRetry = true
		}
		if didRetry && log.Extras() {
			log.Info("Retry succeeded for %s!", id)
		}
		for _, resource := range resp.StackResources {
			ch <- resource
		}
		close(ch)
	}()
	return ch
}
Beispiel #2
0
// this is a copy of the method from events.go EXCEPT
// that it triggers whether or not the state was updated this run
func (e *ReaperEventConfig) shouldTriggerFor(r Reapable) bool {
	if e.DryRun {
		if log.Extras() {
			log.Info("DryRun: Not triggering %s for %s", e.Name, r.ReapableDescriptionTiny())
		}
		return false
	}
	triggering := false
	// if the reapable's state is set to trigger this EventReporter
	for _, trigger := range e.parseTriggers() {
		// if the reapable's state should trigger this event
		if trigger == r.ReaperState().State {
			triggering = true
		}
	}
	return triggering
}
Beispiel #3
0
// newEvent is a method of EventReporter
// newEvent reports an event to Datadog
func (e *DatadogEvents) newEvent(title string, text string, fields map[string]string, tags []string) error {
	if e.Config.DryRun {
		if log.Extras() {
			log.Info("DryRun: Not reporting %s", title)
		}
		return nil
	}

	g, err := e.godspeed()
	if err != nil {
		return err
	}
	err = g.Event(title, text, fields, tags)
	if err != nil {
		return err
	}
	return nil
}