Skip to content

Fix combineRulesEndpoints to correctly handle allow-all port semantics#205

Closed
Supreeth095 wants to merge 1 commit intomainfrom
fix/combine-rules-port-semantics
Closed

Fix combineRulesEndpoints to correctly handle allow-all port semantics#205
Supreeth095 wants to merge 1 commit intomainfrom
fix/combine-rules-port-semantics

Conversation

@Supreeth095
Copy link
Copy Markdown
Contributor

When combining rules for the same CIDR, if any rule allows all ports (empty Ports slice), the combined rule should allow all ports.

Previously, the function would incorrectly append the empty slice, resulting in policies being more restrictive than intended.

Fixes #197 #193

What type of PR is this?

Which issue does this PR fix:

What does this PR do / Why do we need it:

If an issue # is not available please add steps to reproduce and the controller logs:

Testing done on this change:

Automation added to e2e:

Will this PR introduce any new dependencies?:

Will this break upgrades or downgrades. Has updating a running cluster been tested?:

Does this PR introduce any user-facing change?:


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

When combining rules for the same CIDR, if any rule allows all ports
(empty Ports slice), the combined rule should allow all ports.

Previously, the function would incorrectly append the empty slice,
resulting in policies being more restrictive than intended.

Fixes #197
@stefansedich
Copy link
Copy Markdown

Hi @Supreeth095 do we have any idea on when this change might be merged and deployed to the controlplane?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes combineRulesEndpoints so that when combining EndpointInfo entries for the same CIDR, an “allow all ports” rule (empty Ports slice) results in the combined rule allowing all ports, avoiding unintended over-restriction in generated PolicyEndpoints.

Changes:

  • Update combineRulesEndpoints to treat an empty Ports slice as “allow all ports” and make it dominate during combination.
  • Add a unit test covering allow-all port semantics for combined rules.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
pkg/policyendpoints/manager.go Adjusts rule-combination logic so empty Ports correctly yields “allow all ports” when merging same-CIDR entries.
pkg/policyendpoints/manager_test.go Adds a test validating allow-all port behavior during endpoint combination.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

tempIEP.Ports = append(combinedMap[string(iep.CIDR)].Ports, iep.Ports...)
}
// If tempIEP.Ports is already empty (allow all), keep it empty
tempIEP.Except = append(combinedMap[string(iep.CIDR)].Except, iep.Except...)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tempIEP.Except = append(...) effectively unions exception lists when combining entries. For ipBlock semantics, unioning Except is overly restrictive (the union of two ipBlocks with the same CIDR corresponds to intersecting their exception sets, not unioning). If you keep combining, exceptions should be handled in a semantics-preserving way (or avoid combining when Except differs).

Suggested change
tempIEP.Except = append(combinedMap[string(iep.CIDR)].Except, iep.Except...)
// For ipBlock semantics, combining rules with the same CIDR must intersect their
// exception sets: (CIDR - E1) ∪ (CIDR - E2) == CIDR - (E1 ∩ E2).
existingExcept := sets.NewString(tempIEP.Except...)
newExcept := sets.NewString(iep.Except...)
intersectExcept := existingExcept.Intersection(newExcept)
tempIEP.Except = intersectExcept.UnsortedList()

Copilot uses AI. Check for mistakes.
Comment on lines +636 to +643
result := combineRulesEndpoints(tt.inputEndpoints)
assert.Equal(t, 1, len(result), "Should combine to single CIDR entry")

if tt.wantPortsEmpty {
assert.Empty(t, result[0].Ports, tt.description)
} else {
assert.NotEmpty(t, result[0].Ports, tt.description)
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test only checks whether the combined Ports slice is empty/non-empty. For the "only specific ports" case it would be stronger to assert the exact number of ports (and ideally their protocol/port values) so the test fails if ports are accidentally dropped or duplicated during combination.

Copilot uses AI. Check for mistakes.
Comment on lines 291 to 293
for _, iep := range ingressEndpoints {
if _, ok := combinedMap[string(iep.CIDR)]; ok {
tempIEP := combinedMap[string(iep.CIDR)]
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combineRulesEndpoints currently combines endpoints solely by CIDR. If two rules share a CIDR but have different Except lists, merging them into a single EndpointInfo changes NetworkPolicy semantics (e.g., it can drop an allow that should apply to an excepted range). Consider including Except (normalized/sorted) in the grouping key, or skipping combination when Except differs, so only compatible rules are merged.

Copilot uses AI. Check for mistakes.
@Supreeth095 Supreeth095 closed this Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Policy endpoint does not accurately reflect the network policy

3 participants