Skip to content

feat(tenant): allow egress to vlinsert in parent tenants - #3439

Closed
IvanHunters wants to merge 2 commits into
mainfrom
feat/tenant-egress-vlinsert
Closed

IvanHunters wants to merge 2 commits into
mainfrom
feat/tenant-egress-vlinsert

Conversation

@IvanHunters

@IvanHunters IvanHunters commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Tenant egress CiliumClusterwideNetworkPolicy already permits child tenants to reach vminsert (VictoriaMetrics ingest) and etcd and ingress controllers in any ancestor namespace. vlinsert (VictoriaLogs ingest) was missing — so a child tenant that runs its own monitoring-agents cannot forward container logs to a parent tenant's VictoriaLogs.

Mirrors the existing vminsert block.

Problem statement

In a chain tenant-root → tenant-a → tenant-a-b, the tenant-a-b tenant's fluent-bit (deployed via monitoring-agents) tries to POST to vlinsert-generic.tenant-a.svc:9481 (parent's VictoriaLogs). The current tenant-a-b-egress CCNP only allows egress to ancestor namespaces for vminsert / etcd / ingress-labelled endpoints. Connections to vlinsert are dropped at L4 by Cilium.

Observable as no upstream connections available errors in fluent-bit, with no visible drops anywhere downstream — the dropped packets never leave the source node.

Change

Add a third toEndpoints block matching app.kubernetes.io/name: vlinsert in any ancestor namespace, identical in structure to the existing vminsert block.

Test plan

  • helm template packages/apps/tenant for a child tenant — verify the new block appears.
  • Real-world: deploy a kubernetes app inside a tenant with addons.monitoringAgents.enabled: true; verify fluent-bit logs reach the parent tenant's VictoriaLogs without manual CCNP additions.

Notes

The same splitList "-" pattern is used as in the surrounding blocks, which assumes the parent name encodes the full hierarchy via dashes — that ancestor-walk bug is tracked separately in #2810 / #2171 and is intentionally not touched here to keep this PR minimal.

Release note

feat(tenant): allow child tenants running monitoring-agents to forward container logs to a parent tenant's VictoriaLogs (vlinsert) without manual CiliumClusterwideNetworkPolicy edits

Summary by CodeRabbit

  • Bug Fixes
    • Updated tenant network policy egress rules to correctly match tenant-scoped insert pods in ancestor-tenant scenarios.
    • Improved targeting of insert pods for non-root tenant environments to keep expected connectivity behavior consistent.

Tenant egress CCNP already permits child tenants to reach vminsert
(VictoriaMetrics ingest) in any ancestor namespace, but vlinsert
(VictoriaLogs ingest) was missing. Without it, fluent-bit / vector
deployed via monitoring-agents in a child tenant cannot forward logs
to a parent tenant's VictoriaLogs.

Mirror the existing vminsert block.

Signed-off-by: IvanHunters <[email protected]>
@github-actions github-actions Bot added size/S This PR changes 10-29 lines, ignoring generated files area/tenant Issues or PRs related to the tenant chart and multi-tenancy kind/feature Categorizes issue or PR as related to a new feature labels Jul 23, 2026
@dosubot dosubot Bot added the area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) label Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: de3acd58-270c-4e10-9433-a47b79f963f5

📥 Commits

Reviewing files that changed from the base of the PR and between 338b89c and 35a61e6.

📒 Files selected for processing (1)
  • packages/apps/tenant/tests/networkpolicy_egress_test.yaml

📝 Walkthrough

Walkthrough

The tenant network policy template changes non-tenant-root egress matching to select vlinsert pods in derived tenant namespaces. Helm tests cover child-tenant ancestor ingest rules and root-tenant exclusion.

Changes

Tenant egress policy

Layer / File(s) Summary
Update tenant endpoint selector
packages/apps/tenant/templates/networkpolicy.yaml
Non-tenant-root tenant egress targets vlinsert pods using derived namespace and application labels.
Validate ancestor ingest egress
packages/apps/tenant/tests/networkpolicy_egress_test.yaml
Tests verify child tenants receive parent vlinsert and vminsert endpoint rules, while tenant-root receives neither ancestor block and has one egress rule.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: kvaps

🚥 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 is concise and accurately summarizes the main change: allowing tenant egress to parent-tenant vlinsert endpoints.
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/tenant-egress-vlinsert

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
packages/apps/tenant/tests/networkpolicy_egress_test.yaml

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

NOT LGTM — the change is correct and I verified it renders and targets the right endpoint, but it modifies a template in a chart that gates on tests and ships no test for the new rule.

Business context: the tenant egress CiliumClusterwideNetworkPolicy already lets a child tenant reach vminsert, etcd, and ingress controllers in ancestor namespaces; this PR adds the missing vlinsert (VictoriaLogs insert) allowance so a child tenant running monitoring-agents can forward container logs to a parent tenant's VictoriaLogs without hand-editing the policy.

Verified correct

The new toEndpoints block is a verbatim structural mirror of the existing vminsert block, changing only the matched selector value. I confirmed the surrounding facts rather than taking them on faith:

  • Selector is right: vlinsert pods are labeled app.kubernetes.io/name: vlinsert (cross-checked against packages/extra/monitoring/templates/workloadmonitors.yaml and packages/system/monitoring/templates/vm/vmcluster-scrape.yaml), matching the block's k8s:app.kubernetes.io/name: vlinsert. This is the same convention as vminsert, and correctly distinct from etcd, which is matched by app.kubernetes.io/instance.
  • It renders: helm template of templates/networkpolicy.yaml for a depth-2 child (tenant-htdev in namespace tenant-ktj) emits the vlinsert block parallel to vminsert, scoped to the parent namespace tenant-ktj; the ne (include "tenant.name" .) "tenant-root" guard correctly suppresses it for the root tenant.
  • It is purely additive: CiliumClusterwideNetworkPolicy egress is allow-only, so appending a toEndpoints block only widens egress and cannot tighten the baseline; existing rules are untouched (the only other change is a trailing-whitespace cleanup on the preceding {{- end }}).
  • Scope is correct: egress is limited to pods matching both app.kubernetes.io/name: vlinsert and an ancestor namespace, so it is not a general child→parent hole. The ancestor-walk limitation the PR calls out is genuinely pre-existing and mirrored identically from vminsert, so it introduces no new bug and is correctly left out of scope.

Blockers

B1 — no test for the new egress rule (blocking)

packages/apps/tenant/ is a tested chart: it has a tests/ directory with five helm unittest suites and a make test target (helm unittest .). Under this repo's convention, a change to a template in a chart that already has a test harness needs a test, and this change ships none. This is a network egress rule — a security boundary — which is exactly the kind of behavior that should be pinned so it cannot silently regress. Testing here is also cheap and has direct precedent: the sibling suite tests/namespace_ancestor_labels_test.yaml already renders the same helper-driven ancestor logic offline, and its header comment names this very <tenant>-egress policy as the consumer of those labels.

Please add a suite targeting templates/networkpolicy.yaml that covers the full contract, not just the happy path:

  1. For a child tenant (e.g. release tenant-htdev in namespace tenant-ktj), assert the egress list contains a toEndpoints entry matching k8s:app.kubernetes.io/name: vlinsert and k8s:io.kubernetes.pod.namespace: tenant-ktj.
  2. For a tenant-root release, assert no vlinsert block is emitted, pinning the root-tenant guard.

Since this PR touches the template, it owns its coverage: fold a matching vminsert assertion into the same suite while you are here rather than leaving it as a separate follow-up.

Non-blocking follow-ups

  1. (non-blocking) The PR description points at #2810 and #2171 as separately tracking the ancestor-walk limitation, but both issues are closed — so the "tracked separately" framing currently references nothing open. If that limitation still stands (the walk recovers only the immediate parent, not grandparents), it is worth tracking against an open issue.

The <tenant>-egress CiliumClusterwideNetworkPolicy opens child-tenant
egress to vminsert/vlinsert/etcd/ingress in ancestor namespaces. These
are allow rules on a clusterwide policy and act as a security boundary,
so a silent template regression would quietly cut a child tenant's
metric or log delivery.

Add a helm-unittest suite for templates/networkpolicy.yaml covering the
full contract: a depth-2 child tenant's egress must contain both the
vlinsert and vminsert toEndpoints blocks scoped to the parent namespace,
and the root tenant must emit no ancestor ingest block (guard pinned by
notContains plus an exact egress-length assertion).

Signed-off-by: IvanHunters <[email protected]>
@github-actions github-actions Bot added size/M This PR changes 30-99 lines, ignoring generated files and removed size/S This PR changes 10-29 lines, ignoring generated files labels Jul 23, 2026
@github-actions

Copy link
Copy Markdown

This PR has had no activity for 60 days and was marked lifecycle/stale.
It will be closed in 14 days unless commented or labelled lifecycle/frozen.

@github-actions github-actions Bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale label Sep 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IvanHunters NOT LGTM, but only because of the PR description. Sorry this re-review took two months. The test I asked for is in and it works, so the code side is done. What's left is the body: it goes into the merge commit as written, and a few lines in it don't match the diff.

The new test catches every break I tried. I changed the template in a scratch copy and ran the suite after each change. Renaming vlinsert, switching its selector key to app.kubernetes.io/instance, dropping its namespace label, pointing it at the tenant's own namespace, or deleting the block all fail "child tenant egress allows vlinsert and vminsert in the parent namespace". Renaming vminsert fails the same test on its second assert. Removing the root guard from the new block fails "root tenant egress emits no ancestor ingest blocks", on both the notContains and the lengthEqual.

Current main doesn't change anything here. The branch merges without conflicts, and nothing merged since July touched the ancestor blocks around the new one. On the merged tree the tenant suite passes, 12 suites and 48 tests. I rendered the chart from main and from the merged tree for a direct child of root, a depth-2 tenant and a depth-3 tenant, and compared every object. The only difference is one new entry in <tenant>-egress: pods labelled app.kubernetes.io/name: vlinsert in the ancestor namespaces, on any port, same shape as vminsert. For tenant-a-b-c those are tenant-a and tenant-a-b. The root tenant renders identically. The CI on this head ran on 2026-07-23 against a July base, so it doesn't cover current main.

The body needs four fixes before merge:

  1. It says "Add a third toEndpoints block". The policy already had three ancestor blocks (vminsert, etcd, ingress), so this is the fourth.
  2. The CodeRabbit summary at the bottom puts the change under "Bug Fixes" and says the rules now "correctly match tenant-scoped insert pods". Nothing was mismatched before, this is a new allowance. It also adds a vendor-named section to the commit. Please delete that block. Editing the description is enough, the bot writes it back on a push, not on an edit.
  3. The Summary says the rules cover "any ancestor namespace", and the Notes say the gap is tracked in #2810 and #2171. Both issues were closed on 2026-07-03. Below the first level, the walk reaches every ancestor except tenant-root, because a first-level tenant's namespace name doesn't contain root. So tenant-a-b can't reach a vlinsert in tenant-root, even when root is the nearest tenant running monitoring. My last review called this "only the immediate parent", which was wrong for depth 3 and deeper. Please describe the gap this way and link an open issue, or say it's untracked.
  4. The test plan doesn't mention the new unit suite, and the real-world item is still unchecked. Please say whether that run happened.

Not blocking: the child test checks that both blocks exist, but not that nothing else was added. When I added - toEndpoints: [{}] for non-root tenants, which opens egress to every endpoint in the cluster, both tests still passed. A lengthEqual with count: 5 on the child's spec.egress, like the one in the root case, would catch that.

@lexfrei

Copy link
Copy Markdown
Contributor

IvanHunters the code is done, the review from 2026-09-22 has no open points on it. Only the PR body does not match the diff yet. Can you update it?

@IvanHunters

Copy link
Copy Markdown
Collaborator Author

Superseded by #5257, which adds the vlinsert egress as part of a single owner-targeted rule that also fixes the namespace-prefix walk (never reaches tenant-root from below the first level, see #4726). Closing in favor of #5257.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) area/tenant Issues or PRs related to the tenant chart and multi-tenancy kind/feature Categorizes issue or PR as related to a new feature size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants