func()

in pkg/scheduler/framework/plugins/clusteraffinity/types.go [122:208]


func (c *clusterRequirement) Matches(cluster *clusterv1beta1.MemberCluster) (bool, error) {
	// Match the cluster against the label selector.
	if c.LabelSelector != nil {
		ls, err := metav1.LabelSelectorAsSelector(c.LabelSelector)
		if err != nil {
			return false, fmt.Errorf("failed to parse label selector: %w", err)
		}
		if !ls.Matches(labels.Set(cluster.Labels)) {
			// The cluster does not match with the label selector; it is ineligible for resource
			// placement.
			return false, nil
		}
	}

	// Match the cluster against the property selector.
	if c.PropertySelector == nil || len(c.PropertySelector.MatchExpressions) == 0 {
		// The term does not feature a property selector; no check is needed.
		return true, nil
	}

	for _, exp := range c.PropertySelector.MatchExpressions {
		// Compare the observed value with the expected one using the specified operator.
		q, err := retrievePropertyValueFrom(cluster, exp.Name)
		if err != nil {
			return false, err
		}
		if q == nil {
			// The property is not available for the cluster.
			return false, nil
		}

		// With the current set of operators, only one expected value can be specified.
		if len(exp.Values) != 1 {
			// The property selector expression is invalid, as there are too many expected
			// values.
			//
			// Normally this should never happen.
			return false, fmt.Errorf("more than one value in the property selector expression")
		}
		expectedQ, err := resource.ParseQuantity(exp.Values[0])
		if err != nil {
			return false, fmt.Errorf("value specified in property selector %s is not a valid resource quantity: %w", exp.Values[0], err)
		}

		switch exp.Operator {
		case placementv1beta1.PropertySelectorEqualTo:
			if !q.Equal(expectedQ) {
				// The observed value is not equal to the expected one (equality is expected)
				return false, nil
			}
		case placementv1beta1.PropertySelectorNotEqualTo:
			if q.Equal(expectedQ) {
				// The observed value is equal to the expected one (inequality is expected).
				return false, nil
			}
		case placementv1beta1.PropertySelectorGreaterThan:
			if q.Cmp(expectedQ) <= 0 {
				// The observed value is less than or equal to the expected one (expected to be
				// greater than the value).
				return false, nil
			}
		case placementv1beta1.PropertySelectorGreaterThanOrEqualTo:
			if q.Cmp(expectedQ) < 0 {
				// The observed value is less than the expected one (expected to be greater
				// than or equal to the value).
				return false, nil
			}
		case placementv1beta1.PropertySelectorLessThan:
			if q.Cmp(expectedQ) >= 0 {
				// The observed value is greater than or equal to the expected one (expected to be
				// less than the value).
				return false, nil
			}
		case placementv1beta1.PropertySelectorLessThanOrEqualTo:
			if q.Cmp(expectedQ) > 0 {
				// The observed value is greater than the expected one (expected to be less than
				// or equal to the value).
				return false, nil
			}
		default:
			// The operator is not recognized; normally this should never happen.
			return false, fmt.Errorf("invalid operator: %s", exp.Operator)
		}
	}
	// The cluster matches the property selector.
	return true, nil
}