Skip to content

OTA-1639: Restrict osus egress namespace#265

Open
nader-ziada wants to merge 1 commit into
openshift:masterfrom
nader-ziada:restrict-osus-egress-namespace
Open

OTA-1639: Restrict osus egress namespace#265
nader-ziada wants to merge 1 commit into
openshift:masterfrom
nader-ziada:restrict-osus-egress-namespace

Conversation

@nader-ziada
Copy link
Copy Markdown
Contributor

@nader-ziada nader-ziada commented Jun 2, 2026

When spec.releases points to a cluster-internal registry (.svc), the NetworkPolicy now restricts egress to only that registry's namespace using a namespaceSelector, blocking all cluster-external traffic.

blocked by #264 being merged first

Summary by CodeRabbit

  • Improvements

    • Better detection of cluster-internal registries with stricter hostname validation.
    • Network policies now add a dedicated registry egress rule and apply namespace-specific egress restrictions for internal registries while leaving external registries unrestricted.
    • Network policies include clearer descriptive annotations about egress behavior.
  • Tests

    • Added tests validating namespace extraction from internal service hostnames and egress namespace behavior.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 2, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Jun 2, 2026

@nader-ziada: This pull request references OTA-1639 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

When spec.releases points to a cluster-internal registry (.svc), the NetworkPolicy now restricts egress to only that registry's namespace using a namespaceSelector, blocking all cluster-external traffic.

blocked by #264 being merged first

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 2, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 2, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refactors internal-registry detection with constants and a namespaceFromInternalHost parser. Updates newNetworkPolicy to compute a registryEgress rule, set a description annotation, and restrict egress To to a namespace selector when the registry hostname is cluster-internal. Tests added for parsing and egress namespace behavior.

Changes

Cluster-internal registry egress filtering

Layer / File(s) Summary
Hostname parsing and internal registry detection
controllers/new.go, controllers/new_test.go
Adds constants for .svc and .svc.cluster.local suffixes and namespaceFromInternalHost that extracts namespace names (supports optional :port). Includes tests validating extraction for valid and invalid hostnames.
NetworkPolicy egress namespace selector
controllers/new.go, controllers/new_test.go
newNetworkPolicy computes a registryEgress rule, sets kubernetes.io/description, and when the registry is cluster-internal restricts To with a namespace selector; otherwise leaves To empty. Tests validate namespace-selector presence only for cluster-internal registries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

lgtm


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error Code logs sensitive data: instance.Spec.Releases (internal hostnames) at line 517, and proxy URL value at line 330 in controllers/new.go. Remove or redact instance.Spec.Releases from error message; omit proxy URL value from log (log env name only, not its value).
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: restricting OSUS egress to a specific namespace when a cluster-internal registry is configured.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All test names in the PR are stable and deterministic with static string literals, no dynamic values like UUIDs or timestamps, and descriptive titles clearly indicating test purpose.
Test Structure And Quality ✅ Passed PR contains standard Go unit tests, not Ginkgo tests. Custom check targets Ginkgo test structure (It blocks, Describe, BeforeEach/AfterEach), which doesn't apply here.
Microshift Test Compatibility ✅ Passed New tests are standard Go unit tests using testing.T, not Ginkgo e2e tests. The custom check applies only to Ginkgo e2e tests (It, Describe, Context, When), so it does not apply here.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests added. The PR only adds standard Go unit tests using testing.T to verify function behavior, which do not make multi-node cluster assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed PR modifies only NetworkPolicy egress rules; no scheduling constraints, affinity rules, nodeSelectors, or topology-dependent logic introduced that would break non-standard OpenShift topologies.
Ote Binary Stdout Contract ✅ Passed No OTE binary stdout contract violations found. PR changes only add helper function and modify NetworkPolicy generation logic with no process-level stdout writes, klog defaults to stderr.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests are added. The PR adds only standard Go unit tests using testing.T, which are not subject to IPv6/disconnected network requirements.
No-Weak-Crypto ✅ Passed PR uses only crypto/sha256 (strong hash function). No weak crypto algorithms, custom implementations, or unsafe secret comparisons found.
Container-Privileges ✅ Passed PR modifies NetworkPolicy egress. No privileged container settings found: no privileged containers, hostPID, hostNetwork, hostIPC, allowPrivilegeEscalation, or capabilities.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 2, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: nader-ziada
Once this PR has been reviewed and has the lgtm label, please assign wking for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
controllers/new.go (1)

395-405: 💤 Low value

Refactor to avoid duplicating registry extraction.

The registry is extracted from instance.Spec.Releases on line 405, but the same extraction already happens inside egressPorts on line 322. Consider extracting the registry once and passing it to both functions, or returning it from egressPorts.

♻️ Suggested refactor
-func egressPorts(releases string) []int32 {
+func egressPorts(releases string) ([]int32, string) {
 	seen := map[int32]bool{}
 	var ports []int32
 	add := func(p int32) {
@@ -331,7 +331,7 @@ func egressPorts(releases string) []int32 {
 		}
 	}
 
-	return ports
+	return ports, registry
 }

Then update the caller:

 func (k *kubeResources) newNetworkPolicy(instance *cv1.UpdateService) *networkingv1.NetworkPolicy {
-	ports := egressPorts(instance.Spec.Releases)
+	ports, registry := egressPorts(instance.Spec.Releases)
 	egressPolicyPorts := make([]networkingv1.NetworkPolicyPort, len(ports))
 	for i, p := range ports {
 		egressPolicyPorts[i] = networkingv1.NetworkPolicyPort{
@@ -402,7 +402,6 @@ func (k *kubeResources) newNetworkPolicy(instance *cv1.UpdateService) *networki
 		}
 	}
 
-	registry := strings.SplitN(instance.Spec.Releases, "/", 2)[0]
 	registryEgress := networkingv1.NetworkPolicyEgressRule{
 		Ports: egressPolicyPorts,
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/new.go` around lines 395 - 405, The code duplicates extraction of
the registry from instance.Spec.Releases in newNetworkPolicy and inside
egressPorts; refactor to extract registry once and pass it where needed (or have
egressPorts return it). Specifically, modify calls so newNetworkPolicy computes
registry := strings.SplitN(instance.Spec.Releases, "/", 2)[0] once and then pass
that registry into egressPorts (or change egressPorts to return (ports,
registry)), updating the function signatures and call sites accordingly
(egressPorts, newNetworkPolicy) to remove the duplicate extraction.
controllers/testdata/resources/zz_fixture_Test_newKubeResources_network_policy.yaml (1)

3-6: 💤 Low value

Description mentions "proxy ports" but only registry port 443 is shown.

The annotation describes egress to "the registry and proxy ports", but the egress rules only show port 443. If this fixture represents a scenario with no proxy configured, or a cluster-internal registry (where proxy ports are excluded per the PR design), the description could be misleading.

Consider clarifying the description to match the actual egress rules present in this test fixture.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@controllers/testdata/resources/zz_fixture_Test_newKubeResources_network_policy.yaml`
around lines 3 - 6, Update the kubernetes.io/description annotation so it
accurately matches the egress rules in this NetworkPolicy: either remove mention
of "proxy ports" and state that egress is limited to the registry (port 443)
only, or explicitly list the proxy ports in the egress spec to match the current
description; locate the annotation line with key kubernetes.io/description in
the NetworkPolicy manifest and edit the text accordingly so description and
actual egress ports are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controllers/new.go`:
- Around line 367-393: The code treats malformed hosts like "foo.svc" as
cluster-internal; fix this by making proxy-port skipping depend on successful
namespace extraction: change isClusterInternal to call
namespaceFromInternalHost(host) and return true only when that call yields a
non-empty namespace; keep namespaceFromInternalHost's current strict parsing
(service.namespace.svc(.cluster.local) -> namespace or "" for malformed) so
malformed hosts are not treated as internal. Also add validation on the
spec.releases field (the Releases/Spec type) to enforce the expected hostname
format/pattern (add a kubebuilder validation pattern) so malformed internal
hostnames are rejected before reconciliation.

---

Nitpick comments:
In `@controllers/new.go`:
- Around line 395-405: The code duplicates extraction of the registry from
instance.Spec.Releases in newNetworkPolicy and inside egressPorts; refactor to
extract registry once and pass it where needed (or have egressPorts return it).
Specifically, modify calls so newNetworkPolicy computes registry :=
strings.SplitN(instance.Spec.Releases, "/", 2)[0] once and then pass that
registry into egressPorts (or change egressPorts to return (ports, registry)),
updating the function signatures and call sites accordingly (egressPorts,
newNetworkPolicy) to remove the duplicate extraction.

In
`@controllers/testdata/resources/zz_fixture_Test_newKubeResources_network_policy.yaml`:
- Around line 3-6: Update the kubernetes.io/description annotation so it
accurately matches the egress rules in this NetworkPolicy: either remove mention
of "proxy ports" and state that egress is limited to the registry (port 443)
only, or explicitly list the proxy ports in the egress spec to match the current
description; locate the annotation line with key kubernetes.io/description in
the NetworkPolicy manifest and edit the text accordingly so description and
actual egress ports are consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c923eaf8-e876-407e-8cf3-58203bdd4bf5

📥 Commits

Reviewing files that changed from the base of the PR and between bf8d3a0 and 20f0dc3.

📒 Files selected for processing (4)
  • controllers/new.go
  • controllers/new_test.go
  • controllers/testdata/resources/zz_fixture_Test_newKubeResources_network_policy.yaml
  • controllers/updateservice_controller_test.go

Comment thread controllers/new.go
@nader-ziada nader-ziada force-pushed the restrict-osus-egress-namespace branch 3 times, most recently from 62075c3 to 1806ef7 Compare June 4, 2026 13:56
@nader-ziada nader-ziada marked this pull request as ready for review June 4, 2026 15:57
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 4, 2026
@nader-ziada nader-ziada force-pushed the restrict-osus-egress-namespace branch 2 times, most recently from 0fe565d to 5b7d0c6 Compare June 4, 2026 16:12
@nader-ziada
Copy link
Copy Markdown
Contributor Author

/retest

@nader-ziada
Copy link
Copy Markdown
Contributor Author

@hongkailiu ready for review

@nader-ziada
Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 5, 2026

@nader-ziada: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/operator-e2e-hypershift-local-graph-data 5b7d0c6 link true /test operator-e2e-hypershift-local-graph-data
ci/prow/scorecard 5b7d0c6 link true /test scorecard
ci/prow/install-bundle 5b7d0c6 link true /test install-bundle

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 7, 2026
…tries

When spec.releases points to a cluster-internal registry (.svc), the
NetworkPolicy now restricts egress to only that registry's namespace
using a namespaceSelector, blocking all cluster-external traffic.

Signed-off-by: Nader Ziada <nziada@redhat.com>
@nader-ziada nader-ziada force-pushed the restrict-osus-egress-namespace branch from 5b7d0c6 to 711054d Compare June 8, 2026 00:31
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants