func exec()

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
}