Skip to content

feat: runtime NetworkPolicies for EDA operator workloads - #362

Open
ttuffin wants to merge 11 commits into
mainfrom
feat/AAP-73976_networkpolicies
Open

feat: runtime NetworkPolicies for EDA operator workloads#362
ttuffin wants to merge 11 commits into
mainfrom
feat/AAP-73976_networkpolicies

Conversation

@ttuffin

@ttuffin ttuffin commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Create NetworkPolicy templates and tasks for all EDA operator-managed
workloads: api, ui, default-worker, activation-worker, event-stream,
postgres, and db-management (backup/restore pods).

Pattern follows the gateway operator reference, default-deny first
using match Expressions, per-workload least-privilege allow policies,
conditional managed/external database logic, DNS egress on all
egress-bearing policies, and NP tasks ordered before deployment tasks.

Key EDA-specific decisions:

  • Activation-worker has unrestricted egress (user-defined event sources)
  • Postgres NP includes app=eda ingress rule for runtime activation Job
    pods that connect via pg_notify (not operator-managed, no managed-by
    label)
  • db-management NP covers backup/restore pods blocked by default-deny
  • UI NP is conditionally absent when ui_disabled=true

Add networkpolicies to networking.k8s.io RBAC rule and replace molecule
FIXME stub with real NP assertions.

https://redhat.atlassian.net/browse/AAP-73976

Summary by CodeRabbit

  • New Features
    • Added network security policies for EDA components and managed PostgreSQL databases.
    • Restricted component communication to required services, including DNS, PostgreSQL, gateways, routers, and configured event sources.
    • Added a default-deny policy for stronger namespace isolation.
    • Network policies are automatically removed for the UI when the UI is disabled.
    • Added PostgreSQL 15 as the default supported version.
  • Bug Fixes
    • Corrected EDA permissions so ingress and network policy resources are authorized under the appropriate Kubernetes API groups.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 79a32baa-97b4-41ba-9992-c15b4ef0bf4d

📥 Commits

Reviewing files that changed from the base of the PR and between 8065a2c and b1002d6.

📒 Files selected for processing (1)
  • molecule/default/tasks/eda_test.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • molecule/default/tasks/eda_test.yml

📝 Walkthrough

Walkthrough

The operator adds NetworkPolicies for EDA workloads and managed PostgreSQL. It updates RBAC and Ansible task wiring, supports managed or external databases, conditionally removes the UI policy, and adds Molecule validation.

Changes

NetworkPolicy enforcement

Layer / File(s) Summary
Policy templates and database defaults
roles/eda/defaults/main.yml, roles/eda/templates/*networkpolicy.yaml.j2, roles/postgres/templates/postgres.networkpolicy.yaml.j2
Templates define default-deny and workload policies for EDA and PostgreSQL. The policies configure selectors, ingress sources, DNS access, database access, and external-service egress.
Ansible policy application
roles/eda/tasks/*, roles/postgres/tasks/*
Ansible applies the policies with server-side apply. The UI policy is removed when ui_disabled is enabled. The managed PostgreSQL policy is applied before database resources.
RBAC and integration validation
config/rbac/role.yaml, molecule/default/tasks/eda_test.yml
RBAC separates apps and networking.k8s.io permissions. Molecule checks policy selectors, rules, PostgreSQL targeting, required policies, and conditional UI removal.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EDAAnsibleRole
  participant PostgreSQLRole
  participant KubernetesAPI
  participant EDAWorkloads
  participant PostgreSQLPods
  EDAAnsibleRole->>KubernetesAPI: Apply EDA NetworkPolicies
  KubernetesAPI->>EDAWorkloads: Enforce workload ingress and egress rules
  PostgreSQLRole->>KubernetesAPI: Apply PostgreSQL NetworkPolicy
  KubernetesAPI->>PostgreSQLPods: Enforce database ingress and DNS egress
Loading
sequenceDiagram
  participant Molecule
  participant KubernetesAPI
  participant NetworkPolicies
  Molecule->>KubernetesAPI: Retrieve expected NetworkPolicies
  KubernetesAPI->>NetworkPolicies: Return policy resources
  Molecule->>NetworkPolicies: Validate selectors, rules, and UI presence
Loading

Suggested reviewers: rooftopcellist, kaiokmo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding runtime NetworkPolicies for EDA operator workloads.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/AAP-73976_networkpolicies

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

@ttuffin

ttuffin commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (3)
roles/eda/defaults/main.yml (1)

11-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use one shared source for supported_pg_version.

The EDA NetworkPolicies use this value in five PostgreSQL selectors. A version mismatch can block database egress for four policies; the activation-worker policy also allows unrestricted egress. Move the value to play-level or group_vars data.

🤖 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 `@roles/eda/defaults/main.yml` around lines 11 - 12, Move supported_pg_version
out of roles/eda/defaults/main.yml into shared play-level or group_vars data,
then update the EDA NetworkPolicies and roles/postgres usage to reference that
single shared variable. Remove the duplicated role default while preserving the
current PostgreSQL version value and all five selector references.
roles/eda/tasks/networkpolicy.yml (1)

14-18: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Remove apply: true from the deletion task. ui_disabled has a role default of false. state: absent deletes the NetworkPolicy identified by its metadata name and namespace. apply only affects updates.

🤖 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 `@roles/eda/tasks/networkpolicy.yml` around lines 14 - 18, Remove the apply:
true parameter from the kubernetes.core.k8s task applying the EDA UI
NetworkPolicy, while preserving the existing conditional state based on
ui_disabled and the templated definition.
molecule/default/tasks/eda_test.yml (1)

57-73: 🔒 Security & Privacy | 🔵 Trivial | 🏗️ Heavy lift

Validate workload policy rules, not only resource existence.

This loop accepts any policy with the expected name. It does not validate selectors, policy types, peers, or ports. An empty or overly broad policy can therefore pass while violating least-privilege isolation. Add per-workload assertions for the intended rules.

As per path instructions, this comment addresses a major security validation gap.

🤖 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 `@molecule/default/tasks/eda_test.yml` around lines 57 - 73, Extend the “Verify
per-workload NetworkPolicies exist” task to assert each policy’s intended
selectors, policyTypes, ingress/egress peers, and ports rather than only
checking resources | length. Use workload-specific expected rules for every loop
item, and fail when any policy is empty or broader than the least-privilege
configuration.

Source: Path instructions

🤖 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 `@molecule/default/tasks/eda_test.yml`:
- Around line 67-73: Update the policy-check loop in the EDA test to
conditionally exclude the ui entry when ui_disabled is true, while retaining all
other policy checks. Add an assertion for the ui_disabled path that the UI
policy is absent, and preserve the existing policy-existence assertions when the
UI is enabled.
- Around line 52-54: Update the PostgreSQL NetworkPolicy assertions in the EDA
test to validate the complete database selector, including the PostgreSQL name
and instance labels alongside component=database, and verify the ingress rule’s
protocol is TCP and its port equals eda_postgres_port. Preserve the existing eda
source-selector validation while ensuring an overly broad selector or all-port
rule cannot pass.
- Around line 29-31: Update the default-deny selector assertions to require
operator == 'In' and ensure the values collection contains exactly the expected
deployment_type-derived value, rather than merely containing 'eda-operator'.
Preserve the existing key and single-expression checks in the np_default_deny
assertions.
- Line 20: Define test variables for the EDA resource name (`eda-sample`) and
`supported_pg_version` in eda_test.yml, then update the NetworkPolicy lookups at
molecule/default/tasks/eda_test.yml lines 20, 43, and 62 to use the EDA
resource-name variable instead of namespace-derived names; use the
supported_pg_version variable wherever the PostgreSQL version is referenced.

In `@roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2`:
- Around line 36-65: The unrestricted `- {}` egress rule in the activation
worker policy supersedes the DNS, managed database, and gateway rules. Replace
it with an `ipBlock` rule allowing external destinations while excluding the
cluster and service CIDRs, preserving the existing granular internal egress
rules and the comment explaining user-defined event-source destinations.

In `@roles/eda/templates/eda-api.networkpolicy.yaml.j2`:
- Around line 70-75: Update the external-database egress rule in the network
policy template to include a `to.ipBlock` destination using the configured
database host’s stable CIDR(s), while retaining the existing TCP port selection.
Use the already-available `managed_database` configuration to source the
destination; do not attempt to place a DNS hostname in `ipBlock`, and preserve
the managed-database branch behavior.
- Around line 50-59: Make DNS egress cluster-aware by creating one configurable
partial and reusing it in all seven network policies:
roles/eda/templates/eda-api.networkpolicy.yaml.j2 lines 50-59,
roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2 lines 27-36,
roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2 lines 26-35,
roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2 lines 48-57,
roles/eda/templates/eda-ui.networkpolicy.yaml.j2 lines 47-56,
roles/eda/templates/db-management.networkpolicy.yaml.j2 lines 17-26, and
roles/postgres/templates/postgres.networkpolicy.yaml.j2. Select openshift-dns on
port 5353 for OpenShift and kube-system on port 53 for Kubernetes, and remove
the activation-worker DNS rule where its unrestricted - {} egress rule already
permits traffic.

In `@roles/eda/templates/eda-ui.networkpolicy.yaml.j2`:
- Around line 19-45: Update both ingress port entries in the network policy
template’s router/ingress-controller and gateway-operator rules to use the UI
listener port 8080 instead of api_nginx_port. Leave the UI egress rule using
api_nginx_port for API access.

---

Nitpick comments:
In `@molecule/default/tasks/eda_test.yml`:
- Around line 57-73: Extend the “Verify per-workload NetworkPolicies exist” task
to assert each policy’s intended selectors, policyTypes, ingress/egress peers,
and ports rather than only checking resources | length. Use workload-specific
expected rules for every loop item, and fail when any policy is empty or broader
than the least-privilege configuration.

In `@roles/eda/defaults/main.yml`:
- Around line 11-12: Move supported_pg_version out of
roles/eda/defaults/main.yml into shared play-level or group_vars data, then
update the EDA NetworkPolicies and roles/postgres usage to reference that single
shared variable. Remove the duplicated role default while preserving the current
PostgreSQL version value and all five selector references.

In `@roles/eda/tasks/networkpolicy.yml`:
- Around line 14-18: Remove the apply: true parameter from the
kubernetes.core.k8s task applying the EDA UI NetworkPolicy, while preserving the
existing conditional state based on ui_disabled and the templated definition.
🪄 Autofix

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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: a8a4df3e-76e9-4cbb-8a6c-08f7e64234e4

📥 Commits

Reviewing files that changed from the base of the PR and between 91c0a6f and d38d8cd.

📒 Files selected for processing (15)
  • config/rbac/role.yaml
  • molecule/default/tasks/eda_test.yml
  • roles/eda/defaults/main.yml
  • roles/eda/tasks/main.yml
  • roles/eda/tasks/networkpolicy.yml
  • roles/eda/templates/db-management.networkpolicy.yaml.j2
  • roles/eda/templates/default-deny.networkpolicy.yaml.j2
  • roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2
  • roles/eda/templates/eda-api.networkpolicy.yaml.j2
  • roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2
  • roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2
  • roles/eda/templates/eda-ui.networkpolicy.yaml.j2
  • roles/postgres/tasks/main.yml
  • roles/postgres/tasks/networkpolicy.yml
  • roles/postgres/templates/postgres.networkpolicy.yaml.j2

Comment thread molecule/default/tasks/eda_test.yml Outdated
Comment thread molecule/default/tasks/eda_test.yml Outdated
Comment thread molecule/default/tasks/eda_test.yml
Comment thread molecule/default/tasks/eda_test.yml Outdated
Comment thread roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2 Outdated
Comment thread roles/eda/templates/eda-api.networkpolicy.yaml.j2
Comment thread roles/eda/templates/eda-api.networkpolicy.yaml.j2 Outdated
Comment thread roles/eda/templates/eda-ui.networkpolicy.yaml.j2 Outdated
@ttuffin
ttuffin marked this pull request as ready for review August 10, 2026 17:14
@ttuffin

ttuffin commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Responding to the three nitpick comments from the CodeRabbit review summary:

supported_pg_version in shared vars — The roles/backup/vars/main.yml and roles/restore/vars/main.yml in this repo both define supported_pg_version independently in their own role scope — this is the established pattern. Moving it to play-level group_vars would be a broader refactor across multiple roles and is out of scope for this story. The fix (adding it to roles/eda/defaults/main.yml) follows the same convention already used by the backup and restore roles.

apply: true on the UI absent task — Fixed. Removed apply: true from the UI NP task since it is meaningless when state: absent.

Validate workload policy rules, not only resource existence — Declined per the test plan for AAP-73976 (MR !280), which explicitly delegates rule-level connectivity validation to ATF regression and scopes molecule to existence validation and key selector checks. The app: eda postgres ingress assertion covers the one EDA-specific correctness risk.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
roles/eda/templates/eda-api.networkpolicy.yaml.j2 (1)

62-77: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

An empty - {} egress rule removes all egress isolation and makes the DNS rule dead configuration. In all four policies the - {} rule permits every destination on every port, including the Kubernetes API server, other namespaces, and any in-cluster service. The preceding openshift-dns rule therefore has no effect, and policyTypes: [Egress] no longer restricts anything. A reader can wrongly conclude that these workloads are egress-restricted.

Pick one approach and apply it consistently:

  1. Keep - {} and delete the superseded DNS rule, keeping only the explanatory comment. This is honest but leaves in-cluster egress fully open.
  2. Replace - {} with an ipBlock for 0.0.0.0/0 that has except entries for the cluster pod CIDR and the service CIDR, and keep the granular DNS rule plus explicit rules for postgres and the gateway. This preserves the isolation goal of the PR while still permitting user-defined external destinations.

Approach 2 is preferred for the API and event-stream policies, which have known in-cluster destinations.

  • roles/eda/templates/eda-api.networkpolicy.yaml.j2#L62-L77: replace - {} with a CIDR-scoped external rule and restore explicit postgres and gateway egress rules, or delete the DNS rule at Lines 63-72.
  • roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2#L26-L41: apply the same choice; delete the DNS rule at Lines 27-36 if - {} stays.
  • roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2#L25-L40: apply the same choice; delete the DNS rule at Lines 26-35 if - {} stays.
  • roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2#L47-L63: apply the same choice; delete the DNS rule at Lines 48-57 if - {} stays.
🤖 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 `@roles/eda/templates/eda-api.networkpolicy.yaml.j2` around lines 62 - 77, The
empty egress rule makes the DNS allow rule ineffective and removes all egress
isolation. Prefer the CIDR-scoped external egress approach: in
roles/eda/templates/eda-api.networkpolicy.yaml.j2 lines 62-77,
roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2 lines 26-41,
roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2 lines 25-40, and
roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2 lines 47-63, replace
- {} with an ipBlock for 0.0.0.0/0 excluding the cluster pod and service CIDRs,
retain DNS access, and add explicit postgres and gateway rules where applicable.
Apply the same policy consistently across all four templates.
🤖 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.

Duplicate comments:
In `@roles/eda/templates/eda-api.networkpolicy.yaml.j2`:
- Around line 62-77: The empty egress rule makes the DNS allow rule ineffective
and removes all egress isolation. Prefer the CIDR-scoped external egress
approach: in roles/eda/templates/eda-api.networkpolicy.yaml.j2 lines 62-77,
roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2 lines 26-41,
roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2 lines 25-40, and
roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2 lines 47-63, replace
- {} with an ipBlock for 0.0.0.0/0 excluding the cluster pod and service CIDRs,
retain DNS access, and add explicit postgres and gateway rules where applicable.
Apply the same policy consistently across all four templates.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 74a31ffd-2f96-4329-837b-73c5790f127f

📥 Commits

Reviewing files that changed from the base of the PR and between d38d8cd and 8065a2c.

📒 Files selected for processing (8)
  • molecule/default/tasks/eda_test.yml
  • roles/eda/tasks/networkpolicy.yml
  • roles/eda/templates/eda-activation-worker.networkpolicy.yaml.j2
  • roles/eda/templates/eda-api.networkpolicy.yaml.j2
  • roles/eda/templates/eda-default-worker.networkpolicy.yaml.j2
  • roles/eda/templates/eda-event-stream.networkpolicy.yaml.j2
  • roles/eda/templates/eda-ui.networkpolicy.yaml.j2
  • roles/postgres/templates/postgres.networkpolicy.yaml.j2
💤 Files with no reviewable changes (1)
  • roles/eda/tasks/networkpolicy.yml
🚧 Files skipped from review as they are similar to previous changes (3)
  • roles/eda/templates/eda-ui.networkpolicy.yaml.j2
  • molecule/default/tasks/eda_test.yml
  • roles/postgres/templates/postgres.networkpolicy.yaml.j2

@sonarqubecloud

Copy link
Copy Markdown


- name: Apply EDA UI NetworkPolicy
kubernetes.core.k8s:
state: "{{ 'present' if not ui_disabled else 'absent' }}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should we also add an apply here for consistency? it doesn't necessarily change anything, and state does the job correctly... but still, we're doing it for every other resource, so... I think we should put it here as well:

Suggested change
state: "{{ 'present' if not ui_disabled else 'absent' }}"
state: "{{ 'present' if not ui_disabled else 'absent' }}"
apply: "{{ omit if ui_disabled else true }}"

ui_disabled: false

# Keep in sync with roles/postgres/vars/main.yml
supported_pg_version: 15

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is OK for now, but we could accidentally drift in case the postgres role changes its value. Why don't we load this value from the postgres role instead? We could include_vars before calling calling Apply PostgreSQL NetworkPolicy. WDYT?

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.

2 participants