CMP-4569: Create operand NetworkPolicies at runtime - #1364
CMP-4569: Create operand NetworkPolicies at runtime#1364abushkin-redhat wants to merge 3 commits into
Conversation
|
@abushkin-redhat: This pull request references CMP-4569 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.1.0" version, but no target version was set. DetailsIn response to this:
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. |
|
🤖 To deploy this PR, run the following command: |
yuumasato
left a comment
There was a problem hiding this comment.
@abushkin-redhat Looking good. Just one small comment.
Also, please sign the commits so the PR is mergeable.
The operator now creates and reconciles label-scoped NetworkPolicies for its operand pods (result server, scanners, aggregator, profileparser, rerunner) so operand traffic is governed at runtime rather than left unrestricted. - Add the compliance.openshift.io/netpol-managed marker to every operand pod template (pod template only for the result-server and profileparser Deployments, to avoid mutating their immutable selectors). - Create three named policies in the operator namespace via get-or-create/update (no list/watch, matching the RBAC granted for CMP-4496): default-deny (ingress+egress), allow-all-egress, and result-server ingress on 8443 from pod-network scanners and host-networked node scanners. - Reconcile the policies at the start of the scan launching phase, before any operand pods are created. - Read NetworkPolicy directly from the API server (manager client cache DisableFor) so a by-name Get does not start an informer list+watch, which the operand RBAC does not grant. Depends on ComplianceAsCode#1313 (CMP-4496) for the NetworkPolicy RBAC.
4237b3a to
fceeb32
Compare
|
New changes are detected. LGTM label has been removed. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: abushkin-redhat The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
1 similar comment
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: abushkin-redhat The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
The CMP-4569 commit is signed, just the two commits from PR #1313 are unsigned, but my plan there was to wait for that PR to be merged, and then rebase this one. |
|
🤖 To deploy this PR, run the following command: |
|
@abushkin-redhat: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |
|
@abushkin-redhat Hi, this can be rebased now, #1313 is merged. |
CMP-4569: Create operand NetworkPolicies at runtime
What
Per HPSTRAT-104, layered operators must create NetworkPolicies for their operand pods.
This is the operand half of that work for the Compliance Operator (the RBAC half is #1313).
The operator now creates and reconciles label-scoped NetworkPolicies for all of its
operand pods, so operand traffic is governed at runtime instead of being unrestricted.
compliance.openshift.io/netpol-managed: ""to every operandpod template: node scanner, platform scanner, aggregator, result server, profileparser,
and the suite rerunner CronJob.
to the pod template only, never to the Deployment/Service selector, since a
Deployment's
spec.selectoris immutable after creation.ComplianceScan controller (
pkg/controller/compliancescan/networkpolicy.go):compliance-operator-operands-default-deny— selects operand pods; denies all ingressand egress (baseline).
compliance-operator-operands-allow-egress— allows all egress from operand pods.compliance-operator-resultserver-allow-ingress— allows ingress to the result serveron
8443/TCPfrom pod-network scanners (workload=scannerpodSelector) and fromhost-networked node scanners (the OVN
policy-group.network.openshift.io/host-networknamespaceSelector).
pod is created, so operands start with their network access already governed. Reconcile
is get-then-create/update (idempotent), with no
ListorWatch— matching the RBACgranted in CMP-4496: Add NetworkPolicy RBAC for operands to operator Role and CSV #1313.
NetworkPolicydirectly from the API server (manager clientCache.DisableFor: NetworkPolicy); see Cache bypass below.workloadoperand label key/values as constants (config.go) so thepolicy selectors stay in sync with the pod templates.
coverage-baseline.txt(the new tests raise coverage;make build/test-unitgates on the baseline).
Why
Operand pods (scanners, result server, aggregator, profileparser, rerunner) previously ran
with no NetworkPolicy, so all ingress/egress was allowed. HPSTRAT-104 requires operators to
manage NetworkPolicies for their operands dynamically at runtime (not via the OLM bundle
manifest). This PR provides that: a default-deny baseline plus the minimal allow rules the
operands actually need.
Cache bypass (why NetworkPolicy is read uncached)
controller-runtime's default client is cache-backed: a
Getfor a type the cache has notseen lazily starts an informer, which performs a
list+watch. The operand RBAC(#1313) intentionally grants only
get/create/update/delete— notlist/watch.Without intervention, the first
Getof a NetworkPolicy starts an informer that fails withnetworkpolicies ... is forbidden: cannot list, the reconcile errors, and scans hang inLAUNCHING. The manager is therefore configured with:so NetworkPolicy reads go straight to the API server (
getonly; writes already bypass thecache). This keeps the RBAC least-privilege (no
list/watch) and requires no informer.Behavior notes (intended, worth knowing)
fails (e.g., an admission/validating webhook rejects a NetworkPolicy, an API error, or a
networkpolicies quota), the scan stays in
LAUNCHINGand requeues rather than launchingoperands ungoverned. Previously the scan path had no dependency on NetworkPolicy.
first time a scan enters
LAUNCHING. There is no controllerWatch/OwnsonNetworkPolicy (by design — no
list/watchRBAC), so out-of-band deletion or edits arere-asserted on the next scan launch, not continuously.
every scan's launching phase (idempotent; a few extra GETs).
and scanners make arbitrary external egress (
oscap --fetch-remote-resourcesunlessNoExternalResources). With a single operand bucket, the shared egress policy mustaccommodate the scanner, so egress is open; the enforced hardening here is on ingress.
compliance.openshift.io/netpol-managed="".reads NetworkPolicy via the manager client, and the CEL/
api-resource-collectorcontentpath is a separate binary/ServiceAccount and is unaffected.
Known limitations / follow-ups
Deployment is long-lived and
workloadNeedsUpdatecompares images/commands, not labels,so on operator upgrade an existing profileparser Deployment is not recreated solely to
gain the marker — it stays outside default-deny (i.e., today's allow-all behavior) until a
content/image change triggers a redeploy. The per-scan/per-suite operands (scanners,
result server, aggregator, rerunner) pick up the marker on the next scan.
reflect.DeepEqualon.Spec. If the API server ever defaultsa NetworkPolicy field we don't set identically, reconcile could issue a redundant
Updateeach pass. All spec fields we care about are set explicitly and no such churn was observed
on-cluster; a follow-up could narrow the comparison to owned fields if it ever appears.
the result server over the network on 8443 (rather than via the results PVC) would be
denied.
oc compliance fetch-rawreads the PVC via an extractor pod, so it is unaffected.Test plan
Unit (local; in-memory fake client, no cluster/envtest)
Covers: policy builders (selectors, policy types, allow-all-egress shape, result-server
ingress port 8443 and both
frompeers);reconcileNetworkPoliciescreate / idempotent /drift-correction (get/create/update only); and that every operand pod template carries the
marker while the result-server and profileparser Deployment selectors do not.
E2E (requires OCP on OVN-Kubernetes)
tests/e2e/deployment/networkpolicy_test.go→TestOperandNetworkPoliciesAreReconciled:runs a node ComplianceScan (host-networked scanner → result server on 8443, the critical
ingress path), waits for
DONE, then asserts all three policies exist, default-deny selectsoperands with no allow rules, and the result-server ingress opens 8443.
Verified on ClusterBot
openshift-e2e-aws 4.22(RHEL-10, TechPreviewNoUpgrade, OVN):the scan progressed
RUNNING → AGGREGATING → DONEwith policies in place, and allassertions passed (
--- PASS: TestOperandNetworkPoliciesAreReconciled).Optional manual confirmation: