in pkg/selector/selector.go [444:633]
func exec(instanceType ec2types.InstanceType, filterName string, filter filterPair) (bool, error) {
filterVal := filter.filterValue
instanceSpec := filter.instanceSpec
filterValReflection := reflect.ValueOf(filterVal)
// if filter is nil, user did not specify a filter, so skip evaluation
if filterValReflection.IsNil() {
return true, nil
}
instanceSpecType := reflect.ValueOf(instanceSpec).Type()
filterType := filterValReflection.Type()
filterDetailsMsg := fmt.Sprintf("filter (%s: %s => %s) corresponding to instance spec (%s => %s) for instance type %s", filterName, filterVal, filterType, instanceSpec, instanceSpecType, instanceType)
errInvalidInstanceSpec := fmt.Errorf("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, errInvalidInstanceSpec
}
case *bool:
switch iSpec := instanceSpec.(type) {
case *bool:
if !isSupportedWithBool(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *IntRangeFilter:
switch iSpec := instanceSpec.(type) {
case *int64:
if !isSupportedWithRangeInt64(iSpec, filter) {
return false, nil
}
case *int32:
var iSpec64 *int64
if iSpec != nil {
iSpec64 = aws.Int64(int64(*iSpec))
}
if !isSupportedWithRangeInt64(iSpec64, filter) {
return false, nil
}
case *int:
if !isSupportedWithRangeInt(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *Int32RangeFilter:
switch iSpec := instanceSpec.(type) {
case *int32:
if !isSupportedWithRangeInt32(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *Float64RangeFilter:
switch iSpec := instanceSpec.(type) {
case *float64:
if !isSupportedWithRangeFloat64(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
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:
if !isSupportedWithRangeUint64(iSpec, &mibRange) {
return false, nil
}
case *float64:
floatMiBRange := Float64RangeFilter{
LowerBound: float64(filter.LowerBound.Quantity),
UpperBound: float64(filter.UpperBound.Quantity),
}
if !isSupportedWithRangeFloat64(iSpec, &floatMiBRange) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *float64:
switch iSpec := instanceSpec.(type) {
case *float64:
if !isSupportedWithFloat64(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *ec2types.ArchitectureType:
switch iSpec := instanceSpec.(type) {
case []ec2types.ArchitectureType:
if !isSupportedArchitectureType(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *ec2types.UsageClassType:
switch iSpec := instanceSpec.(type) {
case []ec2types.UsageClassType:
if !isSupportedUsageClassType(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *CPUManufacturer:
switch iSpec := instanceSpec.(type) {
case CPUManufacturer:
if !isMatchingCpuArchitecture(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *ec2types.VirtualizationType:
switch iSpec := instanceSpec.(type) {
case []ec2types.VirtualizationType:
if !isSupportedVirtualizationType(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *ec2types.InstanceTypeHypervisor:
switch iSpec := instanceSpec.(type) {
case ec2types.InstanceTypeHypervisor:
if !isSupportedInstanceTypeHypervisorType(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
case *ec2types.RootDeviceType:
switch iSpec := instanceSpec.(type) {
case []ec2types.RootDeviceType:
if !isSupportedRootDeviceType(iSpec, filter) {
return false, nil
}
default:
return false, errInvalidInstanceSpec
}
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, errInvalidInstanceSpec
}
default:
return false, fmt.Errorf("no filter handler found for %s", filterDetailsMsg)
}
return true, nil
}