From 0e10819e9f46c6d00c2e54e544c8df4a2f1ce9a2 Mon Sep 17 00:00:00 2001 From: schillinge Date: Wed, 30 Jan 2019 17:48:27 +0100 Subject: [PATCH] Allow multiple ports to exist with the same name Ports in OpenStack may very well have identical names. In fact this is almost guaranteed when deploying network services with multiple identical VNFs. Change-Id: Iba196e64be329c376eca9f34c7b2cbcdfd569a3e Signed-off-by: schillinge --- src/emuvim/api/openstack/compute.py | 21 ++++++++++--------- .../openstack_dummies/neutron_dummy_api.py | 4 ---- .../openstack_dummies/nova_dummy_api.py | 6 +++--- src/emuvim/test/unittests/test_openstack.py | 20 ++++++++++++------ 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/emuvim/api/openstack/compute.py b/src/emuvim/api/openstack/compute.py index 405fa6f..4d6517e 100755 --- a/src/emuvim/api/openstack/compute.py +++ b/src/emuvim/api/openstack/compute.py @@ -687,12 +687,6 @@ class OpenstackCompute(object): :return: Returns the created port. :rtype: :class:`heat.resources.port` """ - port = self.find_port_by_name_or_id(name) - if port is not None and not stack_operation: - LOG.warning( - "Creating port with name %s failed, as it already exists" % name) - raise Exception("Port with name %s already exists." % name) - LOG.debug("Creating port with name %s" % name) port = Port(name) if not stack_operation: self.ports[port.id] = port @@ -708,12 +702,19 @@ class OpenstackCompute(object): :return: Returns the port reference if it was found or None :rtype: :class:`heat.resources.port` """ + # find by id if name_or_id in self.ports: return self.ports[name_or_id] - for port in self.ports.values(): - if port.name == name_or_id or port.template_name == name_or_id: - return port - + # find by name + matching_ports = filter( + lambda port: port.name == name_or_id or port.template_name == name_or_id, + self.ports.values() + ) + matching_ports_count = len(matching_ports) + if matching_ports_count == 1: + return matching_ports[0] + if matching_ports_count > 1: + raise RuntimeError("Ambiguous port name %s" % name_or_id) return None def delete_port(self, name_or_id): diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py index e094f0e..13698bd 100755 --- a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py @@ -816,10 +816,6 @@ class NeutronCreatePort(Resource): num_ports = len(self.api.compute.ports) name = "port:cp%s:man:%s" % (num_ports, str(uuid.uuid4())) - if self.api.compute.find_port_by_name_or_id(name): - return Response("Port with name %s already exists.\n" % - name, status=500, mimetype='application/json') - port = self.api.compute.create_port(name) port.net_name = net.name diff --git a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py index e12fb05..12a9cc2 100755 --- a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py @@ -246,10 +246,10 @@ class NovaListServersApi(Resource): if networks is not None: for net in networks: - port = self.api.compute.find_port_by_name_or_id( - net.get('port', "")) + port_name_or_id = net.get('port', "") + port = self.api.compute.find_port_by_name_or_id(port_name_or_id) if port is not None: - server.port_names.append(port.name) + server.port_names.append(port_name_or_id) else: return Response( "Currently only networking by port is supported.", status=400) diff --git a/src/emuvim/test/unittests/test_openstack.py b/src/emuvim/test/unittests/test_openstack.py index 93d7f4a..5540247 100755 --- a/src/emuvim/test/unittests/test_openstack.py +++ b/src/emuvim/test/unittests/test_openstack.py @@ -610,18 +610,26 @@ class testRestApi(ApiBaseOpenStack): url, data=createportdata, headers=headers) self.assertEqual(createportresponse.status_code, 201) print(createportresponse.content) - self.assertEqual(json.loads(createportresponse.content)[ - "port"]["name"], "new_port") + createport = json.loads(createportresponse.content)["port"] + self.assertEqual(createport["name"], "new_port") print(" ") print('->>>>>>> test Neutron Create Port With Existing Name ->>>>>>>>>>>>>>>') print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>') url = "http://0.0.0.0:19696/v2.0/ports" - createportwithexistingnamedata = '{"port": {"name": "new_port", "network_id": "%s"} }' % ( - json.loads(createnetworkresponse.content)["network"]["id"]) - createportwithexistingnameresponse = requests.post( + network_id = json.loads(createnetworkresponse.content)["network"]["id"] + createportwithexistingnamedata = '{"port": {"name": "duplicate_port_name", "network_id": "%s"} }' % network_id + createportwithexistingnameresponse1 = requests.post( + url, data=createportwithexistingnamedata, headers=headers) + createportwithexistingnameresponse2 = requests.post( url, data=createportwithexistingnamedata, headers=headers) - self.assertEqual(createportwithexistingnameresponse.status_code, 500) + createportwithexistingname1 = json.loads(createportwithexistingnameresponse1.content)["port"] + createportwithexistingname2 = json.loads(createportwithexistingnameresponse2.content)["port"] + self.assertEqual(createportwithexistingnameresponse1.status_code, 201) + self.assertEqual(createportwithexistingnameresponse2.status_code, 201) + self.assertEqual(createportwithexistingname1["name"], "duplicate_port_name") + self.assertEqual(createportwithexistingname2["name"], "duplicate_port_name") + self.assertNotEqual(createportwithexistingname1["id"], createportwithexistingname2["id"], "Duplicate port should have different id") print(" ") print('->>>>>>> test Neutron Create Port Without Name ->>>>>>>>>>>>>>>') -- 2.17.1