Skip to content

Commit 36b316d

Browse files
committed
add NetworkPolicy support to operator installation
Apply three default NetworkPolicies to every operator namespace (except openshift-operators): allow intra-namespace traffic, allow ingress from cluster nodes for admission webhook access, and allow ingress from the OpenShift monitoring stack. Operators can opt out of all default policies via the new disableDefaultNetworkPolicies flag, and opt in to additional cross-namespace ingress policies via allowIngressFrom (a list of name/namespaceSelector pairs). The schema forbids combining allowIngressFrom with disableDefaultNetworkPolicies: true, since disabling defaults while selectively re-allowing traffic is semantically inconsistent. Operators with exposed routes (quay-operator, ACM, cincinnati, pipelines, ODF, LVMS) are configured with allowIngressFrom for the OpenShift ingress namespace. MCE and ACM are configured with bidirectional allowIngressFrom to preserve east-west traffic between the two operators that collaborate at runtime. cert-manager and openshift-gitops require policies in secondary namespaces (cert-manager and openshift-gitops) that are created by the operators themselves rather than by the generic installation task; these are handled in each operator's own tasks.yaml. The kube-apiserver NetworkPolicy uses ipBlock with machineNetwork rather than a namespaceSelector for openshift-kube-apiserver. kube-apiserver pods run with hostNetwork: true in OpenShift, meaning their traffic originates from node IPs rather than pod-network addresses. A namespaceSelector only matches pod-network traffic, so it silently failed to allow webhook calls, leaving the implicit deny in place and causing context deadline exceeded errors when creating resources with admission webhooks (observed with the OCM webhook at ocm-webhook.multicluster-engine.svc:443). Using ipBlock with machineNetwork correctly covers all cluster nodes including the control plane. Signed-off-by: Rafa Porres Molina <rporresm@redhat.com> Assisted-by: Claude <noreply@anthropic.com>
1 parent 8f5a0ec commit 36b316d

6 files changed

Lines changed: 340 additions & 2 deletions

File tree

defaults/operators.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,39 @@ operators:
77
init_version: 3.15.0
88
namespace: quay-enterprise
99
source: cs-redhat-operator-index-v4-20
10+
allowIngressFrom:
11+
- name: ingress
12+
namespaceSelector:
13+
matchLabels:
14+
network.openshift.io/policy-group: ingress
1015

1116
- name: multicluster-engine
1217
version: 2.10.1
1318
channel: stable-2.10
1419
init_version: 2.10.0
1520
namespace: multicluster-engine
1621
source: cs-redhat-operator-index-v4-20
22+
allowIngressFrom:
23+
- name: acm
24+
namespaceSelector:
25+
matchLabels:
26+
kubernetes.io/metadata.name: open-cluster-management
1727

1828
- name: advanced-cluster-management
1929
version: 2.15.1
2030
channel: release-2.15
2131
init_version: 2.15.0
2232
namespace: open-cluster-management
2333
source: cs-redhat-operator-index-v4-20
34+
allowIngressFrom:
35+
- name: ingress
36+
namespaceSelector:
37+
matchLabels:
38+
network.openshift.io/policy-group: ingress
39+
- name: mce
40+
namespaceSelector:
41+
matchLabels:
42+
kubernetes.io/metadata.name: multicluster-engine
2443

2544
- name: cincinnati-operator
2645
version: 5.0.3
@@ -30,6 +49,11 @@ operators:
3049
source: cs-redhat-operator-index-v4-20
3150
csvNames:
3251
- update-service-operator
52+
allowIngressFrom:
53+
- name: ingress
54+
namespaceSelector:
55+
matchLabels:
56+
network.openshift.io/policy-group: ingress
3357

3458
- name: openshift-gitops-operator
3559
version: 1.19.2
@@ -46,6 +70,11 @@ operators:
4670
namespace: openshift-pipelines
4771
source: cs-redhat-operator-index-v4-20
4872
global: true
73+
allowIngressFrom:
74+
- name: ingress
75+
namespaceSelector:
76+
matchLabels:
77+
network.openshift.io/policy-group: ingress
4978

5079
- name: netobserv-operator
5180
version: 1.11.0

defaults/storage_operators.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
storage_operators: # Install operator depending blockStorageBackend variable
2+
odf:
3+
- name: odf-operator
4+
version: 4.20.7-rhodf
5+
channel: stable-4.20
6+
init_version: 4.20.7-rhodf
7+
namespace: openshift-storage
8+
source: cs-redhat-operator-index-v4-20
9+
csvNames:
10+
- odf-operator
11+
- odf-dependencies
12+
- odf-csi-addons-operator
13+
- rook-ceph-operator
14+
- ocs-operator
15+
- recipe
16+
- mcg-operator
17+
- odf-prometheus-operator
18+
- ocs-client-operator
19+
- cephcsi-operator
20+
- odf-external-snapshotter-operator
21+
csvMirror: true
22+
extraMirrorPackages:
23+
- odr-cluster-operator
24+
- odr-hub-operator
25+
allowIngressFrom:
26+
- name: ingress
27+
namespaceSelector:
28+
matchLabels:
29+
network.openshift.io/policy-group: ingress
30+
lvms:
31+
- name: lvms-operator
32+
version: 4.20.0
33+
channel: stable-4.20
34+
init_version: 4.20.0
35+
namespace: openshift-storage
36+
source: cs-redhat-operator-index-v4-20
37+
allowIngressFrom:
38+
- name: ingress
39+
namespaceSelector:
40+
matchLabels:
41+
network.openshift.io/policy-group: ingress

operators/openshift-cert-manager-operator/tasks.yaml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,58 @@
11
---
2+
- name: "Ensure same-namespace NetworkPolicy exists in cert-manager"
3+
kubernetes.core.k8s:
4+
state: present
5+
definition:
6+
apiVersion: networking.k8s.io/v1
7+
kind: NetworkPolicy
8+
metadata:
9+
name: allow-from-same-namespace
10+
namespace: cert-manager
11+
spec:
12+
podSelector: {}
13+
ingress:
14+
- from:
15+
- podSelector: {}
16+
policyTypes:
17+
- Ingress
18+
19+
- name: "Ensure monitoring can reach cert-manager"
20+
kubernetes.core.k8s:
21+
state: present
22+
definition:
23+
apiVersion: networking.k8s.io/v1
24+
kind: NetworkPolicy
25+
metadata:
26+
name: allow-ingress-from-monitoring
27+
namespace: cert-manager
28+
spec:
29+
podSelector: {}
30+
ingress:
31+
- from:
32+
- namespaceSelector:
33+
matchLabels:
34+
network.openshift.io/policy-group: monitoring
35+
policyTypes:
36+
- Ingress
37+
38+
- name: "Ensure kube-apiserver can reach cert-manager webhook"
39+
kubernetes.core.k8s:
40+
state: present
41+
definition:
42+
apiVersion: networking.k8s.io/v1
43+
kind: NetworkPolicy
44+
metadata:
45+
name: allow-ingress-from-kube-apiserver
46+
namespace: cert-manager
47+
spec:
48+
podSelector: {}
49+
ingress:
50+
- from:
51+
- ipBlock:
52+
cidr: "{{ machineNetwork }}"
53+
policyTypes:
54+
- Ingress
55+
256
- name: Patch CertManager to set resources
357
kubernetes.core.k8s:
458
state: patched
Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,77 @@
11
---
2-
- ansible.builtin.debug:
3-
msg: "Operator configured properly, no further actions"
2+
# The gitops operator creates the openshift-gitops namespace where ArgoCD
3+
# components run. NetworkPolicies must be applied here separately since
4+
# configure_operator.yaml only manages the operator namespace
5+
# (openshift-gitops-operator).
6+
- name: "Ensure same-namespace NetworkPolicy exists in openshift-gitops"
7+
kubernetes.core.k8s:
8+
state: present
9+
definition:
10+
apiVersion: networking.k8s.io/v1
11+
kind: NetworkPolicy
12+
metadata:
13+
name: allow-from-same-namespace
14+
namespace: openshift-gitops
15+
spec:
16+
podSelector: {}
17+
ingress:
18+
- from:
19+
- podSelector: {}
20+
policyTypes:
21+
- Ingress
22+
23+
- name: "Ensure kube-apiserver can reach openshift-gitops webhooks"
24+
kubernetes.core.k8s:
25+
state: present
26+
definition:
27+
apiVersion: networking.k8s.io/v1
28+
kind: NetworkPolicy
29+
metadata:
30+
name: allow-ingress-from-kube-apiserver
31+
namespace: openshift-gitops
32+
spec:
33+
podSelector: {}
34+
ingress:
35+
- from:
36+
- ipBlock:
37+
cidr: "{{ machineNetwork }}"
38+
policyTypes:
39+
- Ingress
40+
41+
- name: "Ensure monitoring can reach openshift-gitops"
42+
kubernetes.core.k8s:
43+
state: present
44+
definition:
45+
apiVersion: networking.k8s.io/v1
46+
kind: NetworkPolicy
47+
metadata:
48+
name: allow-ingress-from-monitoring
49+
namespace: openshift-gitops
50+
spec:
51+
podSelector: {}
52+
ingress:
53+
- from:
54+
- namespaceSelector:
55+
matchLabels:
56+
network.openshift.io/policy-group: monitoring
57+
policyTypes:
58+
- Ingress
59+
60+
- name: "Ensure ingress can reach openshift-gitops"
61+
kubernetes.core.k8s:
62+
state: present
63+
definition:
64+
apiVersion: networking.k8s.io/v1
65+
kind: NetworkPolicy
66+
metadata:
67+
name: allow-ingress-from-ingress
68+
namespace: openshift-gitops
69+
spec:
70+
podSelector: {}
71+
ingress:
72+
- from:
73+
- namespaceSelector:
74+
matchLabels:
75+
network.openshift.io/policy-group: ingress
76+
policyTypes:
77+
- Ingress

playbooks/tasks/configure_operator.yaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,109 @@
1010
delay: "{{ k8s_delay }}"
1111
until: r_namespace_exists is success
1212

13+
- name: "Ensure same-namespace NetworkPolicy exists"
14+
when:
15+
- operator.namespace != "openshift-operators"
16+
- not (operator.disableDefaultNetworkPolicies | default(false))
17+
kubernetes.core.k8s:
18+
state: present
19+
definition:
20+
apiVersion: networking.k8s.io/v1
21+
kind: NetworkPolicy
22+
metadata:
23+
name: allow-from-same-namespace
24+
namespace: "{{ operator.namespace }}"
25+
spec:
26+
podSelector: {}
27+
ingress:
28+
- from:
29+
- podSelector: {}
30+
policyTypes:
31+
- Ingress
32+
register: r_same_namespace_netpol
33+
retries: "{{ k8s_retries }}"
34+
delay: "{{ k8s_delay }}"
35+
until: r_same_namespace_netpol is success
36+
37+
- name: "Ensure kube-apiserver NetworkPolicy exists"
38+
when:
39+
- operator.namespace != "openshift-operators"
40+
- not (operator.disableDefaultNetworkPolicies | default(false))
41+
kubernetes.core.k8s:
42+
state: present
43+
definition:
44+
apiVersion: networking.k8s.io/v1
45+
kind: NetworkPolicy
46+
metadata:
47+
name: allow-ingress-from-kube-apiserver
48+
namespace: "{{ operator.namespace }}"
49+
spec:
50+
podSelector: {}
51+
ingress:
52+
- from:
53+
- ipBlock:
54+
cidr: "{{ machineNetwork }}"
55+
policyTypes:
56+
- Ingress
57+
register: r_kube_apiserver_netpol
58+
retries: "{{ k8s_retries }}"
59+
delay: "{{ k8s_delay }}"
60+
until: r_kube_apiserver_netpol is success
61+
62+
- name: "Ensure monitoring NetworkPolicy exists"
63+
when:
64+
- operator.namespace != "openshift-operators"
65+
- not (operator.disableDefaultNetworkPolicies | default(false))
66+
kubernetes.core.k8s:
67+
state: present
68+
definition:
69+
apiVersion: networking.k8s.io/v1
70+
kind: NetworkPolicy
71+
metadata:
72+
name: allow-ingress-from-monitoring
73+
namespace: "{{ operator.namespace }}"
74+
spec:
75+
podSelector: {}
76+
ingress:
77+
- from:
78+
- namespaceSelector:
79+
matchLabels:
80+
network.openshift.io/policy-group: monitoring
81+
policyTypes:
82+
- Ingress
83+
register: r_monitoring_netpol
84+
retries: "{{ k8s_retries }}"
85+
delay: "{{ k8s_delay }}"
86+
until: r_monitoring_netpol is success
87+
88+
- name: "Ensure ingress NetworkPolicies exist"
89+
when:
90+
- operator.namespace != "openshift-operators"
91+
- not (operator.disableDefaultNetworkPolicies | default(false))
92+
kubernetes.core.k8s:
93+
state: present
94+
definition:
95+
apiVersion: networking.k8s.io/v1
96+
kind: NetworkPolicy
97+
metadata:
98+
name: "allow-ingress-from-{{ item.name }}"
99+
namespace: "{{ operator.namespace }}"
100+
spec:
101+
podSelector: {}
102+
ingress:
103+
- from:
104+
- namespaceSelector:
105+
matchLabels: "{{ item.namespaceSelector.matchLabels }}"
106+
policyTypes:
107+
- Ingress
108+
loop: "{{ operator.allowIngressFrom | default([]) }}"
109+
loop_control:
110+
label: "{{ item.name }}"
111+
register: r_ingress_netpols
112+
retries: "{{ k8s_retries }}"
113+
delay: "{{ k8s_delay }}"
114+
until: r_ingress_netpols is success
115+
13116
- name: "Check if OperatorGroup already exists in namespace"
14117
when: operator.namespace != "openshift-operators"
15118
kubernetes.core.k8s_info:

schemas/operators.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,43 @@ definitions:
4141
global:
4242
type: boolean
4343
description: Configure operator to watch the entire cluster.
44+
disableDefaultNetworkPolicies:
45+
type: boolean
46+
description: >-
47+
Opt out of all three default NetworkPolicies: allow-from-same-namespace,
48+
allow-ingress-from-kube-apiserver, and allow-ingress-from-monitoring.
49+
When true, no default ingress rules are created and allowIngressFrom is forbidden.
50+
allowIngressFrom:
51+
type: array
52+
description: Additional ingress NetworkPolicies based on namespace label selectors.
53+
items:
54+
type: object
55+
additionalProperties: false
56+
required:
57+
- name
58+
- namespaceSelector
59+
properties:
60+
name:
61+
type: string
62+
description: Identifier used to name the NetworkPolicy (allow-ingress-from-<name>).
63+
namespaceSelector:
64+
type: object
65+
additionalProperties: false
66+
required:
67+
- matchLabels
68+
properties:
69+
matchLabels:
70+
type: object
71+
description: Label selector to match source namespaces.
72+
if:
73+
required:
74+
- disableDefaultNetworkPolicies
75+
properties:
76+
disableDefaultNetworkPolicies:
77+
const: true
78+
then:
79+
properties:
80+
allowIngressFrom: false
4481
dependencies:
4582
csvMirror:
4683
- csvNames

0 commit comments

Comments
 (0)