Browse Source

Update CRD when NP has namespaceSelectors

When a namespace is created, deleted or updated and
its labels matches the namespaceSelector of a NP,
the CRD and the respective sg must be updated.

Partially Implements: blueprint k8s-network-policies

Change-Id: I515de28647f5f06248555733c27dd4f5a56149ec
Maysa Macedo 3 months ago
parent
commit
9deb322962

+ 1
- 0
kuryr_kubernetes/constants.py View File

@@ -37,6 +37,7 @@ K8S_POD_STATUS_PENDING = 'Pending'
37 37
 K8S_ANNOTATION_PREFIX = 'openstack.org/kuryr'
38 38
 K8S_ANNOTATION_VIF = K8S_ANNOTATION_PREFIX + '-vif'
39 39
 K8S_ANNOTATION_LABEL = K8S_ANNOTATION_PREFIX + '-pod-label'
40
+K8S_ANNOTATION_NAMESPACE_LABEL = K8S_ANNOTATION_PREFIX + '-namespace-label'
40 41
 K8S_ANNOTATION_LBAAS_SPEC = K8S_ANNOTATION_PREFIX + '-lbaas-spec'
41 42
 K8S_ANNOTATION_LBAAS_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-state'
42 43
 K8S_ANNOTATION_NET_CRD = K8S_ANNOTATION_PREFIX + '-net-crd'

+ 21
- 0
kuryr_kubernetes/controller/drivers/base.py View File

@@ -268,6 +268,27 @@ class PodSecurityGroupsDriver(DriverBase):
268 268
         """
269 269
         raise NotImplementedError()
270 270
 
271
+    def delete_namespace_sg_rules(self, namespace):
272
+        """Delete security group rule associated to a namespace.
273
+
274
+        :param namespace: dict containing K8S Namespace object
275
+        """
276
+        raise NotImplementedError()
277
+
278
+    def create_namespace_sg_rules(self, namespace):
279
+        """Create security group rule associated to a namespace.
280
+
281
+        :param namespace: dict containing K8S Namespace object
282
+        """
283
+        raise NotImplementedError()
284
+
285
+    def update_namespace_sg_rules(self, namespace):
286
+        """Update security group rule associated to a namespace.
287
+
288
+        :param namespace: dict containing K8S Namespace object
289
+        """
290
+        raise NotImplementedError()
291
+
271 292
 
272 293
 @six.add_metaclass(abc.ABCMeta)
273 294
 class ServiceSecurityGroupsDriver(DriverBase):

+ 12
- 0
kuryr_kubernetes/controller/drivers/default_security_groups.py View File

@@ -59,6 +59,18 @@ class DefaultPodSecurityGroupsDriver(base.PodSecurityGroupsDriver):
59 59
         LOG.debug("Security group driver does not update SG rules for "
60 60
                   "the pods.")
61 61
 
62
+    def delete_namespace_sg_rules(self, namespace):
63
+        LOG.debug("Security group driver does not delete SG rules for "
64
+                  "namespace.")
65
+
66
+    def create_namespace_sg_rules(self, namespace):
67
+        LOG.debug("Security group driver does not create SG rules for "
68
+                  "namespace.")
69
+
70
+    def update_namespace_sg_rules(self, namespace):
71
+        LOG.debug("Security group driver does not update SG rules for "
72
+                  "namespace.")
73
+
62 74
 
63 75
 class DefaultServiceSecurityGroupsDriver(base.ServiceSecurityGroupsDriver):
64 76
     """Provides security groups for Service based on a configuration option."""

+ 130
- 0
kuryr_kubernetes/controller/drivers/namespace_security_groups.py View File

@@ -21,6 +21,7 @@ from kuryr_kubernetes import clients
21 21
 from kuryr_kubernetes import config
22 22
 from kuryr_kubernetes import constants
23 23
 from kuryr_kubernetes.controller.drivers import base
24
+from kuryr_kubernetes.controller.drivers import utils
24 25
 from kuryr_kubernetes import exceptions
25 26
 
26 27
 from neutronclient.common import exceptions as n_exc
@@ -67,6 +68,73 @@ def _get_net_crd(namespace):
67 68
     return net_crd
68 69
 
69 70
 
71
+def _create_sg_rule(sg_id, direction, cidr, port=None, namespace=None):
72
+    if port:
73
+        sg_rule = utils.create_security_group_rule_body(
74
+            sg_id, direction, port.get('port'),
75
+            protocol=port.get('protocol'), cidr=cidr, namespace=namespace)
76
+    else:
77
+        sg_rule = utils.create_security_group_rule_body(
78
+            sg_id, direction, port_range_min=1,
79
+            port_range_max=65535, cidr=cidr, namespace=namespace)
80
+
81
+    sgr_id = utils.create_security_group_rule(sg_rule)
82
+
83
+    sg_rule['security_group_rule']['id'] = sgr_id
84
+    return sg_rule
85
+
86
+
87
+def _parse_rules(direction, crd, namespace):
88
+    policy = crd['spec']['networkpolicy_spec']
89
+    sg_id = crd['spec']['securityGroupId']
90
+
91
+    ns_labels = namespace['metadata'].get('labels')
92
+    ns_name = namespace['metadata'].get('name')
93
+    ns_cidr = utils.get_namespace_subnet_cidr(namespace)
94
+
95
+    rule_direction = 'from'
96
+    crd_rules = crd['spec'].get('ingressSgRules')
97
+    if direction == 'egress':
98
+        rule_direction = 'to'
99
+        crd_rules = crd['spec'].get('egressSgRules')
100
+
101
+    matched = False
102
+    rule_list = policy.get(direction, None)
103
+    for rule_block in rule_list:
104
+        for rule in rule_block.get(rule_direction, []):
105
+            pod_selector = rule.get('podSelector')
106
+            ns_selector = rule.get('namespaceSelector')
107
+            if (ns_selector and ns_labels and
108
+                    utils.match_selector(ns_selector, ns_labels)):
109
+                if pod_selector:
110
+                    pods = utils.get_pods(pod_selector, ns_name)
111
+                    for pod in pods.get('items'):
112
+                        pod_ip = utils.get_pod_ip(pod)
113
+                        if 'ports' in rule_block:
114
+                            for port in rule_block['ports']:
115
+                                matched = True
116
+                                crd_rules.append(_create_sg_rule(
117
+                                    sg_id, direction, pod_ip, port=port,
118
+                                    namespace=ns_name))
119
+                        else:
120
+                            matched = True
121
+                            crd_rules.append(_create_sg_rule(
122
+                                sg_id, direction, pod_ip,
123
+                                namespace=ns_name))
124
+                else:
125
+                    if 'ports' in rule_block:
126
+                        for port in rule_block['ports']:
127
+                            matched = True
128
+                            crd_rules.append(_create_sg_rule(
129
+                                sg_id, direction, ns_cidr,
130
+                                port=port, namespace=ns_name))
131
+                    else:
132
+                        matched = True
133
+                        crd_rules.append(_create_sg_rule(
134
+                            sg_id, direction, ns_cidr, namespace=ns_name))
135
+    return matched, crd_rules
136
+
137
+
70 138
 class NamespacePodSecurityGroupsDriver(base.PodSecurityGroupsDriver):
71 139
     """Provides security groups for Pod based on a configuration option."""
72 140
 
@@ -131,6 +199,68 @@ class NamespacePodSecurityGroupsDriver(base.PodSecurityGroupsDriver):
131 199
             LOG.exception("Error deleting security group %s.", sg_id)
132 200
             raise
133 201
 
202
+    def delete_namespace_sg_rules(self, namespace):
203
+        ns_name = namespace['metadata']['name']
204
+        LOG.debug("Deleting sg rule for namespace: %s",
205
+                  ns_name)
206
+
207
+        knp_crds = utils.get_kuryrnetpolicy_crds()
208
+        for crd in knp_crds.get('items'):
209
+            crd_selector = crd['spec'].get('podSelector')
210
+            ingress_rule_list = crd['spec'].get('ingressSgRules')
211
+            egress_rule_list = crd['spec'].get('egressSgRules')
212
+            i_rules = []
213
+            e_rules = []
214
+
215
+            matched = False
216
+            for i_rule in ingress_rule_list:
217
+                LOG.debug("Parsing ingress rule: %r", i_rule)
218
+                rule_namespace = i_rule.get('namespace', None)
219
+
220
+                if rule_namespace and rule_namespace == ns_name:
221
+                    matched = True
222
+                    utils.delete_security_group_rule(
223
+                        i_rule['security_group_rule']['id'])
224
+                else:
225
+                    i_rules.append(i_rule)
226
+
227
+            for e_rule in egress_rule_list:
228
+                LOG.debug("Parsing egress rule: %r", e_rule)
229
+                rule_namespace = e_rule.get('namespace', None)
230
+
231
+                if rule_namespace and rule_namespace == ns_name:
232
+                    matched = True
233
+                    utils.delete_security_group_rule(
234
+                        e_rule['security_group_rule']['id'])
235
+                else:
236
+                    e_rules.append(e_rule)
237
+
238
+            if matched:
239
+                utils.patch_kuryr_crd(crd, i_rules, e_rules, crd_selector)
240
+
241
+    def create_namespace_sg_rules(self, namespace):
242
+        kubernetes = clients.get_kubernetes_client()
243
+        ns_name = namespace['metadata']['name']
244
+        LOG.debug("Creating sg rule for namespace: %s", ns_name)
245
+        namespace = kubernetes.get(
246
+            '{}/namespaces/{}'.format(constants.K8S_API_BASE, ns_name))
247
+        knp_crds = utils.get_kuryrnetpolicy_crds()
248
+        for crd in knp_crds.get('items'):
249
+            crd_selector = crd['spec'].get('podSelector')
250
+
251
+            i_matched, i_rules = _parse_rules('ingress', crd, namespace)
252
+            e_matched, e_rules = _parse_rules('egress', crd, namespace)
253
+
254
+            if i_matched or e_matched:
255
+                utils.patch_kuryr_crd(crd, i_rules,
256
+                                      e_rules, crd_selector)
257
+
258
+    def update_namespace_sg_rules(self, namespace):
259
+        LOG.debug("Updating sg rule for namespace: %s",
260
+                  namespace['metadata']['name'])
261
+        self.delete_namespace_sg_rules(namespace)
262
+        self.create_namespace_sg_rules(namespace)
263
+
134 264
     def create_sg_rules(self, pod):
135 265
         LOG.debug("Security group driver does not create SG rules for "
136 266
                   "the pods.")

+ 12
- 23
kuryr_kubernetes/controller/drivers/network_policy.py View File

@@ -203,40 +203,27 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
203 203
             matching_pods = driver_utils.get_pods(pod_selector, namespace)
204 204
         for pod in matching_pods.get('items'):
205 205
             if pod['status']['podIP']:
206
-                ips.append(pod['status']['podIP'])
206
+                pod_ip = pod['status']['podIP']
207
+                ns = pod['metadata']['namespace']
208
+                ips.append({'cidr': pod_ip, 'namespace': ns})
207 209
         return ips
208 210
 
209
-    def _get_namespace_subnet_cidr(self, namespace):
210
-        try:
211
-            ns_annotations = namespace['metadata']['annotations']
212
-            ns_name = ns_annotations[constants.K8S_ANNOTATION_NET_CRD]
213
-        except KeyError:
214
-            LOG.exception('Namespace handler must be enabled to support '
215
-                          'Network Policies with namespaceSelector')
216
-            raise exceptions.ResourceNotReady(namespace)
217
-        try:
218
-            net_crd = self.kubernetes.get('{}/kuryrnets/{}'.format(
219
-                constants.K8S_API_CRD, ns_name))
220
-        except exceptions.K8sClientException:
221
-            LOG.exception("Kubernetes Client Exception.")
222
-            raise
223
-        return net_crd['spec']['subnetCIDR']
224
-
225 211
     def _get_namespaces_cidr(self, namespace_selector, namespace=None):
226 212
         cidrs = []
227 213
         if not namespace_selector and namespace:
228 214
             ns = self.kubernetes.get(
229 215
                 '{}/namespaces/{}'.format(constants.K8S_API_BASE, namespace))
230
-            ns_cidr = self._get_namespace_subnet_cidr(ns)
231
-            cidrs.append(ns_cidr)
216
+            ns_cidr = driver_utils.get_namespace_subnet_cidr(ns)
217
+            cidrs.append({'cidr': ns_cidr, 'namespace': namespace})
232 218
         else:
233 219
             matching_namespaces = driver_utils.get_namespaces(
234 220
                 namespace_selector)
235 221
             for ns in matching_namespaces.get('items'):
236 222
                 # NOTE(ltomasbo): This requires the namespace handler to be
237 223
                 # also enabled
238
-                ns_cidr = self._get_namespace_subnet_cidr(ns)
239
-                cidrs.append(ns_cidr)
224
+                ns_cidr = driver_utils.get_namespace_subnet_cidr(ns)
225
+                ns_name = ns['metadata']['name']
226
+                cidrs.append({'cidr': ns_cidr, 'namespace': ns_name})
240 227
         return cidrs
241 228
 
242 229
     def _parse_selectors(self, rule_block, rule_direction, policy_namespace):
@@ -315,7 +302,8 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
315 302
                                 driver_utils.create_security_group_rule_body(
316 303
                                     sg_id, direction, port.get('port'),
317 304
                                     protocol=port.get('protocol'),
318
-                                    cidr=cidr))
305
+                                    cidr=cidr.get('cidr'),
306
+                                    namespace=cidr.get('namespace')))
319 307
                             sg_rule_body_list.append(rule)
320 308
                         if allow_all:
321 309
                             rule = (
@@ -334,7 +322,8 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
334 322
                         sg_id, direction,
335 323
                         port_range_min=1,
336 324
                         port_range_max=65535,
337
-                        cidr=cidr)
325
+                        cidr=cidr.get('cidr'),
326
+                        namespace=cidr.get('namespace'))
338 327
                     sg_rule_body_list.append(rule)
339 328
                 if allow_all:
340 329
                     rule = driver_utils.create_security_group_rule_body(

+ 35
- 96
kuryr_kubernetes/controller/drivers/network_policy_security_groups.py View File

@@ -26,81 +26,6 @@ from oslo_log import log as logging
26 26
 LOG = logging.getLogger(__name__)
27 27
 
28 28
 
29
-OPERATORS_WITH_VALUES = [constants.K8S_OPERATOR_IN,
30
-                         constants.K8S_OPERATOR_NOT_IN]
31
-
32
-
33
-def _get_kuryrnetpolicy_crds(namespace=None):
34
-    kubernetes = clients.get_kubernetes_client()
35
-
36
-    try:
37
-        if namespace:
38
-            knp_path = '{}/{}/kuryrnetpolicies'.format(
39
-                constants.K8S_API_CRD_NAMESPACES, namespace)
40
-        else:
41
-            knp_path = constants.K8S_API_CRD_KURYRNETPOLICIES
42
-        LOG.debug("K8s API Query %s", knp_path)
43
-        knps = kubernetes.get(knp_path)
44
-        LOG.debug("Return Kuryr Network Policies with label %s", knps)
45
-    except exceptions.K8sResourceNotFound:
46
-        LOG.exception("KuryrNetPolicy CRD not found")
47
-        raise
48
-    except exceptions.K8sClientException:
49
-        LOG.exception("Kubernetes Client Exception")
50
-        raise
51
-    return knps
52
-
53
-
54
-def _match_expressions(expressions, labels):
55
-    for exp in expressions:
56
-        exp_op = exp['operator'].lower()
57
-        if labels:
58
-            if exp_op in OPERATORS_WITH_VALUES:
59
-                exp_values = exp['values']
60
-                label_value = labels.get(str(exp['key']), None)
61
-                if exp_op == constants.K8S_OPERATOR_IN:
62
-                    if label_value is None or label_value not in exp_values:
63
-                            return False
64
-                elif exp_op == constants.K8S_OPERATOR_NOT_IN:
65
-                    if label_value in exp_values:
66
-                        return False
67
-            else:
68
-                if exp_op == constants.K8S_OPERATOR_EXISTS:
69
-                    exists = labels.get(str(exp['key']), None)
70
-                    if exists is None:
71
-                        return False
72
-                elif exp_op == constants.K8S_OPERATOR_DOES_NOT_EXIST:
73
-                    exists = labels.get(str(exp['key']), None)
74
-                    if exists is not None:
75
-                        return False
76
-        else:
77
-            if exp_op in (constants.K8S_OPERATOR_IN,
78
-                          constants.K8S_OPERATOR_EXISTS):
79
-                return False
80
-    return True
81
-
82
-
83
-def _match_labels(crd_labels, labels):
84
-    for crd_key, crd_value in crd_labels.items():
85
-        label_value = labels.get(crd_key, None)
86
-        if not label_value or crd_value != label_value:
87
-                return False
88
-    return True
89
-
90
-
91
-def _match_selector(selector, labels):
92
-    crd_labels = selector.get('matchLabels', None)
93
-    crd_expressions = selector.get('matchExpressions', None)
94
-
95
-    match_exp = match_lb = True
96
-    if crd_expressions:
97
-        match_exp = _match_expressions(crd_expressions,
98
-                                       labels)
99
-    if crd_labels and labels:
100
-        match_lb = _match_labels(crd_labels, labels)
101
-    return match_exp and match_lb
102
-
103
-
104 29
 def _get_namespace_labels(namespace):
105 30
     kubernetes = clients.get_kubernetes_client()
106 31
 
@@ -119,15 +44,15 @@ def _get_namespace_labels(namespace):
119 44
     return namespaces['metadata'].get('labels')
120 45
 
121 46
 
122
-def _create_sg_rules(crd, pod, namespace_selector, pod_selector,
123
-                     rule_block, crd_rules, direction,
124
-                     matched):
47
+def _create_sg_rules(crd, pod, pod_selector, rule_block, crd_rules,
48
+                     direction, matched, namespace=None):
125 49
     pod_labels = pod['metadata'].get('labels')
126 50
 
127 51
     # NOTE (maysams) No need to differentiate between podSelector
128 52
     # with empty value or with '{}', as they have same result in here.
129 53
     if (pod_selector and
130
-            _match_selector(pod_selector, pod_labels)):
54
+            driver_utils.match_selector(pod_selector, pod_labels)):
55
+
131 56
         matched = True
132 57
         pod_ip = driver_utils.get_pod_ip(pod)
133 58
         sg_id = crd['spec']['securityGroupId']
@@ -135,7 +60,8 @@ def _create_sg_rules(crd, pod, namespace_selector, pod_selector,
135 60
             for port in rule_block['ports']:
136 61
                 sg_rule = driver_utils.create_security_group_rule_body(
137 62
                     sg_id, direction, port.get('port'),
138
-                    protocol=port.get('protocol'), cidr=pod_ip)
63
+                    protocol=port.get('protocol'), cidr=pod_ip,
64
+                    namespace=namespace)
139 65
                 sgr_id = driver_utils.create_security_group_rule(sg_rule)
140 66
                 sg_rule['security_group_rule']['id'] = sgr_id
141 67
                 crd_rules.append(sg_rule)
@@ -144,7 +70,8 @@ def _create_sg_rules(crd, pod, namespace_selector, pod_selector,
144 70
                 sg_id, direction,
145 71
                 port_range_min=1,
146 72
                 port_range_max=65535,
147
-                cidr=pod_ip)
73
+                cidr=pod_ip,
74
+                namespace=namespace)
148 75
             sgr_id = driver_utils.create_security_group_rule(sg_rule)
149 76
             sg_rule['security_group_rule']['id'] = sgr_id
150 77
             crd_rules.append(sg_rule)
@@ -171,23 +98,22 @@ def _parse_rules(direction, crd, pod):
171 98
             namespace_selector = rule.get('namespaceSelector')
172 99
             pod_selector = rule.get('podSelector')
173 100
             if namespace_selector == {}:
174
-                if _create_sg_rules(crd, pod, namespace_selector,
175
-                                    pod_selector, rule_block, crd_rules,
176
-                                    direction, matched):
101
+                if _create_sg_rules(crd, pod, pod_selector, rule_block,
102
+                                    crd_rules, direction, matched):
177 103
                     matched = True
178 104
             elif namespace_selector:
179 105
                 if (pod_namespace_labels and
180
-                    _match_selector(namespace_selector,
181
-                                    pod_namespace_labels)):
182
-                    if _create_sg_rules(crd, pod, namespace_selector,
183
-                                        pod_selector, rule_block, crd_rules,
184
-                                        direction, matched):
106
+                    driver_utils.match_selector(namespace_selector,
107
+                                                pod_namespace_labels)):
108
+                    if _create_sg_rules(crd, pod, pod_selector, rule_block,
109
+                                        crd_rules, direction, matched,
110
+                                        pod_namespace):
185 111
                         matched = True
186 112
             else:
187 113
                 if pod_namespace == policy_namespace:
188
-                    if _create_sg_rules(crd, pod, namespace_selector,
189
-                                        pod_selector, rule_block, crd_rules,
190
-                                        direction, matched):
114
+                    if _create_sg_rules(crd, pod, pod_selector, rule_block,
115
+                                        crd_rules, direction, matched,
116
+                                        pod_namespace):
191 117
                         matched = True
192 118
     return matched, crd_rules
193 119
 
@@ -198,11 +124,12 @@ def _get_pod_sgs(pod, project_id):
198 124
     pod_labels = pod['metadata'].get('labels')
199 125
     pod_namespace = pod['metadata']['namespace']
200 126
 
201
-    knp_crds = _get_kuryrnetpolicy_crds(namespace=pod_namespace)
127
+    knp_crds = driver_utils.get_kuryrnetpolicy_crds(
128
+        namespace=pod_namespace)
202 129
     for crd in knp_crds.get('items'):
203 130
         pod_selector = crd['spec'].get('podSelector')
204 131
         if pod_selector:
205
-            if _match_selector(pod_selector, pod_labels):
132
+            if driver_utils.match_selector(pod_selector, pod_labels):
206 133
                 LOG.debug("Appending %s",
207 134
                           str(crd['spec']['securityGroupId']))
208 135
                 sg_list.append(str(crd['spec']['securityGroupId']))
@@ -229,7 +156,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
229 156
 
230 157
     def create_sg_rules(self, pod):
231 158
         LOG.debug("Creating sg rule for pod: %s", pod['metadata']['name'])
232
-        knp_crds = _get_kuryrnetpolicy_crds()
159
+        knp_crds = driver_utils.get_kuryrnetpolicy_crds()
233 160
         for crd in knp_crds.get('items'):
234 161
             crd_selector = crd['spec'].get('podSelector')
235 162
 
@@ -244,7 +171,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
244 171
         LOG.debug("Deleting sg rule for pod: %s", pod['metadata']['name'])
245 172
         pod_ip = driver_utils.get_pod_ip(pod)
246 173
 
247
-        knp_crds = _get_kuryrnetpolicy_crds()
174
+        knp_crds = driver_utils.get_kuryrnetpolicy_crds()
248 175
         for crd in knp_crds.get('items'):
249 176
             crd_selector = crd['spec'].get('podSelector')
250 177
             ingress_rule_list = crd['spec'].get('ingressSgRules')
@@ -293,6 +220,18 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
293 220
         LOG.debug("Security group driver does not implement deleting "
294 221
                   "SGs.")
295 222
 
223
+    def delete_namespace_sg_rules(self, namespace):
224
+        LOG.debug("Security group driver does not delete SG rules for "
225
+                  "namespace.")
226
+
227
+    def create_namespace_sg_rules(self, namespace):
228
+        LOG.debug("Security group driver does not create SG rules for "
229
+                  "namespace.")
230
+
231
+    def update_namespace_sg_rules(self, namespace):
232
+        LOG.debug("Security group driver does not update SG rules for "
233
+                  "namespace.")
234
+
296 235
 
297 236
 class NetworkPolicyServiceSecurityGroupsDriver(
298 237
         base.ServiceSecurityGroupsDriver):

+ 97
- 6
kuryr_kubernetes/controller/drivers/utils.py View File

@@ -238,7 +238,7 @@ def patch_kuryr_crd(crd, i_rules, e_rules, pod_selector, np_spec=None):
238 238
 def create_security_group_rule_body(
239 239
         security_group_id, direction, port_range_min,
240 240
         port_range_max=None, protocol=None, ethertype='IPv4', cidr=None,
241
-        description="Kuryr-Kubernetes NetPolicy SG rule"):
241
+        description="Kuryr-Kubernetes NetPolicy SG rule", namespace=None):
242 242
     if not port_range_min:
243 243
         port_range_min = 1
244 244
         port_range_max = 65535
@@ -260,6 +260,8 @@ def create_security_group_rule_body(
260 260
     if cidr:
261 261
         security_group_rule_body[u'security_group_rule'][
262 262
             u'remote_ip_prefix'] = cidr
263
+    if namespace:
264
+        security_group_rule_body['namespace'] = namespace
263 265
     LOG.debug("Creating sg rule body %s", security_group_rule_body)
264 266
     return security_group_rule_body
265 267
 
@@ -280,11 +282,100 @@ def get_pod_ip(pod):
280 282
     return first_subnet_ip
281 283
 
282 284
 
283
-def get_pod_annotated_labels(pod):
285
+def get_annotated_labels(resource, annotation_labels):
284 286
     try:
285
-        annotations = pod['metadata']['annotations']
286
-        pod_labels_annotation = annotations[constants.K8S_ANNOTATION_LABEL]
287
+        annotations = resource['metadata']['annotations']
288
+        labels_annotation = annotations[annotation_labels]
287 289
     except KeyError:
288 290
         return None
289
-    pod_labels = jsonutils.loads(pod_labels_annotation)
290
-    return pod_labels
291
+    labels = jsonutils.loads(labels_annotation)
292
+    return labels
293
+
294
+
295
+def get_kuryrnetpolicy_crds(namespace=None):
296
+    kubernetes = clients.get_kubernetes_client()
297
+
298
+    try:
299
+        if namespace:
300
+            knp_path = '{}/{}/kuryrnetpolicies'.format(
301
+                constants.K8S_API_CRD_NAMESPACES, namespace)
302
+        else:
303
+            knp_path = constants.K8S_API_CRD_KURYRNETPOLICIES
304
+        LOG.debug("K8s API Query %s", knp_path)
305
+        knps = kubernetes.get(knp_path)
306
+        LOG.debug("Return Kuryr Network Policies with label %s", knps)
307
+    except k_exc.K8sResourceNotFound:
308
+        LOG.exception("KuryrNetPolicy CRD not found")
309
+        raise
310
+    except k_exc.K8sClientException:
311
+        LOG.exception("Kubernetes Client Exception")
312
+        raise
313
+    return knps
314
+
315
+
316
+def match_expressions(expressions, labels):
317
+    for exp in expressions:
318
+        exp_op = exp['operator'].lower()
319
+        if labels:
320
+            if exp_op in OPERATORS_WITH_VALUES:
321
+                exp_values = exp['values']
322
+                label_value = labels.get(str(exp['key']), None)
323
+                if exp_op == constants.K8S_OPERATOR_IN:
324
+                    if label_value is None or label_value not in exp_values:
325
+                            return False
326
+                elif exp_op == constants.K8S_OPERATOR_NOT_IN:
327
+                    if label_value in exp_values:
328
+                        return False
329
+            else:
330
+                if exp_op == constants.K8S_OPERATOR_EXISTS:
331
+                    exists = labels.get(str(exp['key']), None)
332
+                    if exists is None:
333
+                        return False
334
+                elif exp_op == constants.K8S_OPERATOR_DOES_NOT_EXIST:
335
+                    exists = labels.get(str(exp['key']), None)
336
+                    if exists is not None:
337
+                        return False
338
+        else:
339
+            if exp_op in (constants.K8S_OPERATOR_IN,
340
+                          constants.K8S_OPERATOR_EXISTS):
341
+                return False
342
+    return True
343
+
344
+
345
+def match_labels(crd_labels, labels):
346
+    for crd_key, crd_value in crd_labels.items():
347
+        label_value = labels.get(crd_key, None)
348
+        if not label_value or crd_value != label_value:
349
+                return False
350
+    return True
351
+
352
+
353
+def match_selector(selector, labels):
354
+    crd_labels = selector.get('matchLabels', None)
355
+    crd_expressions = selector.get('matchExpressions', None)
356
+
357
+    match_exp = match_lb = True
358
+    if crd_expressions:
359
+        match_exp = match_expressions(crd_expressions,
360
+                                      labels)
361
+    if crd_labels and labels:
362
+        match_lb = match_labels(crd_labels, labels)
363
+    return match_exp and match_lb
364
+
365
+
366
+def get_namespace_subnet_cidr(namespace):
367
+    kubernetes = clients.get_kubernetes_client()
368
+    try:
369
+        ns_annotations = namespace['metadata']['annotations']
370
+        ns_name = ns_annotations[constants.K8S_ANNOTATION_NET_CRD]
371
+    except KeyError:
372
+        LOG.exception('Namespace handler must be enabled to support '
373
+                      'Network Policies with namespaceSelector')
374
+        raise k_exc.ResourceNotReady(namespace)
375
+    try:
376
+        net_crd = kubernetes.get('{}/kuryrnets/{}'.format(
377
+            constants.K8S_API_CRD, ns_name))
378
+    except k_exc.K8sClientException:
379
+        LOG.exception("Kubernetes Client Exception.")
380
+        raise
381
+    return net_crd['spec']['subnetCIDR']

+ 29
- 1
kuryr_kubernetes/controller/handlers/namespace.py View File

@@ -15,10 +15,12 @@
15 15
 from oslo_cache import core as cache
16 16
 from oslo_config import cfg as oslo_cfg
17 17
 from oslo_log import log as logging
18
+from oslo_serialization import jsonutils
18 19
 
19 20
 from kuryr_kubernetes import clients
20 21
 from kuryr_kubernetes import constants
21 22
 from kuryr_kubernetes.controller.drivers import base as drivers
23
+from kuryr_kubernetes.controller.drivers import utils as drivers_utils
22 24
 from kuryr_kubernetes import exceptions
23 25
 from kuryr_kubernetes.handlers import k8s_base
24 26
 from kuryr_kubernetes import utils
@@ -57,6 +59,17 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
57 59
         self._drv_vif_pool.set_vif_driver()
58 60
 
59 61
     def on_present(self, namespace):
62
+        current_namespace_labels = namespace['metadata'].get('labels')
63
+        previous_namespace_labels = drivers_utils.get_annotated_labels(
64
+            namespace, constants.K8S_ANNOTATION_NAMESPACE_LABEL)
65
+        LOG.debug("Got previous namespace labels from annotation: %r",
66
+                  previous_namespace_labels)
67
+
68
+        if (previous_namespace_labels and
69
+                current_namespace_labels != previous_namespace_labels):
70
+            self._drv_sg.update_namespace_sg_rules(namespace)
71
+            self._set_namespace_labels(namespace, current_namespace_labels)
72
+
60 73
         ns_name = namespace['metadata']['name']
61 74
         project_id = self._drv_project.get_project(namespace)
62 75
         net_crd_id = self._get_net_crd_id(namespace)
@@ -85,6 +98,8 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
85 98
         try:
86 99
             net_crd = self._add_kuryrnet_crd(ns_name, net_crd_spec)
87 100
             self._set_net_crd(namespace, net_crd)
101
+            self._drv_sg.create_namespace_sg_rules(namespace)
102
+            self._set_namespace_labels(namespace, current_namespace_labels)
88 103
         except exceptions.K8sClientException:
89 104
             LOG.exception("Kuryrnet CRD could not be added. Rolling back "
90 105
                           "network resources created for the namespace.")
@@ -108,8 +123,8 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
108 123
         else:
109 124
             LOG.debug("There is no security group associated with the "
110 125
                       "namespace to be deleted")
111
-
112 126
         self._del_kuryrnet_crd(net_crd_id)
127
+        self._drv_sg.delete_namespace_sg_rules(namespace)
113 128
 
114 129
     def is_ready(self, quota):
115 130
         if not utils.has_kuryr_crd(constants.K8S_API_CRD_KURYRNETS):
@@ -191,3 +206,16 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
191 206
             LOG.exception("Kubernetes Client Exception deleting kuryrnet "
192 207
                           "CRD.")
193 208
             raise
209
+
210
+    def _set_namespace_labels(self, namespace, labels):
211
+        if not labels:
212
+            LOG.debug("Removing Label annotation: %r", labels)
213
+            annotation = None
214
+        else:
215
+            annotation = jsonutils.dumps(labels, sort_keys=True)
216
+            LOG.debug("Setting Labels annotation: %r", annotation)
217
+
218
+        k8s = clients.get_kubernetes_client()
219
+        k8s.annotate(namespace['metadata']['selfLink'],
220
+                     {constants.K8S_ANNOTATION_NAMESPACE_LABEL: annotation},
221
+                     resource_version=namespace['metadata']['resourceVersion'])

+ 265
- 0
kuryr_kubernetes/tests/unit/controller/drivers/test_namespace_security_groups.py View File

@@ -61,6 +61,131 @@ def get_namespace_obj():
61 61
     }
62 62
 
63 63
 
64
+def get_no_match_crd_namespace_obj():
65
+    return {
66
+        "kind": "Namespace",
67
+        "metadata": {
68
+            "annotations": {
69
+                "openstack.org/kuryr-namespace-label": '{"name": "dev"}',
70
+                "openstack.org/kuryr-net-crd": "ns-dev"
71
+            },
72
+            "labels": {"name": "prod"},
73
+            "name": "prod",
74
+            "selfLink": "/api/v1/namespaces/dev"}}
75
+
76
+
77
+def get_match_crd_namespace_obj():
78
+    return {
79
+        "kind": "Namespace",
80
+        "metadata": {
81
+            "annotations": {
82
+                "openstack.org/kuryr-namespace-label": '{"name": "dev"}',
83
+                "openstack.org/kuryr-net-crd": "ns-dev"
84
+            },
85
+            "labels": {
86
+                "name": "dev"
87
+            },
88
+            "name": "dev",
89
+            "selfLink": "/api/v1/namespaces/dev"}}
90
+
91
+
92
+def get_match_crd_pod_obj():
93
+    return {
94
+        'kind': 'Pod',
95
+        'metadata': {
96
+            'name': mock.sentinel.pod_name,
97
+            'namespace': 'dev',
98
+            'labels': {
99
+                'tier': 'backend'},
100
+            'annotations': {
101
+                'openstack.org/kuryr-pod-label': '{"tier": "backend"}'}},
102
+        'status': {'podIP': mock.sentinel.podIP}}
103
+
104
+
105
+def get_sg_rule():
106
+    pod_ip = get_match_crd_pod_obj()['status'].get('podIP')
107
+    return {
108
+        "namespace": 'dev',
109
+        "security_group_rule": {
110
+            "description": "Kuryr-Kubernetes NetPolicy SG rule",
111
+            "direction": "ingress",
112
+            "ethertype": "IPv4",
113
+            "id": 'f15ff50a-e8a4-4872-81bf-a04cbb8cb388',
114
+            "port_range_max": 6379,
115
+            "port_range_min": 6379,
116
+            "protocol": "tcp",
117
+            "remote_ip_prefix": pod_ip,
118
+            "security_group_id": '36923e76-026c-422b-8dfd-7292e7c88228'}}
119
+
120
+
121
+def get_matched_crd_obj():
122
+    return {
123
+        "kind": "KuryrNetPolicy",
124
+        "metadata": {"name": "np-test-network-policy",
125
+                     "namespace": "default"},
126
+        "spec": {
127
+            "egressSgRules": [],
128
+            "ingressSgRules": [get_sg_rule()],
129
+            "networkpolicy_spec": {
130
+                "ingress": [
131
+                    {"from": [
132
+                        {"namespaceSelector": {
133
+                            "matchLabels": {"name": "dev"}}}],
134
+                     "ports": [
135
+                        {"port": 6379,
136
+                         "protocol": "TCP"}]}],
137
+                "podSelector": {"matchLabels": {"app": "demo"}},
138
+                "policyTypes": ["Ingress"]},
139
+            "podSelector": {"matchLabels": {"app": "demo"}},
140
+            "securityGroupId": '36923e76-026c-422b-8dfd-7292e7c88228'}}
141
+
142
+
143
+def get_crd_obj_no_match():
144
+    return {
145
+        "kind": "KuryrNetPolicy",
146
+        "metadata": {"name": "np-test-network-policy",
147
+                     "namespace": "default"},
148
+        "spec": {
149
+            "egressSgRules": [],
150
+            "ingressSgRules": [],
151
+            "networkpolicy_spec": {
152
+                "ingress": [
153
+                    {"from": [
154
+                        {"namespaceSelector": {
155
+                            "matchLabels": {"name": "dev"}}}],
156
+                     "ports": [
157
+                        {"port": 6379,
158
+                         "protocol": "TCP"}]}],
159
+                "podSelector": {"matchLabels": {"app": "demo"}},
160
+                "policyTypes": ["Ingress"]},
161
+            "podSelector": {"matchLabels": {"app": "demo"}},
162
+            "securityGroupId": '36923e76-026c-422b-8dfd-7292e7c88228'}}
163
+
164
+
165
+def get_crd_obj_with_all_selectors():
166
+    return {
167
+        "kind": "KuryrNetPolicy",
168
+        "metadata": {"name": "np-test-network-policy",
169
+                     "namespace": "default"},
170
+        "spec": {
171
+            "egressSgRules": [],
172
+            "ingressSgRules": [],
173
+            "networkpolicy_spec": {
174
+                "ingress": [
175
+                    {"from": [
176
+                        {"namespaceSelector": {
177
+                            "matchLabels": {"name": "dev"}},
178
+                         "podSelector": {
179
+                            "matchLabels": {"tier": "backend"}}}],
180
+                     "ports": [
181
+                        {"port": 6379,
182
+                         "protocol": "TCP"}]}],
183
+                "podSelector": {"matchLabels": {"app": "demo"}},
184
+                "policyTypes": ["Ingress"]},
185
+            "podSelector": {"matchLabels": {"app": "demo"}},
186
+            "securityGroupId": '36923e76-026c-422b-8dfd-7292e7c88228'}}
187
+
188
+
64 189
 class TestNamespacePodSecurityGroupsDriver(test_base.TestCase):
65 190
 
66 191
     @mock.patch('kuryr_kubernetes.controller.drivers.'
@@ -165,3 +290,143 @@ class TestNamespacePodSecurityGroupsDriver(test_base.TestCase):
165 290
 
166 291
         cls.delete_sg(m_driver, sg_id)
167 292
         neutron.delete_security_group.assert_called_once_with(sg_id)
293
+
294
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
295
+                'patch_kuryr_crd')
296
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
297
+                'delete_security_group_rule')
298
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
299
+                'get_kuryrnetpolicy_crds')
300
+    def test_delete_namespace_sg_rule(self, m_get_knp_crd, m_delete_sg_rule,
301
+                                      m_patch_kuryr_crd):
302
+        cls = namespace_security_groups.NamespacePodSecurityGroupsDriver
303
+        m_driver = mock.MagicMock(spec=cls)
304
+        i_rule = get_matched_crd_obj()['spec']['ingressSgRules'][0]
305
+        sg_rule_id = i_rule.get('security_group_rule')['id']
306
+
307
+        m_get_knp_crd.return_value = {"items": [get_matched_crd_obj()]}
308
+
309
+        cls.delete_namespace_sg_rules(m_driver, get_match_crd_namespace_obj())
310
+
311
+        m_get_knp_crd.assert_called_once()
312
+        m_delete_sg_rule.assert_called_once_with(sg_rule_id)
313
+        m_patch_kuryr_crd.assert_called_once()
314
+
315
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
316
+                'patch_kuryr_crd')
317
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
318
+                'delete_security_group_rule')
319
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
320
+                'get_kuryrnetpolicy_crds')
321
+    def test_delete_namespace_sg_rule_no_match(self, m_get_knp_crd,
322
+                                               m_delete_sg_rule,
323
+                                               m_patch_kuryr_crd):
324
+        cls = namespace_security_groups.NamespacePodSecurityGroupsDriver
325
+        m_driver = mock.MagicMock(spec=cls)
326
+
327
+        m_get_knp_crd.return_value = {"items": [get_matched_crd_obj()]}
328
+
329
+        cls.delete_namespace_sg_rules(m_driver,
330
+                                      get_no_match_crd_namespace_obj())
331
+
332
+        m_get_knp_crd.assert_called_once()
333
+        m_delete_sg_rule.assert_not_called()
334
+        m_patch_kuryr_crd.assert_not_called()
335
+
336
+    @mock.patch('kuryr_kubernetes.controller.drivers.'
337
+                'namespace_security_groups._create_sg_rule')
338
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
339
+                'match_selector')
340
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
341
+                'get_namespace_subnet_cidr')
342
+    def test__parse_rules(self, m_get_ns_subnet_cidr, m_match_selector,
343
+                          m_create_sg_rule):
344
+        crd = get_crd_obj_no_match()
345
+        policy = crd['spec']['networkpolicy_spec']
346
+        i_rule = policy.get('ingress')[0]
347
+        ns_selector = i_rule['from'][0].get('namespaceSelector')
348
+        ns = get_match_crd_namespace_obj()
349
+
350
+        m_get_ns_subnet_cidr.return_value = '10.0.2.0/26'
351
+        m_match_selector.return_value = True
352
+        m_create_sg_rule.return_value = get_sg_rule()
353
+
354
+        matched, rules = namespace_security_groups._parse_rules('ingress',
355
+                                                                crd, ns)
356
+
357
+        m_get_ns_subnet_cidr.assert_called_once_with(ns)
358
+        m_match_selector.assert_called_once_with(ns_selector,
359
+                                                 ns['metadata']['labels'])
360
+        m_create_sg_rule.assert_called_once()
361
+
362
+        self.assertEqual(matched, True)
363
+        self.assertEqual(rules, [get_sg_rule()])
364
+
365
+    @mock.patch('kuryr_kubernetes.controller.drivers.'
366
+                'namespace_security_groups._create_sg_rule')
367
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
368
+                'match_selector')
369
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
370
+                'get_namespace_subnet_cidr')
371
+    def test__parse_rules_no_match(self, m_get_ns_subnet_cidr,
372
+                                   m_match_selector, m_create_sg_rule):
373
+        crd = get_crd_obj_no_match()
374
+        policy = crd['spec']['networkpolicy_spec']
375
+        i_rule = policy.get('ingress')[0]
376
+        ns_selector = i_rule['from'][0].get('namespaceSelector')
377
+        ns = get_no_match_crd_namespace_obj()
378
+
379
+        m_get_ns_subnet_cidr.return_value = '10.0.2.0/26'
380
+        m_match_selector.return_value = False
381
+
382
+        matched, rules = namespace_security_groups._parse_rules('ingress',
383
+                                                                crd, ns)
384
+
385
+        m_get_ns_subnet_cidr.assert_called_once_with(ns)
386
+        m_match_selector.assert_called_once_with(ns_selector,
387
+                                                 ns['metadata']['labels'])
388
+        m_create_sg_rule.assert_not_called()
389
+
390
+        self.assertEqual(matched, False)
391
+        self.assertEqual(rules, [])
392
+
393
+    @mock.patch('kuryr_kubernetes.controller.drivers.'
394
+                'namespace_security_groups._create_sg_rule')
395
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
396
+                'get_pod_ip')
397
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
398
+                'get_pods')
399
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
400
+                'match_selector')
401
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
402
+                'get_namespace_subnet_cidr')
403
+    def test__parse_rules_all_selectors(self, m_get_ns_subnet_cidr,
404
+                                        m_match_selector, m_get_pods,
405
+                                        m_get_pod_ip, m_create_sg_rule):
406
+        crd = get_crd_obj_with_all_selectors()
407
+        policy = crd['spec']['networkpolicy_spec']
408
+        i_rule = policy.get('ingress')[0]
409
+        ns_selector = i_rule['from'][0].get('namespaceSelector')
410
+        pod_selector = i_rule['from'][0].get('podSelector')
411
+        ns = get_match_crd_namespace_obj()
412
+        pod = get_match_crd_pod_obj()
413
+
414
+        m_get_ns_subnet_cidr.return_value = '10.0.2.0/26'
415
+        m_match_selector.return_value = True
416
+        m_get_pods.return_value = {"items": [pod]}
417
+        m_get_pod_ip.return_value = pod['status']['podIP']
418
+        m_create_sg_rule.return_value = get_sg_rule()
419
+
420
+        matched, rules = namespace_security_groups._parse_rules('ingress',
421
+                                                                crd, ns)
422
+
423
+        m_get_ns_subnet_cidr.assert_called_once_with(ns)
424
+        m_match_selector.assert_called_once_with(ns_selector,
425
+                                                 ns['metadata']['labels'])
426
+        m_get_pods.assert_called_once_with(pod_selector,
427
+                                           ns['metadata']['name'])
428
+        m_get_pod_ip.assert_called_once_with(pod)
429
+        m_create_sg_rule.assert_called_once()
430
+
431
+        self.assertEqual(matched, True)
432
+        self.assertEqual(rules, [get_sg_rule()])

+ 7
- 5
kuryr_kubernetes/tests/unit/controller/drivers/test_network_policy.py View File

@@ -302,7 +302,7 @@ class TestNetworkPolicyDriver(test_base.TestCase):
302 302
         self.kubernetes.get.side_effect = [{'items': [pod]}, net_crd]
303 303
 
304 304
         resp = self._driver._get_namespaces_cidr(namespace_selector)
305
-        self.assertEqual([subnet_cidr], resp)
305
+        self.assertEqual(subnet_cidr, resp[0].get('cidr'))
306 306
         self.kubernetes.get.assert_called()
307 307
 
308 308
     def test_get_namespaces_cidr_no_matches(self):
@@ -330,7 +330,7 @@ class TestNetworkPolicyDriver(test_base.TestCase):
330 330
     def test_parse_network_policy_rules_with_rules(self, m_create,
331 331
                                                    m_get_ns_cidr):
332 332
         subnet_cidr = '10.10.0.0/24'
333
-        m_get_ns_cidr.return_value = [subnet_cidr]
333
+        m_get_ns_cidr.return_value = [{'cidr': subnet_cidr, 'namespace': ''}]
334 334
         self._driver.parse_network_policy_rules(self._policy, self._sg_id)
335 335
         m_create.assert_called()
336 336
         m_get_ns_cidr.assert_called()
@@ -374,7 +374,7 @@ class TestNetworkPolicyDriver(test_base.TestCase):
374 374
     def test_parse_network_policy_rules_with_no_ports(self, m_create,
375 375
                                                       m_get_ns_cidr):
376 376
         subnet_cidr = '10.10.0.0/24'
377
-        m_get_ns_cidr.return_value = [subnet_cidr]
377
+        m_get_ns_cidr.return_value = [{'cidr': subnet_cidr, 'namespace': ''}]
378 378
         policy = self._policy.copy()
379 379
         selectors = {'namespaceSelector': {
380 380
                      'matchLabels': {
@@ -389,9 +389,11 @@ class TestNetworkPolicyDriver(test_base.TestCase):
389 389
         self._driver.parse_network_policy_rules(policy, self._sg_id)
390 390
         m_get_ns_cidr.assert_called()
391 391
         calls = [mock.call(self._sg_id, 'ingress', port_range_min=1,
392
-                           port_range_max=65535, cidr=subnet_cidr),
392
+                           port_range_max=65535, cidr=subnet_cidr,
393
+                           namespace=''),
393 394
                  mock.call(self._sg_id, 'egress', port_range_min=1,
394
-                           port_range_max=65535, cidr=subnet_cidr)]
395
+                           port_range_max=65535, cidr=subnet_cidr,
396
+                           namespace='')]
395 397
         m_create.assert_has_calls(calls)
396 398
 
397 399
     def test_knps_on_namespace(self):

+ 34
- 36
kuryr_kubernetes/tests/unit/controller/drivers/test_network_policy_security_groups.py View File

@@ -258,8 +258,8 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
258 258
                 'create_security_group_rule')
259 259
     @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
260 260
                 'create_security_group_rule_body')
261
-    @mock.patch.object(network_policy_security_groups,
262
-                       '_match_selector', return_value=True)
261
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
262
+                'match_selector', return_value=True)
263 263
     @mock.patch('kuryr_kubernetes.controller.drivers.utils.get_pod_ip')
264 264
     def test__create_sg_rules(self, m_get_pod_ip,
265 265
                               m_match_selector,
@@ -277,16 +277,15 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
277 277
         policy = crd['spec']['networkpolicy_spec']
278 278
         rule_list = policy.get('ingress', None)
279 279
         crd_rules = crd['spec'].get('ingressSgRules')
280
+        pod_ns = pod['metadata']['namespace']
280 281
 
281 282
         for rule_block in rule_list:
282 283
             for rule in rule_block.get('from', []):
283
-                namespace_selector = rule.get('namespaceSelector')
284 284
                 pod_selector = rule.get('podSelector')
285 285
                 matched = network_policy_security_groups._create_sg_rules(
286
-                    crd, pod, namespace_selector, pod_selector, rule_block,
287
-                    crd_rules, 'ingress', matched)
288
-                new_sg_rule['namespaceSelector'] = namespace_selector
289
-                new_sg_rule['podSelector'] = pod_selector
286
+                    crd, pod, pod_selector, rule_block,
287
+                    crd_rules, 'ingress', matched, pod_ns)
288
+                new_sg_rule['namespace'] = pod_ns
290 289
                 new_sg_rule['security_group_rule']['id'] = sgr_id
291 290
                 m_match_selector.assert_called_once_with(
292 291
                     pod_selector, pod['metadata']['labels'])
@@ -296,8 +295,8 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
296 295
                 self.assertEqual([new_sg_rule], crd_rules)
297 296
                 self.assertEqual(matched, True)
298 297
 
299
-    @mock.patch.object(network_policy_security_groups,
300
-                       '_match_selector', return_value=False)
298
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
299
+                'match_selector', return_value=False)
301 300
     def test__create_sg_rules_no_match(self, m_match_selector):
302 301
         crd = self._crd_without_rules
303 302
         pod = self._pod2
@@ -308,17 +307,16 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
308 307
 
309 308
         for rule_block in rule_list:
310 309
             for rule in rule_block.get('from', []):
311
-                namespace_selector = rule.get('namespaceSelector')
312 310
                 pod_selector = rule.get('podSelector')
313 311
                 matched = network_policy_security_groups._create_sg_rules(
314
-                    crd, pod, namespace_selector, pod_selector, rule_block,
315
-                    crd_rules, 'ingress', False)
312
+                    crd, pod, pod_selector, rule_block,
313
+                    crd_rules, 'ingress', False, self._namespace)
316 314
                 self.assertEqual(matched, False)
317 315
 
318 316
     @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
319 317
                 'patch_kuryr_crd')
320
-    @mock.patch.object(network_policy_security_groups,
321
-                       '_get_kuryrnetpolicy_crds')
318
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
319
+                'get_kuryrnetpolicy_crds')
322 320
     @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
323 321
                 'delete_security_group_rule')
324 322
     @mock.patch('kuryr_kubernetes.controller.drivers.utils.get_pod_ip')
@@ -347,8 +345,8 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
347 345
             crd, i_rules, e_rules, crd['spec'].get('podSelector'))
348 346
 
349 347
     @mock.patch('kuryr_kubernetes.config.CONF')
350
-    @mock.patch.object(network_policy_security_groups,
351
-                       '_get_kuryrnetpolicy_crds')
348
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
349
+                'get_kuryrnetpolicy_crds')
352 350
     def test_get_sgs_for_pod_without_label(self, m_get_crds, m_cfg):
353 351
         m_get_crds.return_value = self._crds
354 352
         sg_list = [str(mock.sentinel.sg_id)]
@@ -360,12 +358,12 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
360 358
         m_get_crds.assert_called_once_with(namespace=self._namespace)
361 359
         self.assertEqual(sg_list, sgs)
362 360
 
363
-    @mock.patch.object(network_policy_security_groups,
364
-                       '_match_expressions')
365
-    @mock.patch.object(network_policy_security_groups,
366
-                       '_match_labels')
367
-    @mock.patch.object(network_policy_security_groups,
368
-                       '_get_kuryrnetpolicy_crds')
361
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
362
+                'match_expressions')
363
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
364
+                'match_labels')
365
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
366
+                'get_kuryrnetpolicy_crds')
369 367
     def test_get_sgs_for_pod_with_label(self, m_get_crds, m_match_labels,
370 368
                                         m_match_expressions):
371 369
         m_get_crds.return_value = self._crds
@@ -382,12 +380,12 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
382 380
         self.assertEqual(resp, [str(self._sg_id)])
383 381
 
384 382
     @mock.patch('kuryr_kubernetes.config.CONF')
385
-    @mock.patch.object(network_policy_security_groups,
386
-                       '_match_expressions')
387
-    @mock.patch.object(network_policy_security_groups,
388
-                       '_match_labels')
389
-    @mock.patch.object(network_policy_security_groups,
390
-                       '_get_kuryrnetpolicy_crds')
383
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
384
+                'match_expressions')
385
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
386
+                'match_labels')
387
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
388
+                'get_kuryrnetpolicy_crds')
391 389
     def test_get_sgs_for_pod_with_label_no_match(self, m_get_crds,
392 390
                                                  m_match_labels,
393 391
                                                  m_match_expressions, m_cfg):
@@ -407,8 +405,8 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
407 405
             self._crd['spec']['podSelector']['matchLabels'], pod_labels)
408 406
         self.assertEqual(sg_list, sgs)
409 407
 
410
-    @mock.patch.object(network_policy_security_groups,
411
-                       '_get_kuryrnetpolicy_crds')
408
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
409
+                'get_kuryrnetpolicy_crds')
412 410
     def test_get_sgs_no_crds(self, m_get_crds):
413 411
         m_get_crds.return_value = self._empty_crds
414 412
         cfg.CONF.set_override('pod_security_groups', [],
@@ -419,12 +417,12 @@ class TestNetworkPolicySecurityGroupsDriver(test_base.TestCase):
419 417
                           self._project_id)
420 418
         m_get_crds.assert_called_with(namespace=self._namespace)
421 419
 
422
-    @mock.patch.object(network_policy_security_groups,
423
-                       '_match_expressions')
424
-    @mock.patch.object(network_policy_security_groups,
425
-                       '_match_labels')
426
-    @mock.patch.object(network_policy_security_groups,
427
-                       '_get_kuryrnetpolicy_crds')
420
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
421
+                'match_expressions')
422
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
423
+                'match_labels')
424
+    @mock.patch('kuryr_kubernetes.controller.drivers.utils.'
425
+                'get_kuryrnetpolicy_crds')
428 426
     def test_get_sgs_multiple_crds(self, m_get_crds, m_match_labels,
429 427
                                    m_match_expressions):
430 428
         m_match_expressions.return_value = True

Loading…
Cancel
Save