diff --git a/pkg/scheduler/framework/plugins/registry.go b/pkg/scheduler/framework/plugins/registry.go index 14d5c355d..dcccc73eb 100644 --- a/pkg/scheduler/framework/plugins/registry.go +++ b/pkg/scheduler/framework/plugins/registry.go @@ -5,15 +5,17 @@ import ( "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/apiinstalled" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/clusteraffinity" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/clusterlocality" + "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/spreadconstraint" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/tainttoleration" ) // NewPlugins builds all the scheduling plugins. func NewPlugins() map[string]framework.Plugin { return map[string]framework.Plugin{ - clusteraffinity.Name: clusteraffinity.New(), - tainttoleration.Name: tainttoleration.New(), - apiinstalled.Name: apiinstalled.New(), - clusterlocality.Name: clusterlocality.New(), + clusteraffinity.Name: clusteraffinity.New(), + tainttoleration.Name: tainttoleration.New(), + apiinstalled.Name: apiinstalled.New(), + clusterlocality.Name: clusterlocality.New(), + spreadconstraint.Name: spreadconstraint.New(), } } diff --git a/pkg/scheduler/framework/plugins/spreadconstraint/spreadconstraint.go b/pkg/scheduler/framework/plugins/spreadconstraint/spreadconstraint.go new file mode 100644 index 000000000..dd9438f0f --- /dev/null +++ b/pkg/scheduler/framework/plugins/spreadconstraint/spreadconstraint.go @@ -0,0 +1,45 @@ +package spreadconstraint + +import ( + "context" + + clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" + policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" + "github.com/karmada-io/karmada/pkg/scheduler/framework" +) + +const ( + // Name is the name of the plugin used in the plugin registry and configurations. + Name = "SpreadConstraint" +) + +// SpreadConstraint is a plugin that checks if spread property in the Cluster.Spec. +type SpreadConstraint struct{} + +var _ framework.FilterPlugin = &SpreadConstraint{} + +// New instantiates the spreadconstraint plugin. +func New() framework.Plugin { + return &SpreadConstraint{} +} + +// Name returns the plugin name. +func (p *SpreadConstraint) Name() string { + return Name +} + +// Filter checks if the cluster Provider/Zone/Region spread is null. +func (p *SpreadConstraint) Filter(ctx context.Context, placement *policyv1alpha1.Placement, resource *workv1alpha2.ObjectReference, cluster *clusterv1alpha1.Cluster) *framework.Result { + for _, spreadConstraint := range placement.SpreadConstraints { + if spreadConstraint.SpreadByField == policyv1alpha1.SpreadByFieldProvider && cluster.Spec.Provider == "" { + return framework.NewResult(framework.Unschedulable, "No Provider Property in the Cluster.Spec") + } else if spreadConstraint.SpreadByField == policyv1alpha1.SpreadByFieldRegion && cluster.Spec.Region == "" { + return framework.NewResult(framework.Unschedulable, "No Region Property in the Cluster.Spec") + } else if spreadConstraint.SpreadByField == policyv1alpha1.SpreadByFieldZone && cluster.Spec.Zone == "" { + return framework.NewResult(framework.Unschedulable, "No Zone Property in the Cluster.Spec") + } + } + + return framework.NewResult(framework.Success) +} diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go index c5d8b0c80..b8d9e3f38 100644 --- a/pkg/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -37,6 +37,7 @@ import ( "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/apiinstalled" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/clusteraffinity" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/clusterlocality" + "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/spreadconstraint" "github.com/karmada-io/karmada/pkg/scheduler/framework/plugins/tainttoleration" "github.com/karmada-io/karmada/pkg/scheduler/metrics" "github.com/karmada-io/karmada/pkg/util" @@ -100,7 +101,7 @@ func NewScheduler(dynamicClient dynamic.Interface, karmadaClient karmadaclientse queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) schedulerCache := schedulercache.NewCache(clusterLister) // TODO: make plugins as a flag - algorithm := core.NewGenericScheduler(schedulerCache, []string{clusteraffinity.Name, tainttoleration.Name, apiinstalled.Name, clusterlocality.Name}) + algorithm := core.NewGenericScheduler(schedulerCache, []string{clusteraffinity.Name, tainttoleration.Name, apiinstalled.Name, clusterlocality.Name, spreadconstraint.Name}) sched := &Scheduler{ DynamicClient: dynamicClient, KarmadaClient: karmadaClient,