Skip to content

Commit

Permalink
Merged trunk.
Browse files Browse the repository at this point in the history
  • Loading branch information
jk0 committed Aug 16, 2011
2 parents dc2ccb9 + ef0e505 commit 0610893
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 113 deletions.
5 changes: 4 additions & 1 deletion bin/nova-manage
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ class NetworkCommands(object):
# sanitize other input using FLAGS if necessary
if not num_networks:
num_networks = FLAGS.num_networks
if not network_size:
if not network_size and fixed_range_v4:
fixnet = netaddr.IPNetwork(fixed_range_v4)
each_subnet_size = fixnet.size / int(num_networks)
if each_subnet_size > FLAGS.network_size:
Expand All @@ -741,6 +741,9 @@ class NetworkCommands(object):
if not dns1 and FLAGS.flat_network_dns:
dns1 = FLAGS.flat_network_dns

if not network_size:
network_size = FLAGS.network_size

# create the network
net_manager = utils.import_object(FLAGS.network_manager)
net_manager.create_networks(context.get_admin_context(),
Expand Down
165 changes: 80 additions & 85 deletions nova/network/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"""

import datetime
import itertools
import math
import netaddr
import socket
Expand Down Expand Up @@ -632,121 +633,112 @@ def release_fixed_ip(self, context, address):
network_ref = self.db.fixed_ip_get_network(context, address)
self._setup_network(context, network_ref)

def _validate_cidrs(self, context, cidr, num_networks, network_size):
significant_bits = 32 - int(math.log(network_size, 2))
req_net = netaddr.IPNetwork(cidr)
req_net_ip = str(req_net.ip)
req_size = network_size * num_networks
if req_size > req_net.size:
msg = _("network_size * num_networks exceeds cidr size")
raise ValueError(msg)
adjusted_cidr_str = req_net_ip + '/' + str(significant_bits)
adjusted_cidr = netaddr.IPNetwork(adjusted_cidr_str)
try:
used_nets = self.db.network_get_all(context)
except exception.NoNetworksFound:
used_nets = []
used_cidrs = [netaddr.IPNetwork(net['cidr']) for net in used_nets]
if adjusted_cidr in used_cidrs:
raise ValueError(_("cidr already in use"))
for adjusted_cidr_supernet in adjusted_cidr.supernet():
if adjusted_cidr_supernet in used_cidrs:
msg = _("requested cidr (%s) conflicts with existing supernet")
raise ValueError(msg % str(adjusted_cidr))
# watch for smaller subnets conflicting
used_supernets = []
for used_cidr in used_cidrs:
if not used_cidr:
continue
if used_cidr.size < network_size:
for ucsupernet in used_cidr.supernet():
if ucsupernet.size == network_size:
used_supernets.append(ucsupernet)
all_req_nets = []
if num_networks == 1:
if adjusted_cidr in used_supernets:
msg = _("requested cidr (%s) conflicts with existing smaller"
" cidr")
raise ValueError(msg % str(adjusted_cidr))
else:
all_req_nets.append(adjusted_cidr)
elif num_networks >= 2:
# split supernet into subnets
next_cidr = adjusted_cidr
for index in range(num_networks):
if next_cidr.first > req_net.last:
msg = _("Not enough subnets avail to satisfy requested "
"num_net works - some subnets in requested range"
" already in use")
raise ValueError(msg)
while True:
used_values = used_cidrs + used_supernets
if next_cidr in used_values:
next_cidr = next_cidr.next()
else:
all_req_nets.append(next_cidr)
next_cidr = next_cidr.next()
break
all_req_nets = sorted(list(set(all_req_nets)))
return all_req_nets

def create_networks(self, context, label, cidr, multi_host, num_networks,
network_size, cidr_v6, gateway_v6, bridge,
bridge_interface, dns1=None, dns2=None, **kwargs):
"""Create networks based on parameters."""
# NOTE(jkoelker): these are dummy values to make sure iter works
fixed_net_v4 = netaddr.IPNetwork('0/32')
fixed_net_v6 = netaddr.IPNetwork('::0/128')
subnets_v4 = []
subnets_v6 = []

subnet_bits = int(math.ceil(math.log(network_size, 2)))

if cidr_v6:
fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
significant_bits_v6 = 64
network_size_v6 = 1 << 64
prefixlen_v6 = 128 - subnet_bits
subnets_v6 = fixed_net_v6.subnet(prefixlen_v6, count=num_networks)

if cidr:
req_cidrs = self._validate_cidrs(context, cidr, num_networks,
network_size)

for index in range(num_networks):
fixed_net_v4 = netaddr.IPNetwork(cidr)
prefixlen_v4 = 32 - subnet_bits
subnets_v4 = list(fixed_net_v4.subnet(prefixlen_v4,
count=num_networks))

# NOTE(jkoelker): This replaces the _validate_cidrs call and
# prevents looping multiple times
try:
nets = self.db.network_get_all(context)
except exception.NoNetworksFound:
nets = []
used_subnets = [netaddr.IPNetwork(net['cidr']) for net in nets]

def find_next(subnet):
next_subnet = subnet.next()
while next_subnet in subnets_v4:
next_subnet = next_subnet.next()
if next_subnet in fixed_net_v4:
return next_subnet

for subnet in list(subnets_v4):
if subnet in used_subnets:
next_subnet = find_next(subnet)
if next_subnet:
subnets_v4.remove(subnet)
subnets_v4.append(next_subnet)
subnet = next_subnet
else:
raise ValueError(_('cidr already in use'))
for used_subnet in used_subnets:
if subnet in used_subnet:
msg = _('requested cidr (%(cidr)s) conflicts with '
'existing supernet (%(super)s)')
raise ValueError(msg % {'cidr': subnet,
'super': used_subnet})
if used_subnet in subnet:
next_subnet = find_next(subnet)
if next_subnet:
subnets_v4.remove(subnet)
subnets_v4.append(next_subnet)
subnet = next_subnet
else:
msg = _('requested cidr (%(cidr)s) conflicts '
'with existing smaller cidr '
'(%(smaller)s)')
raise ValueError(msg % {'cidr': subnet,
'smaller': used_subnet})

networks = []
subnets = itertools.izip_longest(subnets_v4, subnets_v6)
for index, (subnet_v4, subnet_v6) in enumerate(subnets):
net = {}
net['bridge'] = bridge
net['bridge_interface'] = bridge_interface
net['multi_host'] = multi_host

net['dns1'] = dns1
net['dns2'] = dns2

if cidr:
project_net = req_cidrs[index]
net['cidr'] = str(project_net)
net['multi_host'] = multi_host
net['netmask'] = str(project_net.netmask)
net['gateway'] = str(project_net[1])
net['broadcast'] = str(project_net.broadcast)
net['dhcp_start'] = str(project_net[2])

if num_networks > 1:
net['label'] = '%s_%d' % (label, index)
else:
net['label'] = label

if cidr_v6:
start_v6 = index * network_size_v6
cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6],
significant_bits_v6)
net['cidr_v6'] = cidr_v6

project_net_v6 = netaddr.IPNetwork(cidr_v6)
if cidr and subnet_v4:
net['cidr'] = str(subnet_v4)
net['netmask'] = str(subnet_v4.netmask)
net['gateway'] = str(subnet_v4[1])
net['broadcast'] = str(subnet_v4.broadcast)
net['dhcp_start'] = str(subnet_v4[2])

if cidr_v6 and subnet_v6:
net['cidr_v6'] = str(subnet_v6)
if gateway_v6:
# use a pre-defined gateway if one is provided
net['gateway_v6'] = str(gateway_v6)
else:
net['gateway_v6'] = str(project_net_v6[1])
net['gateway_v6'] = str(subnet_v6[1])

net['netmask_v6'] = str(project_net_v6._prefixlen)
net['netmask_v6'] = str(subnet_v6._prefixlen)

if kwargs.get('vpn', False):
# this bit here is for vlan-manager
del net['dns1']
del net['dns2']
vlan = kwargs['vlan_start'] + index
net['vpn_private_address'] = str(project_net[2])
net['dhcp_start'] = str(project_net[3])
net['vpn_private_address'] = str(subnet_v4[2])
net['dhcp_start'] = str(subnet_v4[3])
net['vlan'] = vlan
net['bridge'] = 'br%s' % vlan

Expand All @@ -759,9 +751,12 @@ def create_networks(self, context, label, cidr, multi_host, num_networks,

if not network:
raise ValueError(_('Network already exists!'))
else:
networks.append(network)

if network and cidr:
if network and cidr and subnet_v4:
self._create_fixed_ips(context, network['id'])
return networks

@property
def _bottom_reserved_ips(self): # pylint: disable=R0201
Expand Down
Loading

0 comments on commit 0610893

Please sign in to comment.