Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 3 additions & 115 deletions npm/pkg/controlplane/translation/parseSelector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ParseLabel takes a Azure-NPM processed label then returns if it's referring to complement set,
// and if so, returns the original set as well.
func ParseLabel(label string) (string, bool) {
// The input label is guaranteed to have a non-zero length validated by k8s.
// For label definition, see below parseSelector() function.
if label[0:1] == util.IptablesNotFlag {
return label[1:], true
}
return label, false
}

// GetOperatorAndLabel returns the operator associated with the label and the label without operator.
func GetOperatorAndLabel(labelWithOp string) (op, label string) {
// TODO(jungukcho): check whether this is possible
if labelWithOp == "" {
return op, label
}

// in case "!"" Operaror do not exist
if string(labelWithOp[0]) != util.IptablesNotFlag {
label = labelWithOp
return op, label
}

// in case "!"" Operaror exists
op, label = util.IptablesNotFlag, labelWithOp[1:]
return op, label
}

// GetOperatorsAndLabels returns the operators along with the associated labels.
func GetOperatorsAndLabels(labelsWithOps []string) (ops, labelsWithoutOps []string) {
ops = make([]string, len(labelsWithOps))
labelsWithoutOps = make([]string, len(labelsWithOps))

for i, labelWithOp := range labelsWithOps {
op, labelWithoutOp := GetOperatorAndLabel(labelWithOp)
ops[i] = op
labelsWithoutOps[i] = labelWithoutOp
}
return ops, labelsWithoutOps
}

// getSetNameForMultiValueSelector takes in label with multiple values without operator
// and returns a new 2nd level ipset name
func getSetNameForMultiValueSelector(key string, vals []string) string {
newIPSet := key
for _, val := range vals {
newIPSet = util.GetIpSetFromLabelKV(newIPSet, val)
}
return newIPSet
}

// FlattenNameSpaceSelector will help flatten multiple nameSpace selector match Expressions values
// flattenNameSpaceSelector will help flatten multiple nameSpace selector match Expressions values
// into multiple label selectors helping with the OR condition.
func FlattenNameSpaceSelector(nsSelector *metav1.LabelSelector) []metav1.LabelSelector {
func flattenNameSpaceSelector(nsSelector *metav1.LabelSelector) []metav1.LabelSelector {
/*
This function helps to create multiple labelSelectors when given a single multivalue nsSelector
Take below example: this nsSelector has 2 values in a matchSelector.
Expand Down Expand Up @@ -179,66 +127,6 @@ func zipMatchExprs(baseSelectors []metav1.LabelSelector, matchExpr metav1.LabelS
return zippedLabelSelectors
}

// parseSelector takes a LabelSelector and returns a slice of processed labels, Lists with members as values.
// this function returns a slice of all the label ipsets excluding multivalue matchExprs
// and a map of labelKeys and labelIpsetname for multivalue match exprs
// higher level functions will need to compute what sets or ipsets should be
// used from this map
func parseSelector(selector *metav1.LabelSelector) (labels []string, vals map[string][]string) {
// TODO(jungukcho): check return values
// labels []string and []string{}
if selector == nil {
return labels, vals
}

labels = []string{}
vals = make(map[string][]string)
if len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0 {
labels = append(labels, "")
return labels, vals
}

sortedKeys, sortedVals := util.SortMap(&selector.MatchLabels)
for i := range sortedKeys {
labels = append(labels, sortedKeys[i]+":"+sortedVals[i])
}

for _, req := range selector.MatchExpressions {
var k string
switch op := req.Operator; op {
case metav1.LabelSelectorOpIn:
k = req.Key
if len(req.Values) == 1 {
labels = append(labels, k+":"+req.Values[0])
} else {
// We are not adding the k:v to labels for multiple values, because, labels are used
// to construct partial IptEntries and if these below labels are added then we are inducing
// AND condition on values of a match expression instead of OR
vals[k] = append(vals[k], req.Values...)
}
case metav1.LabelSelectorOpNotIn:
k = util.IptablesNotFlag + req.Key
if len(req.Values) == 1 {
labels = append(labels, k+":"+req.Values[0])
} else {
vals[k] = append(vals[k], req.Values...)
}
// Exists matches pods with req.Key as key
case metav1.LabelSelectorOpExists:
k = req.Key
labels = append(labels, k)
// DoesNotExist matches pods without req.Key as key
case metav1.LabelSelectorOpDoesNotExist:
k = util.IptablesNotFlag + req.Key
labels = append(labels, k)
default:
log.Errorf("Invalid operator [%s] for selector [%v] requirement", op, *selector)
}
}

return labels, vals
}

// labelSelector has parsed matchLabels and MatchExpressions information.
type labelSelector struct {
// include is a flag to indicate whether Op exists or not.
Expand Down Expand Up @@ -297,7 +185,7 @@ func (ps *parsedSelectors) addSelector(include bool, setType ipsets.SetType, set
// parseNSSelector parses namespaceSelector and returns slice of labelSelector object
// which includes operator, setType, ipset name and always nil members slice.
// Member slices is always nil since parseNSSelector function is called
// after FlattenNameSpaceSelector function is called, which guarantees
// after flattenNameSpaceSelector function is called, which guarantees
// there is no matchExpression with multiple values.
// TODO: good to remove this dependency later if possible.
func parseNSSelector(selector *metav1.LabelSelector) []labelSelector {
Expand Down
Loading