Example #1
0
// matchesFilters applies the relevant filter groups to a filterable
func matchesFilters(filterable filters.Filterable) bool {
	// recover from potential panics caused by malformed filters
	defer func() {
		if r := recover(); r != nil {
			log.Error("Recovered in matchesFilters with panic: ", r)
		}
	}()

	var groups map[string]filters.FilterGroup
	switch filterable.(type) {
	case *reaperaws.Instance:
		groups = config.Instances.FilterGroups
	case *reaperaws.AutoScalingGroup:
		groups = config.AutoScalingGroups.FilterGroups
	case *reaperaws.Cloudformation:
		groups = config.Cloudformations.FilterGroups
	case *reaperaws.SecurityGroup:
		groups = config.SecurityGroups.FilterGroups
	case *reaperaws.Volume:
		groups = config.Volumes.FilterGroups
	default:
		log.Warning("You probably screwed up and need to make sure matchesFilters works!")
		return false
	}

	matched := false

	// if there are no filters groups defined default to not match
	if len(groups) == 0 {
		return false
	}

	shouldFilter := false
	for _, group := range groups {
		if len(group) > 0 {
			// there is a filter
			shouldFilter = true
		}
	}
	// no filters, default to not match
	if !shouldFilter {
		return false
	}

	for name, group := range groups {
		didMatch := filters.ApplyFilters(filterable, group)
		if didMatch {
			matched = true
			filterable.AddFilterGroup(name, group)
		}
	}

	// convenient
	if isWhitelisted(filterable) {
		matched = false
	}

	return matched
}
Example #2
0
// newReapableEvent is a method of EventReporter
func (e *Tagger) newReapableEvent(r Reapable, tags []string) error {
	if r.ReaperState().Until.IsZero() {
		log.Warning("Uninitialized time value for %s!", r.ReapableDescription())
	}

	if e.Config.shouldTriggerFor(r) {
		log.Info("Tagging %s with %s", r.ReapableDescriptionTiny(), r.ReaperState().State.String())
		_, err := r.Save(r.ReaperState())
		if err != nil {
			return err
		}
	}
	return nil
}
Example #3
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
}
Example #4
0
func (e *EventReporterConfig) parseTriggers() (triggers []state.StateEnum) {
	for _, t := range e.Triggers {
		switch t {
		case "first":
			triggers = append(triggers, state.FirstState)
		case "second":
			triggers = append(triggers, state.SecondState)
		case "third":
			triggers = append(triggers, state.ThirdState)
		case "final":
			triggers = append(triggers, state.FinalState)
		case "ignore":
			triggers = append(triggers, state.IgnoreState)
		default:
			log.Warning("%s is not an available EventReporter trigger", t)
		}
	}
	return
}
Example #5
0
// Owner extracts useful information out of the Owner tag which should
// be parsable by mail.ParseAddress
func (a *Resource) Owner() *mail.Address {
	// properly formatted email
	if addr, err := mail.ParseAddress(a.Tag("Owner")); err == nil {
		return addr
	}

	// username -> default email host email address
	if addr, err := mail.ParseAddress(fmt.Sprintf("%s@%s", a.Tag("Owner"), config.DefaultEmailHost)); a.Tagged("Owner") && config.DefaultEmailHost != "" && err == nil {
		return addr
	}

	// default owner is specified
	if addr, err := mail.ParseAddress(
		fmt.Sprintf("%s@%s", config.DefaultOwner, config.DefaultEmailHost)); config.DefaultOwner != "" && config.DefaultEmailHost != "" && err == nil {
		return addr
	}
	log.Warning("No default owner or email host.")
	return nil
}