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
}