Skip to content

Commit

Permalink
Merge "Implement network creation in compute API"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Aug 24, 2012
2 parents 6293c0b + e00a398 commit af687ff
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 90 deletions.
96 changes: 15 additions & 81 deletions bin/nova-manage
Expand Up @@ -83,6 +83,7 @@ from nova import db
from nova.db import migration
from nova import exception
from nova import flags
from nova.api.openstack.compute.contrib import networks
from nova.openstack.common import cfg
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
Expand All @@ -94,6 +95,8 @@ from nova import utils
from nova import version
from nova.volume import volume_types

from webob import exc

FLAGS = flags.FLAGS
flags.DECLARE('flat_network_bridge', 'nova.network.manager')
flags.DECLARE('num_networks', 'nova.network.manager')
Expand Down Expand Up @@ -434,15 +437,15 @@ class NetworkCommands(object):

@args('--label', dest="label", metavar='<label>',
help='Label for network (ex: public)')
@args('--fixed_range_v4', dest="fixed_range_v4", metavar='<x.x.x.x/yy>',
@args('--fixed_range_v4', dest="cidr", metavar='<x.x.x.x/yy>',
help='IPv4 subnet (ex: 10.0.0.0/8)')
@args('--num_networks', dest="num_networks", metavar='<number>',
help='Number of networks to create')
@args('--network_size', dest="network_size", metavar='<number>',
help='Number of IPs per network')
@args('--vlan', dest="vlan_start", metavar='<vlan id>', help='vlan id')
@args('--vpn', dest="vpn_start", help='vpn start')
@args('--fixed_range_v6', dest="fixed_range_v6",
@args('--fixed_range_v6', dest="cidr_v6",
help='IPv6 subnet (ex: fe80::/64')
@args('--gateway', dest="gateway", help='gateway')
@args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway')
Expand All @@ -464,91 +467,22 @@ class NetworkCommands(object):
help='Project id')
@args('--priority', dest="priority", metavar="<number>",
help='Network interface priority')
def create(self, label=None, fixed_range_v4=None, num_networks=None,
def create(self, label=None, cidr=None, num_networks=None,
network_size=None, multi_host=None, vlan_start=None,
vpn_start=None, fixed_range_v6=None, gateway=None,
vpn_start=None, cidr_v6=None, gateway=None,
gateway_v6=None, bridge=None, bridge_interface=None,
dns1=None, dns2=None, project_id=None, priority=None,
uuid=None, fixed_cidr=None):
"""Creates fixed ips for host by range"""

# check for certain required inputs
if not label:
raise exception.NetworkNotCreated(req='--label')
# Size of "label" column in nova.networks is 255, hence the restriction
if len(label) > 255:
reason = _("Maximum allowed length for 'label' is 255.")
raise exception.InvalidInput(reason=reason)
if not (fixed_range_v4 or fixed_range_v6):
req = '--fixed_range_v4 or --fixed_range_v6'
raise exception.NetworkNotCreated(req=req)

bridge = bridge or FLAGS.flat_network_bridge
if not bridge:
bridge_required = ['nova.network.manager.FlatManager',
'nova.network.manager.FlatDHCPManager']
if FLAGS.network_manager in bridge_required:
raise exception.NetworkNotCreated(req='--bridge')

bridge_interface = (bridge_interface or FLAGS.flat_interface or
FLAGS.vlan_interface)
if not bridge_interface:
interface_required = ['nova.network.manager.VlanManager']
if FLAGS.network_manager in interface_required:
raise exception.NetworkNotCreated(req='--bridge_interface')

# sanitize other input using FLAGS if necessary
if not num_networks:
num_networks = FLAGS.num_networks
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:
network_size = FLAGS.network_size
subnet = 32 - int(math.log(network_size, 2))
oversize_msg = _('Subnet(s) too large, defaulting to /%s.'
' To override, specify network_size flag.') % subnet
print oversize_msg
else:
network_size = fixnet.size
if not multi_host:
multi_host = FLAGS.multi_host
else:
multi_host = multi_host == 'T'
if not vlan_start:
vlan_start = FLAGS.vlan_start
if not vpn_start:
vpn_start = FLAGS.vpn_start
if not dns1 and FLAGS.flat_network_dns:
dns1 = FLAGS.flat_network_dns

if not network_size:
network_size = FLAGS.network_size

if fixed_cidr:
fixed_cidr = netaddr.IPNetwork(fixed_cidr)

# create the network
kwargs = dict(((k, v) for k, v in locals().iteritems()
if v and k != "self"))
if multi_host is not None:
kwargs['multi_host'] = multi_host == 'T'
net_manager = importutils.import_object(FLAGS.network_manager)
net_manager.create_networks(context.get_admin_context(),
label=label,
cidr=fixed_range_v4,
multi_host=multi_host,
num_networks=int(num_networks),
network_size=int(network_size),
vlan_start=int(vlan_start),
vpn_start=int(vpn_start),
cidr_v6=fixed_range_v6,
gateway=gateway,
gateway_v6=gateway_v6,
bridge=bridge,
bridge_interface=bridge_interface,
dns1=dns1,
dns2=dns2,
project_id=project_id,
priority=priority,
uuid=uuid,
fixed_cidr=fixed_cidr)
try:
net_manager.create_networks(context.get_admin_context(), **kwargs)
except exc.HTTPBadRequest as ex:
print ex

def list(self):
"""List all created networks"""
Expand Down
29 changes: 26 additions & 3 deletions nova/api/openstack/compute/contrib/networks.py
Expand Up @@ -16,7 +16,7 @@
# License for the specific language governing permissions and limitations
# under the License.


import netaddr
import webob
from webob import exc

Expand Down Expand Up @@ -111,8 +111,31 @@ def delete(self, req, id):
raise exc.HTTPNotFound(_("Network not found"))
return exc.HTTPAccepted()

def create(self, req, id, body=None):
raise exc.HTTPNotImplemented()
def create(self, req, body):
context = req.environ['nova.context']
authorize(context)

def bad(e):
return exc.HTTPUnprocessableEntity(explanation=e)

if not (body and body.get("network")):
raise bad(_("Missing network in body"))

params = body["network"]
if not params.get("label"):
raise bad(_("Network label is required"))

cidr = params.get("cidr") or params.get("cidr_v6")
if not cidr:
raise bad(_("Network cidr or cidr_v6 is required"))

LOG.debug(_("Creating network with label %s") % params["label"])

params["num_networks"] = 1
params["network_size"] = netaddr.IPNetwork(cidr).size

network = self.network_api.create(context, **params)[0]
return {"network": network_dict(context, network)}

def add(self, req, body):
context = req.environ['nova.context']
Expand Down
90 changes: 87 additions & 3 deletions nova/network/manager.py
Expand Up @@ -769,6 +769,8 @@ class NetworkManager(manager.SchedulerDependentManager):

timeout_fixed_ips = True

required_create_args = []

def __init__(self, network_driver=None, *args, **kwargs):
if not network_driver:
network_driver = FLAGS.network_driver
Expand Down Expand Up @@ -1348,10 +1350,86 @@ def release_fixed_ip(self, context, address):
if not fixed_ip['allocated']:
self.db.fixed_ip_disassociate(context, address)

def create_networks(self, context, label, cidr, multi_host, num_networks,
network_size, cidr_v6, gateway, gateway_v6, bridge,
bridge_interface, dns1=None, dns2=None,
def create_networks(self, context,
label, cidr=None, multi_host=None, num_networks=None,
network_size=None, cidr_v6=None,
gateway=None, gateway_v6=None, bridge=None,
bridge_interface=None, dns1=None, dns2=None,
fixed_cidr=None, **kwargs):
arg_names = ("label", "cidr", "multi_host", "num_networks",
"network_size", "cidr_v6",
"gateway", "gateway_v6", "bridge",
"bridge_interface", "dns1", "dns2",
"fixed_cidr")
for name in arg_names:
kwargs[name] = locals()[name]
int_args = ("network_size", "num_networks",
"vlan_start", "vpn_start")
for key in int_args:
try:
kwargs[key] = int(kwargs[key])
except ValueError:
raise ValueError(_("%s must be an integer") % key)
except KeyError:
pass

# check for certain required inputs
label = kwargs["label"]
if not label:
raise exception.NetworkNotCreated(req="label")

# Size of "label" column in nova.networks is 255, hence the restriction
if len(label) > 255:
raise ValueError(_("Maximum allowed length for 'label' is 255."))

if not (kwargs["cidr"] or kwargs["cidr_v6"]):
raise exception.NetworkNotCreated(req="cidr or cidr_v6")

kwargs["bridge"] = kwargs["bridge"] or FLAGS.flat_network_bridge
kwargs["bridge_interface"] = (kwargs["bridge_interface"] or
FLAGS.flat_interface)

for fld in self.required_create_args:
if not kwargs[fld]:
raise exception.NetworkNotCreated(req=fld)

num_networks = kwargs["num_networks"] or FLAGS.num_networks
network_size = kwargs["network_size"]
cidr = kwargs["cidr"]
if not network_size and cidr:
fixnet = netaddr.IPNetwork(cidr)
each_subnet_size = fixnet.size / num_networks
if each_subnet_size > FLAGS.network_size:
network_size = FLAGS.network_size
subnet = 32 - int(math.log(network_size, 2))
oversize_msg = _(
'Subnet(s) too large, defaulting to /%s.'
' To override, specify network_size flag.') % subnet
LOG.warn(oversize_msg)
else:
network_size = fixnet.size
kwargs["num_networks"] = num_networks
kwargs["network_size"] = network_size

kwargs["multi_host"] = (FLAGS.multi_host
if kwargs["multi_host"] is None
else
utils.bool_from_str(kwargs["multi_host"]))
kwargs["vlan_start"] = kwargs.get("vlan_start") or FLAGS.vlan_start
kwargs["vpn_start"] = kwargs.get("vpn_start") or FLAGS.vpn_start
kwargs["dns1"] = kwargs["dns1"] or FLAGS.flat_network_dns
kwargs["network_size"] = kwargs["network_size"] or FLAGS.network_size

if kwargs["fixed_cidr"]:
kwargs["fixed_cidr"] = netaddr.IPNetwork(kwargs["fixed_cidr"])

return self._do_create_networks(context, **kwargs)

def _do_create_networks(self, context,
label, cidr, multi_host, num_networks,
network_size, cidr_v6, gateway, gateway_v6, bridge,
bridge_interface, dns1=None, dns2=None,
fixed_cidr=None, **kwargs):
"""Create networks based on parameters."""
# NOTE(jkoelker): these are dummy values to make sure iter works
# TODO(tr3buchet): disallow carving up networks
Expand Down Expand Up @@ -1719,6 +1797,8 @@ class FlatManager(NetworkManager):

timeout_fixed_ips = False

required_create_args = ['bridge']

def _allocate_fixed_ips(self, context, instance_id, host, networks,
**kwargs):
"""Calls allocate_fixed_ip once for each network."""
Expand Down Expand Up @@ -1793,6 +1873,7 @@ class FlatDHCPManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):

SHOULD_CREATE_BRIDGE = True
DHCP = True
required_create_args = ['bridge']

def init_host(self):
"""Do any initialization that needs to be run if this is a
Expand Down Expand Up @@ -1862,6 +1943,7 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
SHOULD_CREATE_BRIDGE = True
SHOULD_CREATE_VLAN = True
DHCP = True
required_create_args = ['bridge_interface']

def init_host(self):
"""Do any initialization that needs to be run if this is a
Expand Down Expand Up @@ -1941,6 +2023,8 @@ def create_networks(self, context, **kwargs):
'%(num_networks)s. Network size is %(network_size)s') %
kwargs)

kwargs['bridge_interface'] = (kwargs.get('bridge_interface') or
FLAGS.vlan_interface)
return NetworkManager.create_networks(
self, context, vpn=True, **kwargs)

Expand Down
2 changes: 1 addition & 1 deletion nova/network/quantum/nova_ipam_lib.py
Expand Up @@ -59,7 +59,7 @@ def create_subnet(self, context, label, tenant_id,
"""
admin_context = context.elevated()
subnet_size = len(netaddr.IPNetwork(cidr))
networks = manager.FlatManager.create_networks(self.net_manager,
networks = manager.FlatManager._do_create_networks(self.net_manager,
admin_context, label, cidr,
False, 1, subnet_size, cidr_v6, gateway,
gateway_v6, quantum_net_id, None, dns1, dns2,
Expand Down

0 comments on commit af687ff

Please sign in to comment.