1
# Copyright 2013 VMware, Inc.
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
17
from oslo.serialization import jsonutils
19
from neutron.common import exceptions
20
from neutron.plugins.vmware.api_client import exception as api_exc
21
from neutron.plugins.vmware.common import exceptions as nsx_exc
22
from neutron.plugins.vmware.common import utils
23
from neutron.plugins.vmware.nsxlib import lsn as lsnlib
24
from neutron.tests import base
27
class LSNTestCase(base.BaseTestCase):
30
super(LSNTestCase, self).setUp()
31
self.mock_request_p = mock.patch(
32
'neutron.plugins.vmware.nsxlib.do_request')
33
self.mock_request = self.mock_request_p.start()
34
self.cluster = mock.Mock()
35
self.cluster.default_service_cluster_uuid = 'foo'
37
def test_service_cluster_None(self):
38
self.mock_request.return_value = None
39
expected = lsnlib.service_cluster_exists(None, None)
40
self.assertFalse(expected)
42
def test_service_cluster_found(self):
43
self.mock_request.return_value = {
46
"_href": "/ws.v1/service-cluster/foo_uuid",
47
"display_name": "foo_name",
50
"_schema": "/ws.v1/schema/ServiceClusterConfig",
56
expected = lsnlib.service_cluster_exists(None, 'foo_uuid')
57
self.assertTrue(expected)
59
def test_service_cluster_not_found(self):
60
self.mock_request.side_effect = exceptions.NotFound()
61
expected = lsnlib.service_cluster_exists(None, 'foo_uuid')
62
self.assertFalse(expected)
64
def test_lsn_for_network_create(self):
65
net_id = "foo_network_id"
66
tags = utils.get_tags(n_network_id=net_id)
67
obj = {"edge_cluster_uuid": "foo", "tags": tags}
68
lsnlib.lsn_for_network_create(self.cluster, net_id)
69
self.mock_request.assert_called_once_with(
70
"POST", "/ws.v1/lservices-node",
71
jsonutils.dumps(obj), cluster=self.cluster)
73
def test_lsn_for_network_get(self):
74
net_id = "foo_network_id"
76
self.mock_request.return_value = {
77
"results": [{"uuid": "foo_lsn_id"}],
80
result = lsnlib.lsn_for_network_get(self.cluster, net_id)
81
self.assertEqual(lsn_id, result)
82
self.mock_request.assert_called_once_with(
84
("/ws.v1/lservices-node?fields=uuid&tag=%s&"
85
"tag_scope=n_network_id" % net_id),
88
def test_lsn_for_network_get_none(self):
89
net_id = "foo_network_id"
90
self.mock_request.return_value = {
91
"results": [{"uuid": "foo_lsn_id1"}, {"uuid": "foo_lsn_id2"}],
94
result = lsnlib.lsn_for_network_get(self.cluster, net_id)
95
self.assertIsNone(result)
97
def test_lsn_for_network_get_raise_not_found(self):
98
net_id = "foo_network_id"
99
self.mock_request.return_value = {
100
"results": [], "result_count": 0
102
self.assertRaises(exceptions.NotFound,
103
lsnlib.lsn_for_network_get,
104
self.cluster, net_id)
106
def test_lsn_delete(self):
108
lsnlib.lsn_delete(self.cluster, lsn_id)
109
self.mock_request.assert_called_once_with(
111
"/ws.v1/lservices-node/%s" % lsn_id, cluster=self.cluster)
113
def _test_lsn_port_host_entries_update(self, lsn_type, hosts_data):
114
lsn_id = 'foo_lsn_id'
115
lsn_port_id = 'foo_lsn_port_id'
116
lsnlib.lsn_port_host_entries_update(
117
self.cluster, lsn_id, lsn_port_id, lsn_type, hosts_data)
118
self.mock_request.assert_called_once_with(
120
'/ws.v1/lservices-node/%s/lport/%s/%s' % (lsn_id,
123
jsonutils.dumps({'hosts': hosts_data}),
124
cluster=self.cluster)
126
def test_lsn_port_dhcp_entries_update(self):
127
hosts_data = [{"ip_address": "11.22.33.44",
128
"mac_address": "aa:bb:cc:dd:ee:ff"},
129
{"ip_address": "44.33.22.11",
130
"mac_address": "ff:ee:dd:cc:bb:aa"}]
131
self._test_lsn_port_host_entries_update("dhcp", hosts_data)
133
def test_lsn_port_metadata_entries_update(self):
134
hosts_data = [{"ip_address": "11.22.33.44",
135
"device_id": "foo_vm_uuid"}]
136
self._test_lsn_port_host_entries_update("metadata-proxy", hosts_data)
138
def test_lsn_port_create(self):
140
"ip_address": "1.2.3.0/24",
141
"mac_address": "aa:bb:cc:dd:ee:ff",
142
"subnet_id": "foo_subnet_id"
144
port_id = "foo_port_id"
145
self.mock_request.return_value = {"uuid": port_id}
146
lsn_id = "foo_lsn_id"
147
result = lsnlib.lsn_port_create(self.cluster, lsn_id, port_data)
148
self.assertEqual(result, port_id)
149
tags = utils.get_tags(n_subnet_id=port_data["subnet_id"],
150
n_mac_address=port_data["mac_address"])
152
"ip_address": port_data["ip_address"],
153
"mac_address": port_data["mac_address"],
154
"type": "LogicalServicesNodePortConfig",
157
self.mock_request.assert_called_once_with(
158
"POST", "/ws.v1/lservices-node/%s/lport" % lsn_id,
159
jsonutils.dumps(port_obj), cluster=self.cluster)
161
def test_lsn_port_delete(self):
162
lsn_id = "foo_lsn_id"
163
lsn_port_id = "foo_port_id"
164
lsnlib.lsn_port_delete(self.cluster, lsn_id, lsn_port_id)
165
self.mock_request.assert_called_once_with(
167
"/ws.v1/lservices-node/%s/lport/%s" % (lsn_id, lsn_port_id),
168
cluster=self.cluster)
170
def test_lsn_port_get_with_filters(self):
171
lsn_id = "foo_lsn_id"
172
port_id = "foo_port_id"
173
filters = {"tag": "foo_tag", "tag_scope": "foo_scope"}
174
self.mock_request.return_value = {
175
"results": [{"uuid": port_id}],
178
result = lsnlib._lsn_port_get(self.cluster, lsn_id, filters)
179
self.assertEqual(result, port_id)
180
self.mock_request.assert_called_once_with(
182
("/ws.v1/lservices-node/%s/lport?fields=uuid&tag=%s&"
183
"tag_scope=%s" % (lsn_id, filters["tag"], filters["tag_scope"])),
184
cluster=self.cluster)
186
def test_lsn_port_get_with_filters_return_none(self):
187
self.mock_request.return_value = {
188
"results": [{"uuid": "foo1"}, {"uuid": "foo2"}],
191
result = lsnlib._lsn_port_get(self.cluster, "lsn_id", None)
192
self.assertIsNone(result)
194
def test_lsn_port_get_with_filters_raises_not_found(self):
195
self.mock_request.return_value = {"results": [], "result_count": 0}
196
self.assertRaises(exceptions.NotFound,
197
lsnlib._lsn_port_get,
198
self.cluster, "lsn_id", None)
200
def test_lsn_port_info_get(self):
201
self.mock_request.return_value = {
203
{"scope": "n_mac_address", "tag": "fa:16:3e:27:fd:a0"},
204
{"scope": "n_subnet_id", "tag": "foo_subnet_id"},
206
"mac_address": "aa:bb:cc:dd:ee:ff",
207
"ip_address": "0.0.0.0/0",
208
"uuid": "foo_lsn_port_id"
210
result = lsnlib.lsn_port_info_get(
211
self.cluster, 'foo_lsn_id', 'foo_lsn_port_id')
212
self.mock_request.assert_called_once_with(
213
'GET', '/ws.v1/lservices-node/foo_lsn_id/lport/foo_lsn_port_id',
214
cluster=self.cluster)
215
self.assertIn('subnet_id', result)
216
self.assertIn('mac_address', result)
218
def test_lsn_port_info_get_raise_not_found(self):
219
self.mock_request.side_effect = exceptions.NotFound
220
self.assertRaises(exceptions.NotFound,
221
lsnlib.lsn_port_info_get,
222
self.cluster, mock.ANY, mock.ANY)
224
def test_lsn_port_plug_network(self):
225
lsn_id = "foo_lsn_id"
226
lsn_port_id = "foo_lsn_port_id"
227
lswitch_port_id = "foo_lswitch_port_id"
228
lsnlib.lsn_port_plug_network(
229
self.cluster, lsn_id, lsn_port_id, lswitch_port_id)
230
self.mock_request.assert_called_once_with(
232
("/ws.v1/lservices-node/%s/lport/%s/"
233
"attachment") % (lsn_id, lsn_port_id),
234
jsonutils.dumps({"peer_port_uuid": lswitch_port_id,
235
"type": "PatchAttachment"}),
236
cluster=self.cluster)
238
def test_lsn_port_plug_network_raise_conflict(self):
239
lsn_id = "foo_lsn_id"
240
lsn_port_id = "foo_lsn_port_id"
241
lswitch_port_id = "foo_lswitch_port_id"
242
self.mock_request.side_effect = api_exc.Conflict
244
nsx_exc.LsnConfigurationConflict,
245
lsnlib.lsn_port_plug_network,
246
self.cluster, lsn_id, lsn_port_id, lswitch_port_id)
248
def _test_lsn_port_dhcp_configure(
249
self, lsn_id, lsn_port_id, is_enabled, opts):
250
lsnlib.lsn_port_dhcp_configure(
251
self.cluster, lsn_id, lsn_port_id, is_enabled, opts)
253
{"name": key, "value": val}
254
for key, val in opts.iteritems()
256
self.mock_request.assert_has_calls([
257
mock.call("PUT", "/ws.v1/lservices-node/%s/dhcp" % lsn_id,
258
jsonutils.dumps({"enabled": is_enabled}),
259
cluster=self.cluster),
261
("/ws.v1/lservices-node/%s/"
262
"lport/%s/dhcp") % (lsn_id, lsn_port_id),
263
jsonutils.dumps({"options": opt_array}),
264
cluster=self.cluster)
267
def test_lsn_port_dhcp_configure_empty_opts(self):
268
lsn_id = "foo_lsn_id"
269
lsn_port_id = "foo_lsn_port_id"
272
self._test_lsn_port_dhcp_configure(
273
lsn_id, lsn_port_id, is_enabled, opts)
275
def test_lsn_port_dhcp_configure_with_opts(self):
276
lsn_id = "foo_lsn_id"
277
lsn_port_id = "foo_lsn_port_id"
279
opts = {"opt1": "val1", "opt2": "val2"}
280
self._test_lsn_port_dhcp_configure(
281
lsn_id, lsn_port_id, is_enabled, opts)
283
def _test_lsn_metadata_configure(
284
self, lsn_id, is_enabled, opts, expected_opts):
285
lsnlib.lsn_metadata_configure(
286
self.cluster, lsn_id, is_enabled, opts)
287
lsn_obj = {"enabled": is_enabled}
288
lsn_obj.update(expected_opts)
289
self.mock_request.assert_has_calls([
291
"/ws.v1/lservices-node/%s/metadata-proxy" % lsn_id,
292
jsonutils.dumps(lsn_obj),
293
cluster=self.cluster),
296
def test_lsn_port_metadata_configure_empty_secret(self):
297
lsn_id = "foo_lsn_id"
300
"metadata_server_ip": "1.2.3.4",
301
"metadata_server_port": "8775"
304
"metadata_server_ip": "1.2.3.4",
305
"metadata_server_port": "8775",
307
self._test_lsn_metadata_configure(
308
lsn_id, is_enabled, opts, expected_opts)
310
def test_lsn_metadata_configure_with_secret(self):
311
lsn_id = "foo_lsn_id"
314
"metadata_server_ip": "1.2.3.4",
315
"metadata_server_port": "8775",
316
"metadata_proxy_shared_secret": "foo_secret"
319
"metadata_server_ip": "1.2.3.4",
320
"metadata_server_port": "8775",
322
"name": "metadata_proxy_shared_secret",
323
"value": "foo_secret"
326
self._test_lsn_metadata_configure(
327
lsn_id, is_enabled, opts, expected_opts)
329
def _test_lsn_port_host_action(
330
self, lsn_port_action_func, extra_action, action, host):
331
lsn_id = "foo_lsn_id"
332
lsn_port_id = "foo_lsn_port_id"
333
lsn_port_action_func(self.cluster, lsn_id, lsn_port_id, host)
334
self.mock_request.assert_called_once_with(
336
("/ws.v1/lservices-node/%s/lport/"
337
"%s/%s?action=%s") % (lsn_id, lsn_port_id, extra_action, action),
338
jsonutils.dumps(host), cluster=self.cluster)
340
def test_lsn_port_dhcp_host_add(self):
342
"ip_address": "1.2.3.4",
343
"mac_address": "aa:bb:cc:dd:ee:ff"
345
self._test_lsn_port_host_action(
346
lsnlib.lsn_port_dhcp_host_add, "dhcp", "add_host", host)
348
def test_lsn_port_dhcp_host_remove(self):
350
"ip_address": "1.2.3.4",
351
"mac_address": "aa:bb:cc:dd:ee:ff"
353
self._test_lsn_port_host_action(
354
lsnlib.lsn_port_dhcp_host_remove, "dhcp", "remove_host", host)
356
def test_lsn_port_metadata_host_add(self):
358
"ip_address": "1.2.3.4",
359
"instance_id": "foo_instance_id"
361
self._test_lsn_port_host_action(lsnlib.lsn_port_metadata_host_add,
362
"metadata-proxy", "add_host", host)
364
def test_lsn_port_metadata_host_remove(self):
366
"ip_address": "1.2.3.4",
367
"instance_id": "foo_instance_id"
369
self._test_lsn_port_host_action(lsnlib.lsn_port_metadata_host_remove,
370
"metadata-proxy", "remove_host", host)