From b0b78b423c37c3a959da1e3ec417e0b980b29f3b Mon Sep 17 00:00:00 2001
From: Maysa Macedo <maysa.macedo95@gmail.com>
Date: Mon, 21 Oct 2019 15:54:57 +0000
Subject: [PATCH] Ensure LB SG is not updated for egress only policy

When an egress Network Policy is enforced, there is no
need to allow the update of the LB SG. Right now, as this
operation is being allowed, we can end up with ingress
rules being removed from the LB.

Closes-Bug: 1850715
Change-Id: Idcdef5c4f2f47a165bfb9b38779b591d5b995216
---
 .../drivers/network_policy_security_groups.py        |  4 ++++
 kuryr_kubernetes/controller/drivers/utils.py         |  2 ++
 kuryr_kubernetes/controller/handlers/policy.py       | 12 ++++++++++--
 .../tests/unit/controller/handlers/test_policy.py    |  1 +
 4 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/kuryr_kubernetes/controller/drivers/network_policy_security_groups.py b/kuryr_kubernetes/controller/drivers/network_policy_security_groups.py
index 5febe1d4b..c7ade9bbb 100644
--- a/kuryr_kubernetes/controller/drivers/network_policy_security_groups.py
+++ b/kuryr_kubernetes/controller/drivers/network_policy_security_groups.py
@@ -472,6 +472,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
                 driver_utils.patch_kuryrnetworkpolicy_crd(crd, i_rules,
                                                           e_rules,
                                                           crd_selector)
+            if i_matched:
                 crd_pod_selectors.append(crd_selector)
         return crd_pod_selectors
 
@@ -498,6 +499,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
                 driver_utils.patch_kuryrnetworkpolicy_crd(crd, i_rules,
                                                           e_rules,
                                                           crd_selector)
+            if i_matched:
                 crd_pod_selectors.append(crd_selector)
         return crd_pod_selectors
 
@@ -528,6 +530,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
             if i_matched or e_matched:
                 driver_utils.patch_kuryrnetworkpolicy_crd(
                     crd, i_rules, e_rules, crd_selector)
+            if i_matched:
                 crd_selectors.append(crd_selector)
         return crd_selectors
 
@@ -548,6 +551,7 @@ class NetworkPolicySecurityGroupsDriver(base.PodSecurityGroupsDriver):
                 driver_utils.patch_kuryrnetworkpolicy_crd(crd, i_rules,
                                                           e_rules,
                                                           crd_selector)
+            if i_matched:
                 crd_selectors.append(crd_selector)
         return crd_selectors
 
diff --git a/kuryr_kubernetes/controller/drivers/utils.py b/kuryr_kubernetes/controller/drivers/utils.py
index d9333dda5..0fba0f376 100644
--- a/kuryr_kubernetes/controller/drivers/utils.py
+++ b/kuryr_kubernetes/controller/drivers/utils.py
@@ -243,6 +243,8 @@ def patch_kuryrnetworkpolicy_crd(crd, i_rules, e_rules, pod_selector,
                               'egressSgRules': e_rules,
                               'podSelector': pod_selector,
                               'networkpolicy_spec': np_spec})
+    except k_exc.K8sResourceNotFound:
+        LOG.debug('KuryrNetPolicy CRD not found %s', crd_name)
     except k_exc.K8sClientException:
         LOG.exception('Error updating kuryrnetpolicy CRD %s', crd_name)
         raise
diff --git a/kuryr_kubernetes/controller/handlers/policy.py b/kuryr_kubernetes/controller/handlers/policy.py
index 42bf20e50..5227011df 100644
--- a/kuryr_kubernetes/controller/handlers/policy.py
+++ b/kuryr_kubernetes/controller/handlers/policy.py
@@ -79,7 +79,8 @@ class NetworkPolicyHandler(k8s_base.ResourceEventHandler):
             self._drv_vif_pool.update_vif_sgs(pod, pod_sgs)
 
         if (pods_to_update and
-                oslo_cfg.CONF.octavia_defaults.enforce_sg_rules):
+                oslo_cfg.CONF.octavia_defaults.enforce_sg_rules and
+                not self._is_egress_only_policy(policy)):
             # NOTE(ltomasbo): only need to change services if the pods that
             # they point to are updated
             services = driver_utils.get_services(
@@ -123,7 +124,8 @@ class NetworkPolicyHandler(k8s_base.ResourceEventHandler):
 
             self._drv_policy.release_network_policy(netpolicy_crd)
 
-            if oslo_cfg.CONF.octavia_defaults.enforce_sg_rules:
+            if (oslo_cfg.CONF.octavia_defaults.enforce_sg_rules and
+                    not self._is_egress_only_policy(policy)):
                 services = driver_utils.get_services(
                     policy['metadata']['namespace'])
                 for svc in services.get('items'):
@@ -167,3 +169,9 @@ class NetworkPolicyHandler(k8s_base.ResourceEventHandler):
             LOG.exception("Kubernetes Client Exception.")
             raise
         return net_crd['spec']['netId']
+
+    def _is_egress_only_policy(self, policy):
+        policy_types = policy['spec'].get('policyTypes', [])
+        return (policy_types == ['Egress'] or
+                (policy['spec'].get('egress') and
+                    not policy['spec'].get('ingress')))
diff --git a/kuryr_kubernetes/tests/unit/controller/handlers/test_policy.py b/kuryr_kubernetes/tests/unit/controller/handlers/test_policy.py
index 3c1c94256..c4eaebe4b 100644
--- a/kuryr_kubernetes/tests/unit/controller/handlers/test_policy.py
+++ b/kuryr_kubernetes/tests/unit/controller/handlers/test_policy.py
@@ -188,6 +188,7 @@ class TestPolicyHandler(test_base.TestCase):
         match_pod = mock.sentinel.match_pod
         m_host_network.return_value = False
 
+        self._handler._is_egress_only_policy.return_value = False
         self._handler._is_service_affected.return_value = True
         knp_on_ns = self._handler._drv_policy.knps_on_namespace
         knp_on_ns.return_value = True