func()

in pkg/selector/selector.go [294:409]


func (itf Selector) executeFilters(filterToInstanceSpecMapping map[string]filterPair, instanceType string) (bool, error) {
	for filterName, filterPair := range filterToInstanceSpecMapping {
		filterVal := filterPair.filterValue
		instanceSpec := filterPair.instanceSpec
		// if filter is nil, user did not specify a filter, so skip evaluation
		if reflect.ValueOf(filterVal).IsNil() {
			continue
		}
		instanceSpecType := reflect.ValueOf(instanceSpec).Type()
		filterType := reflect.ValueOf(filterVal).Type()
		filterDetailsMsg := fmt.Sprintf("filter (%s: %s => %s) corresponding to instance spec (%s => %s) for instance type %s", filterName, filterVal, filterType, instanceSpec, instanceSpecType, instanceType)
		invalidInstanceSpecTypeMsg := fmt.Sprintf("Unable to process for %s", filterDetailsMsg)

		// Determine appropriate filter comparator by switching on filter type
		switch filter := filterVal.(type) {
		case *string:
			switch iSpec := instanceSpec.(type) {
			case []*string:
				if !isSupportedFromStrings(iSpec, filter) {
					return false, nil
				}
			case *string:
				if !isSupportedFromString(iSpec, filter) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *bool:
			switch iSpec := instanceSpec.(type) {
			case *bool:
				if !isSupportedWithBool(iSpec, filter) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *IntRangeFilter:
			switch iSpec := instanceSpec.(type) {
			case *int64:
				if !isSupportedWithRangeInt64(iSpec, filter) {
					return false, nil
				}
			case *int:
				if !isSupportedWithRangeInt(iSpec, filter) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *Float64RangeFilter:
			switch iSpec := instanceSpec.(type) {
			case *float64:
				if !isSupportedWithRangeFloat64(iSpec, filter) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *ByteQuantityRangeFilter:
			mibRange := Uint64RangeFilter{
				LowerBound: filter.LowerBound.Quantity,
				UpperBound: filter.UpperBound.Quantity,
			}
			switch iSpec := instanceSpec.(type) {
			case *int:
				var iSpec64 *int64
				if iSpec != nil {
					iSpecVal := int64(*iSpec)
					iSpec64 = &iSpecVal
				}
				if !isSupportedWithRangeUint64(iSpec64, &mibRange) {
					return false, nil
				}
			case *int64:
				mibRange := Uint64RangeFilter{
					LowerBound: filter.LowerBound.Quantity,
					UpperBound: filter.UpperBound.Quantity,
				}
				if !isSupportedWithRangeUint64(iSpec, &mibRange) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *float64:
			switch iSpec := instanceSpec.(type) {
			case *float64:
				if !isSupportedWithFloat64(iSpec, filter) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		case *[]string:
			switch iSpec := instanceSpec.(type) {
			case *string:
				filterOfPtrs := []*string{}
				for _, f := range *filter {
					// this allows us to copy a static pointer to f into filterOfPtrs
					// since the pointer to f is updated on each loop iteration
					temp := f
					filterOfPtrs = append(filterOfPtrs, &temp)
				}
				if !isSupportedFromStrings(filterOfPtrs, iSpec) {
					return false, nil
				}
			default:
				return false, fmt.Errorf(invalidInstanceSpecTypeMsg)
			}
		default:
			return false, fmt.Errorf("No filter handler found for %s", filterDetailsMsg)
		}
	}
	return true, nil
}