Skip to content

Commit 5566538

Browse files
feat(netpol): ODCN router-pod selector ipv namespace-naam
Per ODCN docs (docs/knowledge/odcn-ingress-controller.md): de aanbevolen NetworkPolicy match is pod-selector op ingresscontroller.operator.openshift.io/deployment-ingresscontroller naast namespaceSelector. Daarmee alleen de 'rig' router-pods, niet eventuele andere customer-routers in dezelfde namespace. cluster_config heeft nu ingress_controller_selector (dict met namespace + pod_labels). Sandbox/local laten pod_labels leeg (nginx geen OpenShift- specifieke labels). Plus: test_internet_egress_is_permissive — geen 169.254 exception meer (eerder verwijderd want IP is op ODCN niet bereikbaar).
1 parent c3e8aef commit 5566538

3 files changed

Lines changed: 46 additions & 22 deletions

File tree

operations-manager/python/manifests/tenant-baseline-network-policy.yaml.jinja

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,19 @@ spec:
3838
- podSelector: {}
3939
{% endif %}
4040
# Ingress controller: published web apps stay reachable from outside.
41+
# Op odcn matchen we pod-specifiek (alleen 'rig' router pods, niet
42+
# eventuele andere customer-routers in dezelfde namespace).
4143
- from:
4244
- namespaceSelector:
4345
matchLabels:
44-
kubernetes.io/metadata.name: "{{ ingress_controller_namespace }}"
46+
kubernetes.io/metadata.name: "{{ ingress_controller_selector.namespace }}"
47+
{% if ingress_controller_selector.pod_labels %}
48+
podSelector:
49+
matchLabels:
50+
{% for k, v in ingress_controller_selector.pod_labels.items() %}
51+
{{ k }}: "{{ v }}"
52+
{% endfor %}
53+
{% endif %}
4554
# Operations / platform namespace (OPI, shared datastores, Keycloak).
4655
- from:
4756
- namespaceSelector:

operations-manager/python/opi/core/cluster_config.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
"minio_port": 9000,
2121
"redis_server": "rig-redis.rig-system.svc.cluster.local",
2222
"backup_namespace": "rig-backup-destination",
23-
"ingress_controller_namespace": "ingress-nginx",
23+
"ingress_controller_selector": {
24+
"namespace": "ingress-nginx",
25+
"pod_labels": {},
26+
},
2427
"ingress": {
2528
"enable_tls": True,
2629
"cluster_issuer": "kind-ca-issuer",
@@ -69,7 +72,10 @@
6972
"minio_port": 9000,
7073
"redis_server": "rig-redis.rig-system.svc.cluster.local",
7174
"backup_namespace": "rig-backup-destination",
72-
"ingress_controller_namespace": "ingress-nginx",
75+
"ingress_controller_selector": {
76+
"namespace": "ingress-nginx",
77+
"pod_labels": {},
78+
},
7379
"ingress": {
7480
"enable_tls": True,
7581
"ip_whitelist": "0.0.0.0/0,::/0",
@@ -112,7 +118,12 @@
112118
"minio_port": 9000,
113119
"redis_server": "rig-redis.rig-prd-operations.svc.cluster.local",
114120
"backup_namespace": "rig-prd-backup",
115-
"ingress_controller_namespace": "openshift-ingress",
121+
"ingress_controller_selector": {
122+
"namespace": "openshift-ingress",
123+
"pod_labels": {
124+
"ingresscontroller.operator.openshift.io/deployment-ingresscontroller": "rig",
125+
},
126+
},
116127
"ingress": {
117128
"enable_tls": True,
118129
# "cluster_issuer": "letsencrypt-production", # TODO: verify correct issuer name
@@ -543,22 +554,21 @@ def get_backup_namespace(cluster_name: str) -> str:
543554
return cluster_config["backup_namespace"]
544555

545556

546-
def get_ingress_controller_namespace(cluster_name: str) -> str:
557+
def get_ingress_controller_selector(cluster_name: str) -> dict:
547558
"""
548-
Get the namespace where the cluster's ingress controller pods run.
559+
Return de selector voor de ingress-controller pods van een cluster.
549560
550-
On local/sandbox this is ``ingress-nginx``; on odcn-production it is
551-
``openshift-ingress``. NetworkPolicies use this to allow ingress from
552-
the controller so published web apps stay reachable.
561+
Format::
553562
554-
Args:
555-
cluster_name: Name of the cluster
563+
{"namespace": "<ns>", "pod_labels": {<key>: <val>, ...}}
556564
557-
Returns:
558-
Ingress controller namespace name
565+
pod_labels is leeg voor nginx-clusters; voor odcn (OpenShift Router) bevat
566+
het de ``ingresscontroller.operator.openshift.io/deployment-ingresscontroller``
567+
label zodat NetworkPolicy alleen de juiste customer-router toelaat.
568+
Zie docs/knowledge/odcn-ingress-controller.md.
559569
"""
560570
cluster_config = get_cluster_config(cluster_name)
561-
return cluster_config["ingress_controller_namespace"]
571+
return cluster_config["ingress_controller_selector"]
562572

563573

564574
def get_redis_server(cluster_name: str) -> str:

operations-manager/python/tests/test_tenant_baseline_netpol.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ def _render_baseline(**overrides):
3737
"deployment_selector": "myapp",
3838
"ops_namespace": "rig-system",
3939
"backup_namespace": "rig-backup-destination",
40-
"ingress_controller_namespace": "ingress-nginx",
40+
"ingress_controller_selector": {
41+
"namespace": "ingress-nginx",
42+
"pod_labels": {},
43+
},
4144
"project_infra_namespace": "rig-myproject-infrastructure",
4245
}
4346
values.update(overrides)
@@ -159,7 +162,12 @@ def test_platform_namespaces_are_allow_listed(self):
159162
_, doc = _render_baseline(
160163
ops_namespace="rig-prd-operations",
161164
backup_namespace="rig-prd-backup",
162-
ingress_controller_namespace="openshift-ingress",
165+
ingress_controller_selector={
166+
"namespace": "openshift-ingress",
167+
"pod_labels": {
168+
"ingresscontroller.operator.openshift.io/deployment-ingresscontroller": "rig",
169+
},
170+
},
163171
)
164172
ingress_targets = {
165173
peer["namespaceSelector"]["matchLabels"]["kubernetes.io/metadata.name"]
@@ -176,10 +184,9 @@ def test_platform_namespaces_are_allow_listed(self):
176184
assert {"rig-prd-operations", "openshift-ingress", "rig-prd-backup"} <= ingress_targets
177185
assert {"rig-prd-operations", "rig-prd-backup"} <= egress_targets
178186

179-
def test_internet_egress_is_permissive_except_metadata(self):
180-
"""The baseline does not constrain internet egress (HTTP/HTTPS) on
181-
purpose — tightening that is a separate, later step. The cloud-metadata
182-
IP (169.254.169.254) is excluded to block SSRF-style probes.
187+
def test_internet_egress_is_permissive(self):
188+
"""De baseline laat HTTP/HTTPS egress open zodat tenant-apps externe
189+
APIs kunnen aanroepen. Strikter beleid is een latere stap.
183190
"""
184191
_, doc = _render_baseline()
185192
ip_rules = [
@@ -189,8 +196,6 @@ def test_internet_egress_is_permissive_except_metadata(self):
189196
flat_ports = {p["port"] for rule in ip_rules for p in rule.get("ports", [])}
190197
assert 443 in flat_ports
191198
assert 80 in flat_ports
192-
excepts = {x for rule in ip_rules for peer in rule["to"] for x in peer.get("ipBlock", {}).get("except", [])}
193-
assert "169.254.169.254/32" in excepts, "cloud-metadata IP must be excluded from the internet egress rule"
194199

195200
def test_project_infra_namespace_included_when_distinct(self):
196201
"""When the project has its own infrastructure namespace (dedicated

0 commit comments

Comments
 (0)