Skip to content

Commit

Permalink
feat(detector): resource detector matched policy potimization
Browse files Browse the repository at this point in the history
Signed-off-by: chang.qiangqiang <chang.qiangqiang@immomo.com>
  • Loading branch information
CharlesQQ committed Nov 11, 2024
1 parent b5c6660 commit cfc8912
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 69 deletions.
33 changes: 22 additions & 11 deletions pkg/detector/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,43 @@ import (

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"

policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
"github.com/karmada-io/karmada/pkg/util"
"github.com/karmada-io/karmada/pkg/util/fedinformer/keys"
)

func getHighestPriorityPropagationPolicy(policies []*policyv1alpha1.PropagationPolicy, resource *unstructured.Unstructured, objectKey keys.ClusterWideKey) *policyv1alpha1.PropagationPolicy {
func getHighestPriorityPropagationPolicy(policies []policyv1alpha1.PropagationPolicy, resource *unstructured.Unstructured, objectKey keys.ClusterWideKey) *policyv1alpha1.PropagationPolicy {
matchedPolicyImplicitPriority := util.PriorityMisMatch
matchedPolicyExplicitPriority := int32(math.MinInt32)
var matchedPolicy *policyv1alpha1.PropagationPolicy

for _, policy := range policies {
implicitPriority := util.ResourceMatchSelectorsPriority(resource, policy.Spec.ResourceSelectors...)
policyPointer := ptr.To(policy)
if !policyPointer.DeletionTimestamp.IsZero() {
klog.V(4).Infof("Propagation policy(%s/%s) cannot match any resource template because it's being deleted.", policyPointer.Namespace, policyPointer.Name)
continue
}
implicitPriority := util.ResourceMatchSelectorsPriority(resource, policyPointer.Spec.ResourceSelectors...)
if implicitPriority <= util.PriorityMisMatch {
continue
}
explicitPriority := policy.ExplicitPriority()
explicitPriority := policyPointer.ExplicitPriority()

if matchedPolicyExplicitPriority < explicitPriority {
matchedPolicyImplicitPriority = implicitPriority
matchedPolicyExplicitPriority = explicitPriority
matchedPolicy = policy
matchedPolicy = policyPointer
continue
}

if matchedPolicyExplicitPriority == explicitPriority {
if implicitPriority > matchedPolicyImplicitPriority {
matchedPolicyImplicitPriority = implicitPriority
matchedPolicy = policy
matchedPolicy = policyPointer
} else if implicitPriority == matchedPolicyImplicitPriority {
matchedPolicy = getHigherPriorityPropagationPolicy(matchedPolicy, policy)
matchedPolicy = getHigherPriorityPropagationPolicy(matchedPolicy, policyPointer)
}
}
}
Expand All @@ -64,31 +70,36 @@ func getHighestPriorityPropagationPolicy(policies []*policyv1alpha1.PropagationP
return matchedPolicy
}

func getHighestPriorityClusterPropagationPolicy(policies []*policyv1alpha1.ClusterPropagationPolicy, resource *unstructured.Unstructured, objectKey keys.ClusterWideKey) *policyv1alpha1.ClusterPropagationPolicy {
func getHighestPriorityClusterPropagationPolicy(policies []policyv1alpha1.ClusterPropagationPolicy, resource *unstructured.Unstructured, objectKey keys.ClusterWideKey) *policyv1alpha1.ClusterPropagationPolicy {
matchedClusterPolicyImplicitPriority := util.PriorityMisMatch
matchedClusterPolicyExplicitPriority := int32(math.MinInt32)
var matchedClusterPolicy *policyv1alpha1.ClusterPropagationPolicy

for _, policy := range policies {
policyPointer := ptr.To(policy)
if !policyPointer.DeletionTimestamp.IsZero() {
klog.V(4).Infof("Cluster propagation policy(%s/%s) cannot match any resource template because it's being deleted.", policyPointer.Namespace, policyPointer.Name)
continue
}
implicitPriority := util.ResourceMatchSelectorsPriority(resource, policy.Spec.ResourceSelectors...)
if implicitPriority <= util.PriorityMisMatch {
continue
}
explicitPriority := policy.ExplicitPriority()
explicitPriority := policyPointer.ExplicitPriority()

if matchedClusterPolicyExplicitPriority < explicitPriority {
matchedClusterPolicyImplicitPriority = implicitPriority
matchedClusterPolicyExplicitPriority = explicitPriority
matchedClusterPolicy = policy
matchedClusterPolicy = policyPointer
continue
}

if matchedClusterPolicyExplicitPriority == explicitPriority {
if implicitPriority > matchedClusterPolicyImplicitPriority {
matchedClusterPolicyImplicitPriority = implicitPriority
matchedClusterPolicy = policy
matchedClusterPolicy = policyPointer
} else if implicitPriority == matchedClusterPolicyImplicitPriority {
matchedClusterPolicy = getHigherPriorityClusterPropagationPolicy(matchedClusterPolicy, policy)
matchedClusterPolicy = getHigherPriorityClusterPropagationPolicy(matchedClusterPolicy, policyPointer)
}
}
}
Expand Down
40 changes: 20 additions & 20 deletions pkg/detector/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func Test_GetHigherPriorityClusterPropagationPolicy(t *testing.T) {

func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
type args struct {
policies []*policyv1alpha1.PropagationPolicy
policies []policyv1alpha1.PropagationPolicy
resource *unstructured.Unstructured
objectKey keys.ClusterWideKey
}
Expand All @@ -219,7 +219,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "empty policies",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{},
policies: []policyv1alpha1.PropagationPolicy{},
resource: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
Expand All @@ -237,7 +237,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "mo policy match for resource",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "match-with-name", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -278,7 +278,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "different implicit priority policy",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "match-with-name", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -339,7 +339,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "same implicit priority policy",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -390,7 +390,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "one policy with implicit priority, one policy with explicit priority 1",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -449,7 +449,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority 1(name match), one policy with explicit priority 2(label selector match)",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -512,7 +512,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "two policies with explicit priority 1(name match), select the one with lower alphabetical order",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -575,7 +575,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority 1(name match), one policy with explicit priority 1(label selector match)",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -638,7 +638,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority -1(name match), one policy with implicit priority(label selector match)",
args: args{
policies: []*policyv1alpha1.PropagationPolicy{
policies: []policyv1alpha1.PropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -702,7 +702,7 @@ func Test_getHighestPriorityPropagationPolicies(t *testing.T) {

func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
type args struct {
policies []*policyv1alpha1.ClusterPropagationPolicy
policies []policyv1alpha1.ClusterPropagationPolicy
resource *unstructured.Unstructured
objectKey keys.ClusterWideKey
}
Expand All @@ -714,7 +714,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "empty policies",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{},
policies: []policyv1alpha1.ClusterPropagationPolicy{},
resource: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
Expand All @@ -732,7 +732,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "mo policy match for resource",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "match-with-name", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -773,7 +773,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "different implicit priority policy",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "match-with-name", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -834,7 +834,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "same implicit priority policy",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -885,7 +885,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "one policy with implicit priority, one policy with explicit priority 1",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -944,7 +944,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority 1(name match), one policy with explicit priority 2(label selector match)",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -1007,7 +1007,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "two policies with explicit priority 1(name match), select the one with lower alphabetical order",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -1070,7 +1070,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority 1(name match), one policy with explicit priority 1(label selector match)",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down Expand Up @@ -1133,7 +1133,7 @@ func Test_getHighestPriorityClusterPropagationPolicies(t *testing.T) {
{
name: "one policy with explicit priority -1(name match), one policy with implicit priority(label selector match)",
args: args{
policies: []*policyv1alpha1.ClusterPropagationPolicy{
policies: []policyv1alpha1.ClusterPropagationPolicy{
{
ObjectMeta: metav1.ObjectMeta{Name: "a-pp", Namespace: "test"},
Spec: policyv1alpha1.PropagationSpec{
Expand Down
44 changes: 8 additions & 36 deletions pkg/detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,63 +359,35 @@ func (d *ResourceDetector) LookForMatchedPolicy(object *unstructured.Unstructure
}

klog.V(2).Infof("Attempts to match policy for resource(%s)", objectKey)
policyObjects, err := d.propagationPolicyLister.ByNamespace(objectKey.Namespace).List(labels.Everything())
policyObjectList := &policyv1alpha1.PropagationPolicyList{}
err := d.Client.List(context.TODO(), policyObjectList)
if err != nil {
klog.Errorf("Failed to list propagation policy: %v", err)
return nil, err
}
if len(policyObjects) == 0 {
if len(policyObjectList.Items) == 0 {
klog.V(2).Infof("No propagationpolicy find in namespace(%s).", objectKey.Namespace)
return nil, nil
}

policyList := make([]*policyv1alpha1.PropagationPolicy, 0)
for index := range policyObjects {
policy := &policyv1alpha1.PropagationPolicy{}
if err = helper.ConvertToTypedObject(policyObjects[index], policy); err != nil {
klog.Errorf("Failed to convert PropagationPolicy from unstructured object: %v", err)
return nil, err
}

if !policy.DeletionTimestamp.IsZero() {
klog.V(4).Infof("Propagation policy(%s/%s) cannot match any resource template because it's being deleted.", policy.Namespace, policy.Name)
continue
}
policyList = append(policyList, policy)
}

return getHighestPriorityPropagationPolicy(policyList, object, objectKey), nil
return getHighestPriorityPropagationPolicy(policyObjectList.Items, object, objectKey), nil
}

// LookForMatchedClusterPolicy tries to find a ClusterPropagationPolicy for object referenced by object key.
func (d *ResourceDetector) LookForMatchedClusterPolicy(object *unstructured.Unstructured, objectKey keys.ClusterWideKey) (*policyv1alpha1.ClusterPropagationPolicy, error) {
klog.V(2).Infof("Attempts to match cluster policy for resource(%s)", objectKey)
policyObjects, err := d.clusterPropagationPolicyLister.List(labels.Everything())
policyObjectList := &policyv1alpha1.ClusterPropagationPolicyList{}
err := d.Client.List(context.TODO(), policyObjectList)
if err != nil {
klog.Errorf("Failed to list cluster propagation policy: %v", err)
return nil, err
}
if len(policyObjects) == 0 {
if len(policyObjectList.Items) == 0 {
klog.V(2).Infof("No clusterpropagationpolicy find.")
return nil, nil
}

policyList := make([]*policyv1alpha1.ClusterPropagationPolicy, 0)
for index := range policyObjects {
policy := &policyv1alpha1.ClusterPropagationPolicy{}
if err = helper.ConvertToTypedObject(policyObjects[index], policy); err != nil {
klog.Errorf("Failed to convert ClusterPropagationPolicy from unstructured object: %v", err)
return nil, err
}

if !policy.DeletionTimestamp.IsZero() {
klog.V(4).Infof("Cluster propagation policy(%s) cannot match any resource template because it's being deleted.", policy.Name)
continue
}
policyList = append(policyList, policy)
}

return getHighestPriorityClusterPropagationPolicy(policyList, object, objectKey), nil
return getHighestPriorityClusterPropagationPolicy(policyObjectList.Items, object, objectKey), nil
}

// ApplyPolicy starts propagate the object referenced by object key according to PropagationPolicy.
Expand Down
20 changes: 18 additions & 2 deletions pkg/detector/detector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,14 +678,22 @@ func TestLookForMatchedPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
scheme := setupTestScheme()
fakeClient := dynamicfake.NewSimpleDynamicClient(scheme)

controllerRuntimeFakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
d := &ResourceDetector{
Client: controllerRuntimeFakeClient,
DynamicClient: fakeClient,
propagationPolicyLister: &mockPropagationPolicyLister{
policies: tt.policies,
},
}

for _, policy := range tt.policies {
err := d.Client.Create(context.TODO(), policy)
if err != nil {
t.Errorf("Create policy by fakeClinet failed. : %v", err)
}
}

objectKey := keys.ClusterWideKey{
Name: tt.object.GetName(),
Namespace: tt.object.GetNamespace(),
Expand Down Expand Up @@ -767,13 +775,20 @@ func TestLookForMatchedClusterPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
scheme := setupTestScheme()
fakeClient := dynamicfake.NewSimpleDynamicClient(scheme)

controllerRuntimeFakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
d := &ResourceDetector{
Client: controllerRuntimeFakeClient,
DynamicClient: fakeClient,
clusterPropagationPolicyLister: &mockClusterPropagationPolicyLister{
policies: tt.policies,
},
}
for _, policy := range tt.policies {
err := d.Client.Create(context.TODO(), policy)
if err != nil {
t.Errorf("Create cluster policy by fakeClinet failed. : %v", err)
}
}

objectKey := keys.ClusterWideKey{
Name: tt.object.GetName(),
Expand Down Expand Up @@ -1030,6 +1045,7 @@ func setupTestScheme() *runtime.Scheme {
scheme := runtime.NewScheme()
_ = workv1alpha2.Install(scheme)
_ = corev1.AddToScheme(scheme)
_ = policyv1alpha1.Install(scheme)
return scheme
}

Expand Down

0 comments on commit cfc8912

Please sign in to comment.