Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(policy): use new compute for rules and fix rules intersect #12340

Merged
merged 13 commits into from
Jan 10, 2025
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ issues:
- linters:
- gocritic
text: "appendAssign: append result not assigned to the same slice" # None of the instances of this in Kuma were bugs.
- linters:
- gocritic
text: "elseif: can replace 'else {if cond {}}' with 'else if cond {}'" # None of the instances of this in Kuma were bugs.
- linters:
- gosimple
text: "S1008: should use 'return overlapKeyCount != 0' instead of 'if overlapKeyCount == 0 { return false }; return true'" # Ignore this to better read the code
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved
- linters:
- staticcheck
text: "SA1019: package sigs.k8s.io/controller-runtime/pkg/client/fake is deprecated" # https://github.com/kumahq/kuma/issues/2460
Expand Down
3 changes: 1 addition & 2 deletions pkg/core/xds/inspect/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ func getOutboundRuleAttachments(rules core_rules.Rules, networking *mesh_proto.D
}
attachment := byUniqueClusterName[name]
if attachment == nil {
subset := core_rules.SubsetFromTags(outboundTags)
computedRule := rules.Compute(subset)
computedRule := rules.NewCompute(core_rules.Element(outboundTags))
if computedRule == nil {
continue
}
Expand Down
90 changes: 89 additions & 1 deletion pkg/plugins/policies/core/rules/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,53 @@ func NewSubset(m map[string]string) Subset {
return s
}

func (ss Subset) ContainsElement(element Element) bool {
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved
// 1. find the overlaps of element and current subset
// 2. verify the overlaps
// 3. verify the left of current subset

if len(ss) == 0 {
return true
}
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved

overlapKeyCount := 0
for _, tag := range ss {
tmpVal, ok := element[tag.Key]
if ok {
overlapKeyCount++

// contradict
if tag.Value == tmpVal && tag.Not {
return false
}
// intersect
if tag.Value == tmpVal && !tag.Not {
continue
}
// intersect
if tag.Value != tmpVal && tag.Not {
continue
}
// contradict
if tag.Value != tmpVal && !tag.Not {
return false
}
} else {
// for those items that don't exist in element should not make an impact
if !tag.Not {
return false
}
}
}

// no overlap means no connections
if overlapKeyCount == 0 {
return false
}

return true
}

// IsSubset returns true if 'other' is a subset of the current set.
// Empty set is a superset for all subsets.
func (ss Subset) IsSubset(other Subset) bool {
Expand Down Expand Up @@ -196,7 +243,7 @@ func (ss Subset) Intersect(other Subset) bool {
}
oTags, ok := otherByKeysOnlyPositive[tag.Key]
if !ok {
return true
continue
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved
}
for _, otherTag := range oTags {
if otherTag != tag {
Expand Down Expand Up @@ -235,6 +282,29 @@ func SubsetFromTags(tags map[string]string) Subset {
return subset
}

type Element map[string]string

func (e Element) WithKeyValue(key, value string) Element {
if e == nil {
e = Element{}
}

e[key] = value
return e
}

func MeshElement() Element {
return Element{}
}

func MeshServiceElement(name string) Element {
return Element{mesh_proto.ServiceTag: name}
}

func MeshExternalServiceElement(name string) Element {
return Element{mesh_proto.ServiceTag: name}
}
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved

// NumPositive returns a number of tags without negation
func (ss Subset) NumPositive() int {
pos := 0
Expand Down Expand Up @@ -290,6 +360,24 @@ func (r *Rule) GetBackendRefOrigin(hash common_api.MatchesHash) (core_model.Reso

type Rules []*Rule

func (rs Rules) NewCompute(element Element) *Rule {
Icarus9913 marked this conversation as resolved.
Show resolved Hide resolved
for _, rule := range rs {
if rule.Subset.ContainsElement(element) {
return rule
}
}
return nil
}

func NewComputeConf[T any](rs Rules, element Element) *T {
computed := rs.NewCompute(element)
if computed != nil {
return pointer.To(computed.Conf.(T))
}

return nil
}

// Compute returns configuration for the given subset.
func (rs Rules) Compute(sub Subset) *Rule {
for _, rule := range rs {
Expand Down
Loading
Loading