69 lines
2.8 KiB
Go
69 lines
2.8 KiB
Go
package spreadconstraint
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"k8s.io/klog/v2"
|
|
|
|
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
|
)
|
|
|
|
// SelectBestClusters selects the cluster set based the GroupClustersInfo and placement
|
|
func SelectBestClusters(placement *policyv1alpha1.Placement, groupClustersInfo *GroupClustersInfo, needReplicas int32) ([]*clusterv1alpha1.Cluster, error) {
|
|
if len(placement.SpreadConstraints) == 0 || shouldIgnoreSpreadConstraint(placement) {
|
|
var clusters []*clusterv1alpha1.Cluster
|
|
for _, cluster := range groupClustersInfo.Clusters {
|
|
clusters = append(clusters, cluster.Cluster)
|
|
}
|
|
klog.V(4).Infof("select all clusters")
|
|
return clusters, nil
|
|
}
|
|
|
|
if shouldIgnoreAvailableResource(placement) {
|
|
needReplicas = InvalidReplicas
|
|
}
|
|
|
|
return selectBestClustersBySpreadConstraints(placement.SpreadConstraints, groupClustersInfo, needReplicas)
|
|
}
|
|
|
|
func selectBestClustersBySpreadConstraints(spreadConstraints []policyv1alpha1.SpreadConstraint,
|
|
groupClustersInfo *GroupClustersInfo, needReplicas int32) ([]*clusterv1alpha1.Cluster, error) {
|
|
spreadConstraintMap := make(map[policyv1alpha1.SpreadFieldValue]policyv1alpha1.SpreadConstraint)
|
|
for i := range spreadConstraints {
|
|
spreadConstraintMap[spreadConstraints[i].SpreadByField] = spreadConstraints[i]
|
|
}
|
|
|
|
if _, exist := spreadConstraintMap[policyv1alpha1.SpreadByFieldRegion]; exist {
|
|
return selectBestClustersByRegion(spreadConstraintMap, groupClustersInfo)
|
|
} else if _, exist := spreadConstraintMap[policyv1alpha1.SpreadByFieldCluster]; exist {
|
|
return selectBestClustersByCluster(spreadConstraintMap[policyv1alpha1.SpreadByFieldCluster], groupClustersInfo, needReplicas)
|
|
} else {
|
|
return nil, fmt.Errorf("just support cluster and region spread constraint")
|
|
}
|
|
}
|
|
|
|
func shouldIgnoreSpreadConstraint(placement *policyv1alpha1.Placement) bool {
|
|
strategy := placement.ReplicaScheduling
|
|
|
|
// If the replica division preference is 'static weighted', ignore the declaration specified by spread constraints.
|
|
if strategy != nil && strategy.ReplicaSchedulingType == policyv1alpha1.ReplicaSchedulingTypeDivided &&
|
|
strategy.ReplicaDivisionPreference == policyv1alpha1.ReplicaDivisionPreferenceWeighted &&
|
|
(strategy.WeightPreference != nil && len(strategy.WeightPreference.StaticWeightList) != 0 && strategy.WeightPreference.DynamicWeight == "") {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func shouldIgnoreAvailableResource(placement *policyv1alpha1.Placement) bool {
|
|
strategy := placement.ReplicaScheduling
|
|
|
|
// If the replica division preference is 'Duplicated', ignore the information about cluster available resource.
|
|
if strategy == nil || strategy.ReplicaSchedulingType == policyv1alpha1.ReplicaSchedulingTypeDuplicated {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|