Check if router exists on network creation

List the routers of the tenant and use the first router with external
gateway, thus It is linked to the public network.
In case no router with those features is found, a new one is created.

Change-Id: I696ebe04426fab7e210d86f30084c4fee64cbce8
Closes-bug: #1637497
This commit is contained in:
jorgesece 2016-10-28 14:50:57 +01:00 committed by Alvaro Lopez Garcia
parent e30fdd75f4
commit e2207d7c12
3 changed files with 161 additions and 30 deletions

View File

@ -349,25 +349,26 @@ class OpenStackNeutron(helpers.BaseHelper):
req, 'subnets', subnet_param) req, 'subnets', subnet_param)
# INTERFACE and ROUTER information is agnostic to the user # INTERFACE and ROUTER information is agnostic to the user
net_public = self._get_public_network(req) router = None
attributes_router = {"external_gateway_info": { router_list = self.list_resources(req, "routers")
"network_id": net_public} for r in router_list:
} if r["external_gateway_info"]:
router = self.create_resource(req, router = r
'routers', break
attributes_router) if not router:
try: net_public = self._get_public_network(req)
# create interface to the network attributes_router = {"external_gateway_info": {
self._add_router_interface(req, "network_id": net_public}
router['id'], }
net['subnet_info']['id'] router = self.create_resource(req,
) 'routers',
except Exception as ex: attributes_router)
self.delete_resource(req,
'routers', # create interface to the network
router['id'] self._add_router_interface(req,
) router['id'],
raise ex net['subnet_info']['id']
)
except Exception as ex: except Exception as ex:
self.delete_resource(req, self.delete_resource(req,
'networks', net['id']) 'networks', net['id'])
@ -389,8 +390,6 @@ class OpenStackNeutron(helpers.BaseHelper):
port['device_id'], port['device_id'],
port['id'], port['id'],
) )
self.delete_resource(req,
'routers', port["device_id"])
else: else:
self.delete_resource(req, self.delete_resource(req,
'ports', port["id"]) 'ports', port["id"])

View File

@ -117,10 +117,14 @@ class TestNetNeutronController(test_middleware.TestMiddleware):
200) 200)
mock_subnet = mock.Mock(webob.Request) mock_subnet = mock.Mock(webob.Request)
mock_subnet.get_response.return_value = subnet_out mock_subnet.get_response.return_value = subnet_out
list_router_out = fakes.create_fake_json_resp(
{"routers": []},
200)
mock_list_router = mock.Mock(webob.Request)
mock_list_router.get_response.return_value = list_router_out
public_out = fakes.create_fake_json_resp( public_out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]}, {"networks": fakes.networks[tenant['id']]},
200) 200)
mock_public = mock.Mock(webob.Request) mock_public = mock.Mock(webob.Request)
mock_public.get_response.return_value = public_out mock_public.get_response.return_value = public_out
router_out = fakes.create_fake_json_resp( router_out = fakes.create_fake_json_resp(
@ -131,7 +135,76 @@ class TestNetNeutronController(test_middleware.TestMiddleware):
mock_iface = mock.Mock(webob.Request) mock_iface = mock.Mock(webob.Request)
mock_iface.get_response.return_value = fakes.create_fake_json_resp( mock_iface.get_response.return_value = fakes.create_fake_json_resp(
{"foo": "foo"}, 200) {"foo": "foo"}, 200)
m.side_effect = [mock_net, mock_subnet, mock_public, m.side_effect = [mock_net, mock_subnet, mock_list_router, mock_public,
mock_router, mock_iface
]
name = fakes.networks[tenant["id"]][0]["name"]
net_id = fakes.networks[tenant["id"]][0]["id"]
address = fakes.networks[tenant["id"]][0]["subnet_info"]["cidr"]
headers = {
'Category': 'network;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure#";'
'class="kind",'
'ipnetwork;'
' scheme='
'"http://schemas.ogf.org/occi/infrastructure/'
'network#";'
'class="mixin",',
'X-OCCI-Attribute': 'occi.core.title="%s",'
'occi.network.address="%s"' %
(name, address)
}
req = self._build_req(path="/network",
tenant_id='X',
method="POST",
headers=headers)
m.return_value = fakes.networks[tenant['id']][0]
resp = req.get_response(self.app)
self.assertEqual(200, resp.status_code)
expected = [("X-OCCI-Location",
utils.join_url(self.application_url + "/",
"network/%s" % net_id))]
self.assertExpectedResult(expected, resp)
@mock.patch.object(helpers.BaseHelper, "_get_req")
def test_create_router_exists(self, m):
tenant = fakes.tenants["foo"]
net_out = fakes.create_fake_json_resp(
{"network": fakes.networks[tenant['id']][0]}, 200)
mock_net = mock.Mock(webob.Request)
mock_net.get_response.return_value = net_out
subnet_out = fakes.create_fake_json_resp(
{"subnet": fakes.networks[tenant['id']][0]["subnet_info"]},
200)
mock_subnet = mock.Mock(webob.Request)
mock_subnet.get_response.return_value = subnet_out
list_router_out = fakes.create_fake_json_resp(
{"routers": [
{"id": uuid.uuid4().hex,
"external_gateway_info": None},
{"id": uuid.uuid4().hex,
"external_gateway_info": {"network_id": uuid.uuid4().hex}},
]
},
200)
mock_list_router = mock.Mock(webob.Request)
mock_list_router.get_response.return_value = list_router_out
public_out = fakes.create_fake_json_resp(
{"networks": fakes.networks[tenant['id']]},
200)
mock_public = mock.Mock(webob.Request)
mock_public.get_response.return_value = public_out
router_out = fakes.create_fake_json_resp(
{"router": {"id": uuid.uuid4().hex}},
200)
mock_router = mock.Mock(webob.Request)
mock_router.get_response.return_value = router_out
mock_iface = mock.Mock(webob.Request)
mock_iface.get_response.return_value = fakes.create_fake_json_resp(
{"foo": "foo"}, 200)
m.side_effect = [mock_net, mock_subnet, mock_list_router, mock_public,
mock_router, mock_iface mock_router, mock_iface
] ]
name = fakes.networks[tenant["id"]][0]["name"] name = fakes.networks[tenant["id"]][0]["name"]

View File

@ -379,7 +379,9 @@ class TestNetOpenStackHelper(base.TestCase):
}, },
{"id": router_id}, {"id": router_id},
{"id": 0}] {"id": 0}]
list_net.return_value = [{'id': public_net}] router_list = []
net_list = [{'id': public_net}]
list_net.side_effect = [router_list, net_list]
ret = self.helper.create_network(None, ret = self.helper.create_network(None,
name=name, name=name,
cidr=cidr, cidr=cidr,
@ -407,6 +409,66 @@ class TestNetOpenStackHelper(base.TestCase):
self.assertEqual(cidr, ret['address']) self.assertEqual(cidr, ret['address'])
self.assertEqual(gate_way, ret['gateway']) self.assertEqual(gate_way, ret['gateway'])
@mock.patch.object(helpers_neutron.OpenStackNeutron, "create_resource")
@mock.patch.object(helpers_neutron.OpenStackNeutron, "list_resources")
@mock.patch.object(helpers_neutron.OpenStackNeutron,
"_add_router_interface")
def test_create_full_network_router_exists(self, add_if,
list_net, cre_net):
name = "name_net"
net_id = uuid.uuid4().hex
subnet_id = uuid.uuid4().hex
router_id_1 = uuid.uuid4().hex
router_id_2 = uuid.uuid4().hex
state = "ACTIVE"
ip_version = 4
cidr = "0.0.0.0/24"
gate_way = "0.0.0.1"
parameters = {"occi.core.title": name,
"occi.core.id": net_id,
"occi.network.state": state,
"org.openstack.network.ip_version": ip_version,
"occi.network.address": cidr,
"occi.network.gateway": gate_way
}
cre_net.side_effect = [{'id': net_id,
"status": 'active',
"name": 'xx'},
{"id": subnet_id,
"cidr": cidr,
"gateway_ip": gate_way,
}
]
router_list = [{"id": router_id_1,
"external_gateway_info": None},
{"id": router_id_2,
"external_gateway_info":
{"network_id": net_id}}
]
list_net.return_value = router_list
ret = self.helper.create_network(None,
name=name,
cidr=cidr,
gateway=gate_way,
ip_version=ip_version)
self.assertEqual(net_id, ret["id"])
param = utils.translate_parameters(
self.translation["networks"], parameters)
self.assertEqual((None, 'networks',
param),
cre_net.call_args_list[0][0])
param_subnet = utils.translate_parameters(
self.translation["subnets"], parameters)
param_subnet['network_id'] = net_id
self.assertEqual((None, 'subnets',
param_subnet),
cre_net.call_args_list[1][0])
list_net.assert_called_with(None, "routers")
add_if.assert_called_with(None, router_id_2, subnet_id)
self.assertEqual(cidr, ret['address'])
self.assertEqual(gate_way, ret['gateway'])
@mock.patch.object(helpers_neutron.OpenStackNeutron, "delete_resource") @mock.patch.object(helpers_neutron.OpenStackNeutron, "delete_resource")
@mock.patch.object(helpers_neutron.OpenStackNeutron, "list_resources") @mock.patch.object(helpers_neutron.OpenStackNeutron, "list_resources")
@mock.patch.object(helpers_neutron.OpenStackNeutron, @mock.patch.object(helpers_neutron.OpenStackNeutron,
@ -424,19 +486,16 @@ class TestNetOpenStackHelper(base.TestCase):
} }
port2 = {'id': 2, 'device_owner': 'nova'} port2 = {'id': 2, 'device_owner': 'nova'}
m_list.return_value = [port1, port2] m_list.return_value = [port1, port2]
m_del.side_effect = [{0}, {0}, []] m_del.side_effect = [{0}, []]
m_if.return_value = [] m_if.return_value = []
ret = self.helper.delete_network(None, net_id) ret = self.helper.delete_network(None, net_id)
self.assertEqual(ret, []) self.assertEqual(ret, [])
self.assertEqual((None, 'routers',
port1['device_id']),
m_del.call_args_list[0][0])
self.assertEqual((None, 'ports', self.assertEqual((None, 'ports',
port2['id']), port2['id']),
m_del.call_args_list[1][0]) m_del.call_args_list[0][0])
self.assertEqual((None, 'networks', self.assertEqual((None, 'networks',
net_id), net_id),
m_del.call_args_list[2][0]) m_del.call_args_list[1][0])
@mock.patch.object(helpers_neutron.OpenStackNeutron, @mock.patch.object(helpers_neutron.OpenStackNeutron,
"_make_delete_request") "_make_delete_request")