Browse Source

Merge "Fix fail to recreate namespace when previous KuryrNet CRD is not deleted" into stable/rocky

stable/rocky
Zuul 3 weeks ago
parent
commit
ef4a312dea

+ 30
- 9
kuryr_kubernetes/controller/handlers/namespace.py View File

@@ -46,6 +46,15 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
46 46
             LOG.debug("CRD existing at the new namespace")
47 47
             return
48 48
 
49
+        net_crd_name = 'ns-' + ns_name
50
+        net_crd = self._get_net_crd(net_crd_name)
51
+        if net_crd:
52
+            LOG.debug("Previous CRD existing at the new namespace. "
53
+                      "Deleting namespace resources and retrying its "
54
+                      "creation.")
55
+            self.on_deleted(namespace, net_crd)
56
+            raise exceptions.ResourceNotReady(namespace)
57
+
49 58
         LOG.debug("Creating network resources for namespace: %s", ns_name)
50 59
         net_crd_spec = self._drv_subnets.create_namespace_network(ns_name,
51 60
                                                                   project_id)
@@ -67,20 +76,29 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
67 76
         try:
68 77
             net_crd = self._add_kuryrnet_crd(ns_name, net_crd_spec)
69 78
             self._set_net_crd(namespace, net_crd)
79
+        except exceptions.K8sResourceNotFound:
80
+            LOG.debug("Namespace could not be annotated. Rolling back "
81
+                      "resources created for it.")
82
+            self._drv_subnets.rollback_network_resources(net_crd_spec, ns_name)
83
+            self._drv_sg.delete_sg(net_crd_sg['sgId'])
84
+            self._del_kuryrnet_crd(net_crd_name)
70 85
         except exceptions.K8sClientException:
71 86
             LOG.exception("Kuryrnet CRD could not be added. Rolling back "
72 87
                           "network resources created for the namespace.")
73 88
             self._drv_subnets.rollback_network_resources(net_crd_spec, ns_name)
74 89
             self._drv_sg.delete_sg(net_crd_sg['sgId'])
75 90
 
76
-    def on_deleted(self, namespace):
91
+    def on_deleted(self, namespace, net_crd=None):
77 92
         LOG.debug("Deleting namespace: %s", namespace)
78
-        net_crd_id = self._get_net_crd_id(namespace)
79
-        if not net_crd_id:
80
-            LOG.warning("There is no CRD annotated at the namespace %s",
81
-                        namespace)
82
-            return
83
-        net_crd = self._get_net_crd(net_crd_id)
93
+        if not net_crd:
94
+            net_crd_id = self._get_net_crd_id(namespace)
95
+            if not net_crd_id:
96
+                LOG.warning("There is no CRD annotated at the namespace %s",
97
+                            namespace)
98
+                return
99
+            net_crd = self._get_net_crd(net_crd_id)
100
+
101
+        net_crd_name = 'ns-' + namespace['metadata']['name']
84 102
 
85 103
         self._drv_vif_pool.delete_network_pools(net_crd['spec']['netId'])
86 104
         try:
@@ -98,8 +116,7 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
98 116
         else:
99 117
             LOG.debug("There is no security group associated with the "
100 118
                       "namespace to be deleted")
101
-
102
-        self._del_kuryrnet_crd(net_crd_id)
119
+        self._del_kuryrnet_crd(net_crd_name)
103 120
 
104 121
     def _get_net_crd_id(self, namespace):
105 122
         try:
@@ -114,6 +131,8 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
114 131
         try:
115 132
             kuryrnet_crd = k8s.get('%s/kuryrnets/%s' % (constants.K8S_API_CRD,
116 133
                                                         net_crd_id))
134
+        except exceptions.K8sResourceNotFound:
135
+            return None
117 136
         except exceptions.K8sClientException:
118 137
             LOG.exception("Kubernetes Client Exception.")
119 138
             raise
@@ -156,6 +175,8 @@ class NamespaceHandler(k8s_base.ResourceEventHandler):
156 175
         try:
157 176
             kubernetes.delete('%s/kuryrnets/%s' % (constants.K8S_API_CRD,
158 177
                                                    net_crd_name))
178
+        except exceptions.K8sResourceNotFound:
179
+            LOG.debug("KuryrNetPolicy CRD not found: %s", net_crd_name)
159 180
         except exceptions.K8sClientException:
160 181
             LOG.exception("Kubernetes Client Exception deleting kuryrnet "
161 182
                           "CRD.")

+ 18
- 1
kuryr_kubernetes/tests/unit/controller/handlers/test_namespace.py View File

@@ -42,6 +42,7 @@ class TestNamespaceHandler(test_base.TestCase):
42 42
                          'selfLink': self._namespace_link},
43 43
             'status': {'phase': 'Active'}
44 44
         }
45
+        self._crd_id = 'ns-' + self._namespace_name
45 46
 
46 47
         self._handler = mock.MagicMock(spec=namespace.NamespaceHandler)
47 48
 
@@ -79,6 +80,9 @@ class TestNamespaceHandler(test_base.TestCase):
79 80
     def _get_crd(self):
80 81
         crd = {
81 82
             'kind': 'KuryrNet',
83
+            'metadata': {
84
+                'selfLink': mock.sentinel.self_link
85
+            },
82 86
             'spec': {
83 87
                 'routerId': mock.sentinel.router_id,
84 88
                 'netId': mock.sentinel.net_id,
@@ -114,6 +118,7 @@ class TestNamespaceHandler(test_base.TestCase):
114 118
     def test_on_present(self):
115 119
         net_crd = self._get_crd()
116 120
         self._get_net_crd_id.return_value = None
121
+        self._get_net_crd.return_value = None
117 122
         self._create_namespace_network.return_value = {'test_net': 'uuid'}
118 123
         self._create_namespace_sg.return_value = {'test_sg': 'uuid'}
119 124
         net_crd_spec = {'test_net': 'uuid', 'test_sg': 'uuid'}
@@ -122,6 +127,7 @@ class TestNamespaceHandler(test_base.TestCase):
122 127
         namespace.NamespaceHandler.on_present(self._handler, self._namespace)
123 128
 
124 129
         self._get_net_crd_id.assert_called_once_with(self._namespace)
130
+        self._get_net_crd.assert_called_once_with(self._crd_id)
125 131
         self._create_namespace_network.assert_called_once_with(
126 132
             self._namespace_name, self._project_id)
127 133
         self._create_namespace_sg.assert_called_once_with(
@@ -142,6 +148,7 @@ class TestNamespaceHandler(test_base.TestCase):
142 148
 
143 149
     def test_on_present_create_network_exception(self):
144 150
         self._get_net_crd_id.return_value = None
151
+        self._get_net_crd.return_value = None
145 152
         self._create_namespace_network.side_effect = (
146 153
             n_exc.NeutronClientException)
147 154
 
@@ -150,6 +157,7 @@ class TestNamespaceHandler(test_base.TestCase):
150 157
                           self._handler, self._namespace)
151 158
 
152 159
         self._get_net_crd_id.assert_called_once_with(self._namespace)
160
+        self._get_net_crd.assert_called_once_with(self._crd_id)
153 161
         self._create_namespace_network.assert_called_once_with(
154 162
             self._namespace_name, self._project_id)
155 163
         self._create_namespace_sg.assert_not_called()
@@ -157,6 +165,7 @@ class TestNamespaceHandler(test_base.TestCase):
157 165
 
158 166
     def test_on_present_create_sg_exception(self):
159 167
         self._get_net_crd_id.return_value = None
168
+        self._get_net_crd.return_value = None
160 169
         self._create_namespace_network.return_value = {'test_net': 'uuid'}
161 170
         self._create_namespace_sg.side_effect = (
162 171
             n_exc.NeutronClientException)
@@ -166,6 +175,7 @@ class TestNamespaceHandler(test_base.TestCase):
166 175
                           self._handler, self._namespace)
167 176
 
168 177
         self._get_net_crd_id.assert_called_once_with(self._namespace)
178
+        self._get_net_crd.assert_called_once_with(self._crd_id)
169 179
         self._create_namespace_network.assert_called_once_with(
170 180
             self._namespace_name, self._project_id)
171 181
         self._create_namespace_sg.assert_called_once_with(
@@ -174,6 +184,7 @@ class TestNamespaceHandler(test_base.TestCase):
174 184
 
175 185
     def test_on_present_add_kuryrnet_crd_exception(self):
176 186
         self._get_net_crd_id.return_value = None
187
+        self._get_net_crd.return_value = None
177 188
         self._create_namespace_network.return_value = {'test_net': 'uuid'}
178 189
         self._create_namespace_sg.return_value = {'sgId': 'uuid'}
179 190
         net_crd_spec = {'test_net': 'uuid', 'sgId': 'uuid'}
@@ -182,6 +193,7 @@ class TestNamespaceHandler(test_base.TestCase):
182 193
         namespace.NamespaceHandler.on_present(self._handler, self._namespace)
183 194
 
184 195
         self._get_net_crd_id.assert_called_once_with(self._namespace)
196
+        self._get_net_crd.assert_called_once_with(self._crd_id)
185 197
         self._create_namespace_network.assert_called_once_with(
186 198
             self._namespace_name, self._project_id)
187 199
         self._create_namespace_sg.assert_called_once_with(
@@ -195,6 +207,7 @@ class TestNamespaceHandler(test_base.TestCase):
195 207
         net_crd = self._get_crd()
196 208
 
197 209
         self._get_net_crd_id.return_value = None
210
+        self._get_net_crd.return_value = None
198 211
         self._create_namespace_network.return_value = {'test_net': 'uuid'}
199 212
         self._create_namespace_sg.return_value = {'sgId': 'uuid'}
200 213
         net_crd_spec = {'test_net': 'uuid', 'sgId': 'uuid'}
@@ -204,6 +217,7 @@ class TestNamespaceHandler(test_base.TestCase):
204 217
         namespace.NamespaceHandler.on_present(self._handler, self._namespace)
205 218
 
206 219
         self._get_net_crd_id.assert_called_once_with(self._namespace)
220
+        self._get_net_crd.assert_called_once_with(self._crd_id)
207 221
         self._create_namespace_network.assert_called_once_with(
208 222
             self._namespace_name, self._project_id)
209 223
         self._create_namespace_sg.assert_called_once_with(
@@ -217,6 +231,7 @@ class TestNamespaceHandler(test_base.TestCase):
217 231
         net_crd = self._get_crd()
218 232
 
219 233
         self._get_net_crd_id.return_value = None
234
+        self._get_net_crd.return_value = None
220 235
         self._create_namespace_network.return_value = {'test_net': 'uuid'}
221 236
         self._create_namespace_sg.return_value = {'sgId': 'uuid'}
222 237
         net_crd_spec = {'test_net': 'uuid', 'sgId': 'uuid'}
@@ -230,6 +245,7 @@ class TestNamespaceHandler(test_base.TestCase):
230 245
                           self._handler, self._namespace)
231 246
 
232 247
         self._get_net_crd_id.assert_called_once_with(self._namespace)
248
+        self._get_net_crd.assert_called_once_with(self._crd_id)
233 249
         self._create_namespace_network.assert_called_once_with(
234 250
             self._namespace_name, self._project_id)
235 251
         self._create_namespace_sg.assert_called_once_with(
@@ -249,12 +265,13 @@ class TestNamespaceHandler(test_base.TestCase):
249 265
         namespace.NamespaceHandler.on_deleted(self._handler, self._namespace)
250 266
 
251 267
         self._get_net_crd_id.assert_called_once_with(self._namespace)
268
+
252 269
         self._get_net_crd.assert_called_once_with(net_crd_id)
253 270
         self._delete_network_pools.assert_called_once_with(
254 271
             net_crd['spec']['netId'])
255 272
         self._delete_namespace_subnet.assert_called_once_with(net_crd)
256 273
         self._delete_sg.assert_called_once_with(net_crd['spec']['sgId'])
257
-        self._del_kuryrnet_crd.assert_called_once_with(net_crd_id)
274
+        self._del_kuryrnet_crd.assert_called_once_with(self._crd_id)
258 275
 
259 276
     def test_on_deleted_missing_crd_annotation(self):
260 277
         self._get_net_crd_id.return_value = None

Loading…
Cancel
Save