octavia 14.0.0.0rc1__py3-none-any.whl → 14.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- octavia/amphorae/backends/agent/api_server/keepalivedlvs.py +9 -0
- octavia/amphorae/backends/agent/api_server/osutils.py +4 -2
- octavia/amphorae/backends/agent/api_server/plug.py +5 -4
- octavia/amphorae/backends/agent/api_server/server.py +3 -2
- octavia/amphorae/backends/agent/api_server/util.py +35 -2
- octavia/amphorae/backends/utils/interface.py +2 -37
- octavia/amphorae/backends/utils/interface_file.py +23 -10
- octavia/amphorae/backends/utils/nftable_utils.py +33 -11
- octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +0 -1
- octavia/amphorae/drivers/keepalived/jinja/templates/keepalived_base.template +0 -1
- octavia/api/common/pagination.py +1 -1
- octavia/api/v2/controllers/health_monitor.py +3 -1
- octavia/api/v2/controllers/load_balancer.py +7 -0
- octavia/api/v2/controllers/member.py +12 -2
- octavia/common/clients.py +7 -1
- octavia/common/constants.py +3 -3
- octavia/controller/worker/v2/controller_worker.py +2 -2
- octavia/controller/worker/v2/flows/amphora_flows.py +14 -3
- octavia/controller/worker/v2/flows/flow_utils.py +6 -4
- octavia/controller/worker/v2/flows/listener_flows.py +17 -5
- octavia/controller/worker/v2/tasks/database_tasks.py +10 -6
- octavia/controller/worker/v2/tasks/network_tasks.py +27 -16
- octavia/db/base_models.py +16 -4
- octavia/network/drivers/neutron/allowed_address_pairs.py +3 -2
- octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +1 -1
- octavia/tests/functional/api/v2/test_health_monitor.py +18 -0
- octavia/tests/functional/api/v2/test_member.py +32 -0
- octavia/tests/unit/amphorae/backends/agent/api_server/test_osutils.py +1 -1
- octavia/tests/unit/amphorae/backends/agent/api_server/test_plug.py +4 -3
- octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +89 -1
- octavia/tests/unit/amphorae/backends/utils/test_interface.py +3 -64
- octavia/tests/unit/amphorae/backends/utils/test_nftable_utils.py +28 -22
- octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +0 -4
- octavia/tests/unit/api/common/test_pagination.py +78 -1
- octavia/tests/unit/cmd/test_prometheus_proxy.py +8 -1
- octavia/tests/unit/controller/worker/v2/flows/test_listener_flows.py +10 -15
- octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +4 -6
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +28 -6
- octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +71 -2
- octavia/tests/unit/controller/worker/v2/test_controller_worker.py +56 -1
- octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +2 -1
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/AUTHORS +5 -0
- octavia-14.0.2.dist-info/METADATA +156 -0
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/RECORD +59 -59
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/WHEEL +1 -1
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/entry_points.txt +0 -1
- octavia-14.0.2.dist-info/pbr.json +1 -0
- octavia-14.0.0.0rc1.dist-info/METADATA +0 -158
- octavia-14.0.0.0rc1.dist-info/pbr.json +0 -1
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/LICENSE +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/README.rst +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/README.rst +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/data/share/octavia/diskimage-create/version.txt +0 -0
- {octavia-14.0.0.0rc1.data → octavia-14.0.2.data}/scripts/octavia-wsgi +0 -0
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/LICENSE +0 -0
- {octavia-14.0.0.0rc1.dist-info → octavia-14.0.2.dist-info}/top_level.txt +0 -0
@@ -103,6 +103,16 @@ class TestPaginationHelper(base.TestCase):
|
|
103
103
|
helper.apply(query_mock, models.LoadBalancer)
|
104
104
|
self.assertEqual(params, helper.filters)
|
105
105
|
|
106
|
+
@mock.patch('octavia.api.common.pagination.request')
|
107
|
+
def test_filter_with_booleans(self, request_mock):
|
108
|
+
params = {'backup': 'True', 'admin_state_up': 'false'}
|
109
|
+
expected_params = {'backup': True, 'enabled': False}
|
110
|
+
helper = pagination.PaginationHelper(params)
|
111
|
+
query_mock = mock.MagicMock()
|
112
|
+
|
113
|
+
helper.apply(query_mock, models.Member)
|
114
|
+
self.assertEqual(expected_params, helper.filters)
|
115
|
+
|
106
116
|
@mock.patch('octavia.api.common.pagination.request')
|
107
117
|
def test_filter_mismatched_params(self, request_mock):
|
108
118
|
params = {
|
@@ -227,12 +237,46 @@ class TestPaginationHelper(base.TestCase):
|
|
227
237
|
helper = pagination.PaginationHelper(params)
|
228
238
|
links = helper._make_links(model_list)
|
229
239
|
self.assertEqual(links[0].rel, "previous")
|
240
|
+
self.assertEqual(
|
241
|
+
links[0].href,
|
242
|
+
("{base_uri}{path}?limit={limit}&marker={marker}"
|
243
|
+
"&page_reverse=True").format(
|
244
|
+
base_uri=api_base_uri,
|
245
|
+
path=request_mock.path,
|
246
|
+
limit=params['limit'],
|
247
|
+
marker=member1.id
|
248
|
+
))
|
249
|
+
self.assertEqual(links[1].rel, "next")
|
230
250
|
self.assertEqual(
|
231
251
|
links[1].href,
|
232
252
|
"{base_uri}{path}?limit={limit}&marker={marker}".format(
|
233
253
|
base_uri=api_base_uri,
|
234
254
|
path=request_mock.path,
|
235
255
|
limit=params['limit'],
|
256
|
+
marker=member1.id))
|
257
|
+
|
258
|
+
@mock.patch('octavia.api.common.pagination.request')
|
259
|
+
def test_make_links_with_zero_limit(self, request_mock):
|
260
|
+
request_mock.path = "/lbaas/v2/pools/1/members"
|
261
|
+
request_mock.path_url = "http://localhost" + request_mock.path
|
262
|
+
api_base_uri = "https://127.0.0.1"
|
263
|
+
conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
|
264
|
+
conf.config(group='api_settings', api_base_uri=api_base_uri)
|
265
|
+
member1 = models.Member()
|
266
|
+
member1.id = uuidutils.generate_uuid()
|
267
|
+
model_list = [member1]
|
268
|
+
|
269
|
+
params = {'limit': 0, 'marker': member1.id}
|
270
|
+
helper = pagination.PaginationHelper(params)
|
271
|
+
links = helper._make_links(model_list)
|
272
|
+
self.assertEqual(links[0].rel, "previous")
|
273
|
+
self.assertEqual(
|
274
|
+
links[0].href,
|
275
|
+
("{base_uri}{path}?limit={limit}&marker={marker}"
|
276
|
+
"&page_reverse=True").format(
|
277
|
+
base_uri=api_base_uri,
|
278
|
+
path=request_mock.path,
|
279
|
+
limit=None,
|
236
280
|
marker=member1.id
|
237
281
|
))
|
238
282
|
self.assertEqual(links[1].rel, "next")
|
@@ -241,5 +285,38 @@ class TestPaginationHelper(base.TestCase):
|
|
241
285
|
"{base_uri}{path}?limit={limit}&marker={marker}".format(
|
242
286
|
base_uri=api_base_uri,
|
243
287
|
path=request_mock.path,
|
244
|
-
limit=
|
288
|
+
limit=None,
|
289
|
+
marker=member1.id))
|
290
|
+
|
291
|
+
@mock.patch('octavia.api.common.pagination.request')
|
292
|
+
def test_make_links_with_negative_limit(self, request_mock):
|
293
|
+
request_mock.path = "/lbaas/v2/pools/1/members"
|
294
|
+
request_mock.path_url = "http://localhost" + request_mock.path
|
295
|
+
api_base_uri = "https://127.0.0.1"
|
296
|
+
conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
|
297
|
+
conf.config(group='api_settings', api_base_uri=api_base_uri)
|
298
|
+
member1 = models.Member()
|
299
|
+
member1.id = uuidutils.generate_uuid()
|
300
|
+
model_list = [member1]
|
301
|
+
|
302
|
+
params = {'limit': -1, 'marker': member1.id}
|
303
|
+
helper = pagination.PaginationHelper(params)
|
304
|
+
links = helper._make_links(model_list)
|
305
|
+
self.assertEqual(links[0].rel, "previous")
|
306
|
+
self.assertEqual(
|
307
|
+
links[0].href,
|
308
|
+
("{base_uri}{path}?limit={limit}&marker={marker}"
|
309
|
+
"&page_reverse=True").format(
|
310
|
+
base_uri=api_base_uri,
|
311
|
+
path=request_mock.path,
|
312
|
+
limit=None,
|
313
|
+
marker=member1.id
|
314
|
+
))
|
315
|
+
self.assertEqual(links[1].rel, "next")
|
316
|
+
self.assertEqual(
|
317
|
+
links[1].href,
|
318
|
+
"{base_uri}{path}?limit={limit}&marker={marker}".format(
|
319
|
+
base_uri=api_base_uri,
|
320
|
+
path=request_mock.path,
|
321
|
+
limit=None,
|
245
322
|
marker=member1.id))
|
@@ -147,6 +147,7 @@ class TestPrometheusProxyCMD(base.TestCase):
|
|
147
147
|
mock_http.shutdown.assert_called_once()
|
148
148
|
|
149
149
|
@mock.patch('threading.Thread')
|
150
|
+
@mock.patch('http.server.ThreadingHTTPServer.__init__')
|
150
151
|
@mock.patch('http.server.ThreadingHTTPServer.serve_forever')
|
151
152
|
@mock.patch('octavia.amphorae.backends.utils.network_namespace.'
|
152
153
|
'NetworkNamespace.__exit__')
|
@@ -155,12 +156,18 @@ class TestPrometheusProxyCMD(base.TestCase):
|
|
155
156
|
@mock.patch('octavia.cmd.prometheus_proxy.EXIT_EVENT')
|
156
157
|
@mock.patch('octavia.cmd.prometheus_proxy.SignalHandler')
|
157
158
|
def test_main(self, mock_signal_handler, mock_exit_event, mock_netns_enter,
|
158
|
-
mock_netns_exit, mock_serve_forever,
|
159
|
+
mock_netns_exit, mock_serve_forever, mock_server_init,
|
160
|
+
mock_thread):
|
159
161
|
|
160
162
|
mock_exit_event.is_set.side_effect = [False, False, True]
|
161
163
|
mock_netns_enter.side_effect = [Exception('boom'), True]
|
162
164
|
|
165
|
+
mock_server_init.return_value = None
|
166
|
+
|
163
167
|
prometheus_proxy.main()
|
164
168
|
|
165
169
|
mock_signal_handler.assert_called_once()
|
170
|
+
mock_server_init.assert_called_once_with(
|
171
|
+
('127.0.0.1', 9102),
|
172
|
+
prometheus_proxy.PrometheusProxy)
|
166
173
|
mock_serve_forever.assert_called_once()
|
@@ -44,15 +44,14 @@ class TestListenerFlows(base.TestCase):
|
|
44
44
|
|
45
45
|
self.assertIn(constants.LISTENERS, listener_flow.requires)
|
46
46
|
self.assertIn(constants.LOADBALANCER_ID, listener_flow.requires)
|
47
|
-
self.assertIn(constants.AMPHORAE_STATUS, listener_flow.requires)
|
48
47
|
|
49
48
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG,
|
50
49
|
listener_flow.provides)
|
51
50
|
self.assertIn(constants.AMPHORAE, listener_flow.provides)
|
52
51
|
self.assertIn(constants.AMPHORA_FIREWALL_RULES, listener_flow.provides)
|
53
52
|
|
54
|
-
self.assertEqual(
|
55
|
-
self.assertEqual(
|
53
|
+
self.assertEqual(2, len(listener_flow.requires))
|
54
|
+
self.assertEqual(4, len(listener_flow.provides))
|
56
55
|
|
57
56
|
def test_get_delete_listener_flow(self, mock_get_net_driver):
|
58
57
|
flavor_dict = {
|
@@ -66,15 +65,14 @@ class TestListenerFlows(base.TestCase):
|
|
66
65
|
self.assertIn(constants.LISTENER, listener_flow.requires)
|
67
66
|
self.assertIn(constants.LOADBALANCER_ID, listener_flow.requires)
|
68
67
|
self.assertIn(constants.PROJECT_ID, listener_flow.requires)
|
69
|
-
self.assertIn(constants.AMPHORAE_STATUS, listener_flow.requires)
|
70
68
|
|
71
69
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG,
|
72
70
|
listener_flow.provides)
|
73
71
|
self.assertIn(constants.AMPHORAE, listener_flow.provides)
|
74
72
|
self.assertIn(constants.AMPHORA_FIREWALL_RULES, listener_flow.provides)
|
75
73
|
|
76
|
-
self.assertEqual(
|
77
|
-
self.assertEqual(
|
74
|
+
self.assertEqual(3, len(listener_flow.requires))
|
75
|
+
self.assertEqual(4, len(listener_flow.provides))
|
78
76
|
|
79
77
|
def test_get_delete_listener_internal_flow(self, mock_get_net_driver):
|
80
78
|
flavor_dict = {
|
@@ -88,15 +86,14 @@ class TestListenerFlows(base.TestCase):
|
|
88
86
|
|
89
87
|
self.assertIn(constants.LOADBALANCER_ID, listener_flow.requires)
|
90
88
|
self.assertIn(constants.PROJECT_ID, listener_flow.requires)
|
91
|
-
self.assertIn(constants.AMPHORAE_STATUS, listener_flow.requires)
|
92
89
|
|
93
90
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG,
|
94
91
|
listener_flow.provides)
|
95
92
|
self.assertIn(constants.AMPHORAE, listener_flow.provides)
|
96
93
|
self.assertIn(constants.AMPHORA_FIREWALL_RULES, listener_flow.provides)
|
97
94
|
|
98
|
-
self.assertEqual(
|
99
|
-
self.assertEqual(
|
95
|
+
self.assertEqual(2, len(listener_flow.requires))
|
96
|
+
self.assertEqual(4, len(listener_flow.provides))
|
100
97
|
|
101
98
|
def test_get_update_listener_flow(self, mock_get_net_driver):
|
102
99
|
flavor_dict = {
|
@@ -112,15 +109,14 @@ class TestListenerFlows(base.TestCase):
|
|
112
109
|
self.assertIn(constants.UPDATE_DICT, listener_flow.requires)
|
113
110
|
self.assertIn(constants.LISTENERS, listener_flow.requires)
|
114
111
|
self.assertIn(constants.LOADBALANCER_ID, listener_flow.requires)
|
115
|
-
self.assertIn(constants.AMPHORAE_STATUS, listener_flow.requires)
|
116
112
|
|
117
113
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG,
|
118
114
|
listener_flow.provides)
|
119
115
|
self.assertIn(constants.AMPHORAE, listener_flow.provides)
|
120
116
|
self.assertIn(constants.AMPHORA_FIREWALL_RULES, listener_flow.provides)
|
121
117
|
|
122
|
-
self.assertEqual(
|
123
|
-
self.assertEqual(
|
118
|
+
self.assertEqual(4, len(listener_flow.requires))
|
119
|
+
self.assertEqual(4, len(listener_flow.provides))
|
124
120
|
|
125
121
|
def test_get_create_all_listeners_flow(self, mock_get_net_driver):
|
126
122
|
flavor_dict = {
|
@@ -131,12 +127,11 @@ class TestListenerFlows(base.TestCase):
|
|
131
127
|
self.assertIsInstance(listeners_flow, flow.Flow)
|
132
128
|
self.assertIn(constants.LOADBALANCER, listeners_flow.requires)
|
133
129
|
self.assertIn(constants.LOADBALANCER_ID, listeners_flow.requires)
|
134
|
-
self.assertIn(constants.AMPHORAE_STATUS, listeners_flow.requires)
|
135
130
|
self.assertIn(constants.LOADBALANCER, listeners_flow.provides)
|
136
131
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG,
|
137
132
|
listeners_flow.provides)
|
138
133
|
self.assertIn(constants.AMPHORAE, listeners_flow.provides)
|
139
134
|
self.assertIn(constants.AMPHORA_FIREWALL_RULES,
|
140
135
|
listeners_flow.provides)
|
141
|
-
self.assertEqual(
|
142
|
-
self.assertEqual(
|
136
|
+
self.assertEqual(2, len(listeners_flow.requires))
|
137
|
+
self.assertEqual(6, len(listeners_flow.provides))
|
@@ -344,7 +344,6 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
344
344
|
self.assertIn(constants.FLAVOR, failover_flow.requires)
|
345
345
|
self.assertIn(constants.LOADBALANCER, failover_flow.requires)
|
346
346
|
self.assertIn(constants.LOADBALANCER_ID, failover_flow.requires)
|
347
|
-
self.assertIn(constants.AMPHORAE_STATUS, failover_flow.requires)
|
348
347
|
|
349
348
|
self.assertIn(constants.UPDATED_PORTS, failover_flow.provides)
|
350
349
|
self.assertIn(constants.AMPHORA, failover_flow.provides)
|
@@ -364,9 +363,9 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
364
363
|
self.assertIn(constants.SUBNET, failover_flow.provides)
|
365
364
|
self.assertIn(constants.NEW_AMPHORAE, failover_flow.provides)
|
366
365
|
|
367
|
-
self.assertEqual(
|
366
|
+
self.assertEqual(6, len(failover_flow.requires),
|
368
367
|
failover_flow.requires)
|
369
|
-
self.assertEqual(
|
368
|
+
self.assertEqual(17, len(failover_flow.provides),
|
370
369
|
failover_flow.provides)
|
371
370
|
|
372
371
|
@mock.patch('octavia.common.rpc.NOTIFIER',
|
@@ -424,7 +423,6 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
424
423
|
self.assertIn(constants.FLAVOR, failover_flow.requires)
|
425
424
|
self.assertIn(constants.LOADBALANCER, failover_flow.requires)
|
426
425
|
self.assertIn(constants.LOADBALANCER_ID, failover_flow.requires)
|
427
|
-
self.assertIn(constants.AMPHORAE_STATUS, failover_flow.requires)
|
428
426
|
|
429
427
|
self.assertIn(constants.UPDATED_PORTS, failover_flow.provides)
|
430
428
|
self.assertIn(constants.AMPHORA, failover_flow.provides)
|
@@ -445,9 +443,9 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
445
443
|
self.assertIn(constants.SUBNET, failover_flow.provides)
|
446
444
|
self.assertIn(constants.NEW_AMPHORAE, failover_flow.provides)
|
447
445
|
|
448
|
-
self.assertEqual(
|
446
|
+
self.assertEqual(6, len(failover_flow.requires),
|
449
447
|
failover_flow.requires)
|
450
|
-
self.assertEqual(
|
448
|
+
self.assertEqual(17, len(failover_flow.provides),
|
451
449
|
failover_flow.provides)
|
452
450
|
|
453
451
|
@mock.patch('octavia.common.rpc.NOTIFIER',
|
@@ -184,7 +184,9 @@ class TestDatabaseTasks(base.TestCase):
|
|
184
184
|
|
185
185
|
@mock.patch('octavia.db.repositories.AmphoraRepository.create',
|
186
186
|
return_value=_db_amphora_mock)
|
187
|
+
@mock.patch('octavia.db.repositories.AmphoraHealthRepository.delete')
|
187
188
|
def test_create_amphora_in_db(self,
|
189
|
+
mock_amphora_health_repo_delete,
|
188
190
|
mock_create,
|
189
191
|
mock_generate_uuid,
|
190
192
|
mock_LOG,
|
@@ -210,23 +212,43 @@ class TestDatabaseTasks(base.TestCase):
|
|
210
212
|
|
211
213
|
# Test the revert
|
212
214
|
create_amp_in_db.revert(_tf_failure_mock)
|
213
|
-
|
215
|
+
mock_amphora_repo_delete.assert_not_called()
|
216
|
+
mock_amphora_health_repo_delete.assert_not_called()
|
214
217
|
|
218
|
+
amp_id = 'AMP'
|
215
219
|
mock_amphora_repo_delete.reset_mock()
|
216
|
-
|
220
|
+
mock_amphora_health_repo_delete.reset_mock()
|
221
|
+
create_amp_in_db.revert(result=amp_id)
|
217
222
|
self.assertTrue(mock_amphora_repo_delete.called)
|
223
|
+
self.assertTrue(mock_amphora_health_repo_delete.called)
|
218
224
|
mock_amphora_repo_delete.assert_called_once_with(
|
219
225
|
mock_session,
|
220
|
-
id=
|
226
|
+
id=amp_id)
|
227
|
+
mock_amphora_health_repo_delete.assert_called_once_with(
|
228
|
+
mock_session,
|
229
|
+
amphora_id=amp_id)
|
230
|
+
mock_LOG.error.assert_not_called()
|
231
|
+
mock_LOG.debug.assert_not_called()
|
221
232
|
|
222
233
|
# Test revert with exception
|
223
234
|
mock_amphora_repo_delete.reset_mock()
|
224
|
-
|
225
|
-
|
235
|
+
mock_amphora_health_repo_delete.reset_mock()
|
236
|
+
err1_msg, err2_msg = ('fail', 'fail2')
|
237
|
+
mock_amphora_repo_delete.side_effect = Exception(err1_msg)
|
238
|
+
mock_amphora_health_repo_delete.side_effect = Exception(err2_msg)
|
239
|
+
create_amp_in_db.revert(result=amp_id)
|
226
240
|
self.assertTrue(mock_amphora_repo_delete.called)
|
241
|
+
self.assertTrue(mock_amphora_health_repo_delete.called)
|
227
242
|
mock_amphora_repo_delete.assert_called_once_with(
|
228
243
|
mock_session,
|
229
|
-
id=
|
244
|
+
id=amp_id)
|
245
|
+
mock_amphora_health_repo_delete.assert_called_once_with(
|
246
|
+
mock_session,
|
247
|
+
amphora_id=amp_id)
|
248
|
+
mock_LOG.error.assert_called_once_with(
|
249
|
+
"Failed to delete amphora %(amp)s "
|
250
|
+
"in the database due to: "
|
251
|
+
"%(except)s", {'amp': amp_id, 'except': err1_msg})
|
230
252
|
|
231
253
|
@mock.patch('octavia.db.repositories.ListenerRepository.delete')
|
232
254
|
def test_delete_listener_in_db(self,
|
@@ -1380,6 +1380,10 @@ class TestNetworkTasks(base.TestCase):
|
|
1380
1380
|
AMP_ID = uuidutils.generate_uuid()
|
1381
1381
|
mock_driver = mock.MagicMock()
|
1382
1382
|
mock_get_net_driver.return_value = mock_driver
|
1383
|
+
amphora_config_mock = mock.MagicMock()
|
1384
|
+
mock_driver.get_network_configs.return_value = {
|
1385
|
+
"amphora_uuid1": amphora_config_mock
|
1386
|
+
}
|
1383
1387
|
mock_amp_get.return_value = 'mock amphora'
|
1384
1388
|
mock_lb_get.return_value = 'mock load balancer'
|
1385
1389
|
|
@@ -1391,6 +1395,9 @@ class TestNetworkTasks(base.TestCase):
|
|
1391
1395
|
'mock load balancer', amphora='mock amphora')
|
1392
1396
|
mock_amp_get.assert_called_once_with(mock_get_session(), id=AMP_ID)
|
1393
1397
|
mock_lb_get.assert_called_once_with(mock_get_session(), id=LB_ID)
|
1398
|
+
amphora_config_mock.to_dict.assert_called_once_with(
|
1399
|
+
recurse=True, calling_classes=[o_data_models.LoadBalancer]
|
1400
|
+
)
|
1394
1401
|
|
1395
1402
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
1396
1403
|
@mock.patch('octavia.db.api.get_session', return_value=_session_mock)
|
@@ -1399,10 +1406,17 @@ class TestNetworkTasks(base.TestCase):
|
|
1399
1406
|
mock_driver = mock.MagicMock()
|
1400
1407
|
mock_lb_get.return_value = LB
|
1401
1408
|
mock_get_net_driver.return_value = mock_driver
|
1409
|
+
amphora_config_mock = mock.MagicMock()
|
1410
|
+
mock_driver.get_network_configs.return_value = {
|
1411
|
+
"amphora_uuid1": amphora_config_mock
|
1412
|
+
}
|
1402
1413
|
lb = o_data_models.LoadBalancer()
|
1403
1414
|
net_task = network_tasks.GetAmphoraeNetworkConfigs()
|
1404
1415
|
net_task.execute(self.load_balancer_mock)
|
1405
1416
|
mock_driver.get_network_configs.assert_called_once_with(lb)
|
1417
|
+
amphora_config_mock.to_dict.assert_called_once_with(
|
1418
|
+
recurse=True, calling_classes=[o_data_models.LoadBalancer]
|
1419
|
+
)
|
1406
1420
|
|
1407
1421
|
def test_retrieve_portids_on_amphora_except_lb_network(
|
1408
1422
|
self, mock_get_net_driver):
|
@@ -1526,6 +1540,57 @@ class TestNetworkTasks(base.TestCase):
|
|
1526
1540
|
mock_driver.unplug_aap_port.assert_called_once_with(
|
1527
1541
|
LB.vip, self.db_amphora_mock, mockSubnet)
|
1528
1542
|
|
1543
|
+
@mock.patch('octavia.db.repositories.AmphoraRepository.get')
|
1544
|
+
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
1545
|
+
@mock.patch('octavia.db.api.get_session', return_value=_session_mock)
|
1546
|
+
def test_revert_plug_vip_amphora_subnet_not_found(
|
1547
|
+
self, mock_session, mock_lb_get, mock_get, mock_get_net_driver):
|
1548
|
+
mock_driver = mock.MagicMock()
|
1549
|
+
mock_lb_get.return_value = LB
|
1550
|
+
mock_get.return_value = self.db_amphora_mock
|
1551
|
+
mock_get_net_driver.return_value = mock_driver
|
1552
|
+
net = network_tasks.PlugVIPAmphora()
|
1553
|
+
amphora = {constants.ID: AMPHORA_ID,
|
1554
|
+
constants.LB_NETWORK_IP: IP_ADDRESS}
|
1555
|
+
subnet = {constants.ID: SUBNET_ID}
|
1556
|
+
err_msg = 'Subnet not found'
|
1557
|
+
mock_driver.get_subnet.side_effect = net_base.SubnetNotFound(err_msg)
|
1558
|
+
result = AMPS_DATA[0].to_dict()
|
1559
|
+
net.revert(result, self.load_balancer_mock, amphora, subnet)
|
1560
|
+
mock_driver.unplug_aap_port.assert_not_called()
|
1561
|
+
network_tasks.LOG.error.assert_called_once_with(
|
1562
|
+
'Failed to unplug AAP port for load balancer: %s. '
|
1563
|
+
'Resources may still be in use for VRRP port: %s. '
|
1564
|
+
'Due to error: %s',
|
1565
|
+
self.load_balancer_mock[constants.LOADBALANCER_ID],
|
1566
|
+
result[constants.VRRP_PORT_ID], err_msg
|
1567
|
+
)
|
1568
|
+
|
1569
|
+
@mock.patch('octavia.db.repositories.AmphoraRepository.get')
|
1570
|
+
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
1571
|
+
@mock.patch('octavia.db.api.get_session', return_value=_session_mock)
|
1572
|
+
def test_revert_plug_vip_amphora_raise_db_error(
|
1573
|
+
self, mock_session, mock_lb_get, mock_get, mock_get_net_driver):
|
1574
|
+
mock_driver = mock.MagicMock()
|
1575
|
+
mock_lb_get.return_value = LB
|
1576
|
+
err_msg = 'Some Error'
|
1577
|
+
mock_get.side_effect = Exception(err_msg)
|
1578
|
+
net = network_tasks.PlugVIPAmphora()
|
1579
|
+
amphora = {constants.ID: AMPHORA_ID,
|
1580
|
+
constants.LB_NETWORK_IP: IP_ADDRESS}
|
1581
|
+
subnet = {constants.ID: SUBNET_ID}
|
1582
|
+
result = AMPS_DATA[0].to_dict()
|
1583
|
+
net.revert(result, self.load_balancer_mock, amphora, subnet)
|
1584
|
+
mock_driver.unplug_aap_port.assert_not_called()
|
1585
|
+
mock_lb_get.assert_not_called()
|
1586
|
+
network_tasks.LOG.error.assert_called_once_with(
|
1587
|
+
'Failed to unplug AAP port for load balancer: %s. '
|
1588
|
+
'Resources may still be in use for VRRP port: %s. '
|
1589
|
+
'Due to error: %s',
|
1590
|
+
self.load_balancer_mock[constants.LOADBALANCER_ID],
|
1591
|
+
result[constants.VRRP_PORT_ID], err_msg
|
1592
|
+
)
|
1593
|
+
|
1529
1594
|
@mock.patch('octavia.controller.worker.v2.tasks.network_tasks.DeletePort.'
|
1530
1595
|
'update_progress')
|
1531
1596
|
def test_delete_port(self, mock_update_progress, mock_get_net_driver):
|
@@ -1670,7 +1735,11 @@ class TestNetworkTasks(base.TestCase):
|
|
1670
1735
|
# Test revert
|
1671
1736
|
mock_driver.reset_mock()
|
1672
1737
|
|
1673
|
-
|
1738
|
+
# The execute path generates a port dict, so this will be the result
|
1739
|
+
# passed into the revert method by Taskflow
|
1740
|
+
port_dict = {constants.ID: PORT_ID}
|
1741
|
+
|
1742
|
+
net_task.revert(port_dict, vip_dict, VIP_SG_ID, AMP_ID,
|
1674
1743
|
additional_vips)
|
1675
1744
|
|
1676
1745
|
mock_driver.delete_port.assert_called_once_with(PORT_ID)
|
@@ -1678,7 +1747,7 @@ class TestNetworkTasks(base.TestCase):
|
|
1678
1747
|
# Test revert exception
|
1679
1748
|
mock_driver.reset_mock()
|
1680
1749
|
|
1681
|
-
net_task.revert(
|
1750
|
+
net_task.revert(port_dict, vip_dict, VIP_SG_ID, AMP_ID,
|
1682
1751
|
additional_vips)
|
1683
1752
|
|
1684
1753
|
mock_driver.delete_port.assert_called_once_with(PORT_ID)
|
@@ -27,7 +27,7 @@ from octavia.controller.worker.v2 import controller_worker
|
|
27
27
|
from octavia.controller.worker.v2.flows import flow_utils
|
28
28
|
import octavia.tests.unit.base as base
|
29
29
|
|
30
|
-
|
30
|
+
TLS_CERT_ID = uuidutils.generate_uuid()
|
31
31
|
AMP_ID = uuidutils.generate_uuid()
|
32
32
|
LB_ID = uuidutils.generate_uuid()
|
33
33
|
LISTENER_ID = uuidutils.generate_uuid()
|
@@ -804,6 +804,61 @@ class TestControllerWorker(base.TestCase):
|
|
804
804
|
})
|
805
805
|
)
|
806
806
|
|
807
|
+
@mock.patch(
|
808
|
+
"octavia.common.tls_utils.cert_parser.load_certificates_data",
|
809
|
+
side_effect=RuntimeError
|
810
|
+
)
|
811
|
+
def test_delete_load_balancer_with_cascade_tls_unavailable(
|
812
|
+
self,
|
813
|
+
mock_load_tls_cert,
|
814
|
+
mock_api_get_session,
|
815
|
+
mock_dyn_log_listener,
|
816
|
+
mock_taskflow_load,
|
817
|
+
mock_pool_repo_get,
|
818
|
+
mock_member_repo_get,
|
819
|
+
mock_l7rule_repo_get,
|
820
|
+
mock_l7policy_repo_get,
|
821
|
+
mock_listener_repo_get,
|
822
|
+
mock_lb_repo_get,
|
823
|
+
mock_health_mon_repo_get,
|
824
|
+
mock_amp_repo_get
|
825
|
+
):
|
826
|
+
_flow_mock.reset_mock()
|
827
|
+
|
828
|
+
_listener_mock.tls_certificate_id = TLS_CERT_ID
|
829
|
+
_listener_mock.to_dict.return_value[
|
830
|
+
constants.TLS_CERTIFICATE_ID] = TLS_CERT_ID
|
831
|
+
|
832
|
+
cw = controller_worker.ControllerWorker()
|
833
|
+
cw.delete_load_balancer(_load_balancer_mock, cascade=True)
|
834
|
+
|
835
|
+
mock_lb_repo_get.assert_called_once_with(
|
836
|
+
_db_session,
|
837
|
+
id=LB_ID)
|
838
|
+
|
839
|
+
# Check load_certificates_data called and error is raised
|
840
|
+
# Error must be ignored because it is not critical for current flow
|
841
|
+
mock_load_tls_cert.assert_called_once()
|
842
|
+
|
843
|
+
listener_list = [{constants.LISTENER_ID: LISTENER_ID,
|
844
|
+
constants.LOADBALANCER_ID: LB_ID,
|
845
|
+
constants.PROJECT_ID: PROJECT_ID,
|
846
|
+
"default_tls_container_ref": TLS_CERT_ID}]
|
847
|
+
|
848
|
+
(cw.services_controller.run_poster.
|
849
|
+
assert_called_once_with(
|
850
|
+
flow_utils.get_cascade_delete_load_balancer_flow,
|
851
|
+
_load_balancer_mock, listener_list, [],
|
852
|
+
store={constants.LOADBALANCER: _load_balancer_mock,
|
853
|
+
constants.LOADBALANCER_ID: LB_ID,
|
854
|
+
constants.SERVER_GROUP_ID:
|
855
|
+
_db_load_balancer_mock.server_group_id,
|
856
|
+
constants.PROJECT_ID: _db_load_balancer_mock.project_id,
|
857
|
+
})
|
858
|
+
)
|
859
|
+
|
860
|
+
_listener_mock.reset_mock()
|
861
|
+
|
807
862
|
@mock.patch('octavia.db.repositories.ListenerRepository.get_all',
|
808
863
|
return_value=([_listener_mock], None))
|
809
864
|
def test_update_load_balancer(self,
|
@@ -1071,7 +1071,8 @@ class TestAllowedAddressPairsDriver(base.TestCase):
|
|
1071
1071
|
fake_rules = [
|
1072
1072
|
{'id': 'rule-80', 'port_range_max': 80, 'protocol': 'tcp',
|
1073
1073
|
'remote_ip_prefix': '10.0.101.0/24'},
|
1074
|
-
{'id': 'rule-22', 'port_range_max': 22, 'protocol': 'tcp'}
|
1074
|
+
{'id': 'rule-22', 'port_range_max': 22, 'protocol': 'tcp'},
|
1075
|
+
{'id': 'rule-None', 'port_range_max': 22},
|
1075
1076
|
]
|
1076
1077
|
list_rules = self.driver.network_proxy.security_group_rules
|
1077
1078
|
list_rules.return_value = fake_rules
|
@@ -69,6 +69,7 @@ Elena Ezhova <eezhova@mirantis.com>
|
|
69
69
|
EranRaichstein <eranra@il.ibm.com>
|
70
70
|
Erik Olof Gunnar Andersson <eandersson@blizzard.com>
|
71
71
|
Evan Gray <evanscottgray@gmail.com>
|
72
|
+
Evgeniy Bykov <chypakabre@gmail.com>
|
72
73
|
Evgeny Fedoruk <evgenyf@radware.com>
|
73
74
|
Fei Long Wang <flwang@catalyst.net.nz>
|
74
75
|
Fernando Royo <froyo@redhat.com>
|
@@ -101,6 +102,7 @@ Hongbin Lu <hongbin.lu@huawei.com>
|
|
101
102
|
Ian Wienand <iwienand@redhat.com>
|
102
103
|
Ihar Hrachyshka <ihrachys@redhat.com>
|
103
104
|
Ildar Iskhakov <iiskhako@cisco.com>
|
105
|
+
Ilia Kerbs <ikerbs@protonmail.com>
|
104
106
|
Itzik Brown <itzikb@redhat.com>
|
105
107
|
Jacky Hu <hudayou@hotmail.com>
|
106
108
|
James Arendt <james.arendt@hp.com>
|
@@ -145,6 +147,7 @@ Martin Chlumsky <martin.chlumsky@ubisoft.com>
|
|
145
147
|
Masayuki Igawa <masayuki@igawa.io>
|
146
148
|
Matt Alline <matt.alline@gmail.com>
|
147
149
|
Maximilian Stinsky <maximilian.stinsky@gec.io>
|
150
|
+
Michael Johnson <johnosmor@gmail.com>
|
148
151
|
Michael Johnson <johnsom@hp.com>
|
149
152
|
Michael Johnson <johnsomor@gmail.com>
|
150
153
|
Michal Arbet <michal.arbet@ultimum.io>
|
@@ -188,6 +191,8 @@ Santhosh Fernandes <santhosh.fernandes@gmail.com>
|
|
188
191
|
Sean McGinnis <sean.mcginnis@gmail.com>
|
189
192
|
Selvakumar S <selvakumar.s2@hp.com>
|
190
193
|
Sergey Belous <sbelous@mirantis.com>
|
194
|
+
Sergey Kraynev <sergejyit@gmail.com>
|
195
|
+
Seunghun Lee <seunghun@stackhpc.com>
|
191
196
|
ShangXiao <shangxiaobj@inspur.com>
|
192
197
|
Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
|
193
198
|
Sherif Abdelwahab <sherif.abdelwahab@hp.com>
|