route_qry = context.session.query(models_v2.SubnetRoute)
return route_qry.filter_by(subnet_id=subnet_id).all()
+ def _get_router_gw_ports_by_network(self, context, network_id):
+ port_qry = context.session.query(models_v2.Port)
+ return port_qry.filter_by(network_id=network_id,
+ device_owner=constants.DEVICE_OWNER_ROUTER_GW).all()
+
def _get_subnets_by_network(self, context, network_id):
subnet_qry = context.session.query(models_v2.Subnet)
return subnet_qry.filter_by(network_id=network_id).all()
pool=pool_range,
ip_address=gateway_ip)
+ def _update_router_gw_ports(self, context, subnet_id, network_id):
+ l3plugin = manager.NeutronManager.get_service_plugins().get(
+ service_constants.L3_ROUTER_NAT)
+ if l3plugin:
+ gw_ports = self._get_router_gw_ports_by_network(context,
+ network_id)
+ router_ids = [p['device_id'] for p in gw_ports]
+ ctx_admin = ctx.get_admin_context()
+ for id in router_ids:
+ router = l3plugin.get_router(ctx_admin, id)
+ external_gateway_info = router['external_gateway_info']
+ external_gateway_info['external_fixed_ips'].append(
+ {'subnet_id': subnet_id})
+ info = {'router': {'external_gateway_info':
+ external_gateway_info}}
+ l3plugin.update_router(context, id, info)
+
def create_subnet(self, context, subnet):
net = netaddr.IPNetwork(subnet['subnet']['cidr'])
self._validate_subnet(context, s)
tenant_id = self._get_tenant_id_for_create(context, s)
+ subnet_id = s.get('id') or uuidutils.generate_uuid()
with context.session.begin(subtransactions=True):
network = self._get_network(context, s["network_id"])
self._validate_subnet_cidr(context, network, s['cidr'])
# The 'shared' attribute for subnets is for internal plugin
# use only. It is not exposed through the API
args = {'tenant_id': tenant_id,
- 'id': s.get('id') or uuidutils.generate_uuid(),
+ 'id': subnet_id,
'name': s['name'],
'network_id': s['network_id'],
'ip_version': s['ip_version'],
last_ip=pool['end'])
context.session.add(ip_range)
+ if network.external:
+ self._update_router_gw_ports(context, subnet_id, s['network_id'])
+
return self._make_subnet_dict(subnet)
def _update_subnet_dns_nameservers(self, context, id, s):
self.assertNotEqual(fip1['ip_address'],
fip2['ip_address'])
+ def test_router_update_gateway_upon_subnet_create_ipv6(self):
+ with self.network() as n:
+ with self.subnet(network=n) as s1, self.router() as r:
+ self._set_net_external(n['network']['id'])
+ res1 = self._add_external_gateway_to_router(
+ r['router']['id'],
+ n['network']['id'],
+ ext_ips=[{'subnet_id': s1['subnet']['id']}])
+ fip1 = (res1['router']['external_gateway_info']
+ ['external_fixed_ips'][0])
+ sres = self._create_subnet(self.fmt, net_id=n['network']['id'],
+ ip_version=6, cidr='2001:db8::/32',
+ expected_res_status=(
+ exc.HTTPCreated.code))
+ s2 = self.deserialize(self.fmt, sres)
+ res2 = self._show('routers', r['router']['id'])
+ self.assertEqual(fip1, res2['router']['external_gateway_info']
+ ['external_fixed_ips'][0])
+ fip2 = (res2['router']['external_gateway_info']
+ ['external_fixed_ips'][1])
+ self.assertEqual(s2['subnet']['id'], fip2['subnet_id'])
+ self.assertNotEqual(fip1['subnet_id'], fip2['subnet_id'])
+ self.assertNotEqual(fip1['ip_address'], fip2['ip_address'])
+
def _test_router_add_interface_subnet(self, router, subnet, msg=None):
exp_notifications = ['router.create.start',
'router.create.end',