Skip to content

Commit

Permalink
filter drpc pvc labels
Browse files Browse the repository at this point in the history
Signed-off-by: Raghavendra Talur <raghavendra.talur@gmail.com>
  • Loading branch information
raghavendra-talur committed Oct 3, 2023
1 parent 8eae033 commit bfc6742
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions controllers/drplacementcontrol_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Check failure on line 20 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

ST1019: package "k8s.io/apimachinery/pkg/apis/meta/v1" is being imported more than once (stylecheck)
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Check failure on line 21 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

ST1019(related information): other import of "k8s.io/apimachinery/pkg/apis/meta/v1" (stylecheck)
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -633,6 +634,10 @@ func (r *DRPlacementControlReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}

if err, _ := r.ensureHasNoConflictingLabelSelectors(ctx, drpc); err != nil {
r.recordFailure(ctx, drpc, placementObj, "Error", err.Error(), logger)
}

drPolicy, err := r.getAndEnsureValidDRPolicy(ctx, drpc, logger)
if err != nil {
r.recordFailure(ctx, drpc, placementObj, "Error", err.Error(), logger)
Expand Down Expand Up @@ -2024,3 +2029,96 @@ func ensureDRPCConditionsInited(conditions *[]metav1.Condition, observedGenerati
Message: message,
})
}

func canMatchSameElements(selector1, selector2 *v1.LabelSelector) bool {
// Convert matchLabels to LabelSelectorRequirements for unified processing
exprFromLabels1 := labelsToExpressions(selector1.MatchLabels)
exprFromLabels2 := labelsToExpressions(selector2.MatchLabels)

// Consolidate all matchExpressions
allExprs1 := append(exprFromLabels1, selector1.MatchExpressions...)

Check failure on line 2039 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

appendAssign: append result not assigned to the same slice (gocritic)
allExprs2 := append(exprFromLabels2, selector2.MatchExpressions...)

Check failure on line 2040 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

appendAssign: append result not assigned to the same slice (gocritic)

// Check if any expression contradicts the other selector
return !expressionsContradict(allExprs1, allExprs2) && !expressionsContradict(allExprs2, allExprs1)
}

func labelsToExpressions(matchLabels map[string]string) []v1.LabelSelectorRequirement {
var exprs []v1.LabelSelectorRequirement

Check failure on line 2047 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

Consider pre-allocating `exprs` (prealloc)
for k, v := range matchLabels {
exprs = append(exprs, v1.LabelSelectorRequirement{
Key: k,
Operator: v1.LabelSelectorOpIn,
Values: []string{v},
})
}
return exprs

Check failure on line 2055 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

return statements should not be cuddled if block has more than two lines (wsl)
}

func expressionsContradict(exprs1, exprs2 []v1.LabelSelectorRequirement) bool {

Check failure on line 2058 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

cognitive complexity 47 of func `expressionsContradict` is high (> 15) (gocognit)
for _, expr1 := range exprs1 {
for _, expr2 := range exprs2 {
if expr1.Key != expr2.Key {
continue
}

switch expr1.Operator {
case v1.LabelSelectorOpIn:
if expr2.Operator == v1.LabelSelectorOpNotIn {
for _, val := range expr1.Values {
if contains(expr2.Values, val) {
return true
}
}
}
case v1.LabelSelectorOpNotIn:
if expr2.Operator == v1.LabelSelectorOpIn {
for _, val := range expr1.Values {
if contains(expr2.Values, val) {
return true
}
}
}
case v1.LabelSelectorOpExists:
if expr2.Operator == v1.LabelSelectorOpDoesNotExist {
return true
}
case v1.LabelSelectorOpDoesNotExist:
if expr2.Operator == v1.LabelSelectorOpExists {
return true
}
}
}
}

return false
}

func contains(slice []string, item string) bool {
for _, a := range slice {
if a == item {
return true
}
}
return false

Check failure on line 2103 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

return statements should not be cuddled if block has more than two lines (wsl)
}

func (r *DRPlacementControlReconciler) ensureHasNoConflictingLabelSelectors(ctx context.Context, drpc *rmn.DRPlacementControl) (error, *rmn.DRPlacementControl) {

Check failure on line 2106 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

error should be the last type when returning multiple items (golint)
drpcList := &rmn.DRPlacementControlList{}
err := r.APIReader.List(ctx, drpcList)
if err != nil {

Check failure on line 2109 in controllers/drplacementcontrol_controller.go

View workflow job for this annotation

GitHub Actions / Golangci Lint

only one cuddle assignment allowed before if statement (wsl)
return fmt.Errorf("failed to list DRPC objects %w", err), nil
}

for _, otherDRPC := range drpcList.Items {
if otherDRPC.Name == drpc.Name {
continue
}

if canMatchSameElements(&drpc.Spec.PVCSelector, &otherDRPC.Spec.PVCSelector) {
return fmt.Errorf("DRPC %s has conflicting PVCSelector with DRPC %s", drpc.Name, otherDRPC.Name), &otherDRPC
}
}

return nil, nil
}

0 comments on commit bfc6742

Please sign in to comment.