nova/nova/api/openstack/compute/contrib/floating_ips_bulk.py

173 lines
5.9 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import netaddr
from oslo.config import cfg
import webob.exc
from nova.api.openstack import extensions
from nova import db
from nova import exception
from nova.openstack.common import log as logging
CONF = cfg.CONF
CONF.import_opt('default_floating_pool', 'nova.network.floating_ips')
CONF.import_opt('public_interface', 'nova.network.linux_net')
LOG = logging.getLogger(__name__)
authorize = extensions.extension_authorizer('compute', 'floating_ips_bulk')
class FloatingIPBulkController(object):
def index(self, req):
"""Return a list of all floating ips."""
context = req.environ['nova.context']
authorize(context)
return self._get_floating_ip_info(context)
def show(self, req, id):
"""Return a list of all floating ips for a given host."""
context = req.environ['nova.context']
authorize(context)
return self._get_floating_ip_info(context, id)
def _get_floating_ip_info(self, context, host=None):
floating_ip_info = {"floating_ip_info": []}
try:
if host is None:
floating_ips = db.floating_ip_get_all(context)
else:
floating_ips = db.floating_ip_get_all_by_host(context, host)
except exception.NoFloatingIpsDefined:
return floating_ip_info
for floating_ip in floating_ips:
instance_uuid = None
if floating_ip['fixed_ip_id']:
fixed_ip = db.fixed_ip_get(context, floating_ip['fixed_ip_id'])
instance_uuid = fixed_ip['instance_uuid']
result = {'address': floating_ip['address'],
'pool': floating_ip['pool'],
'interface': floating_ip['interface'],
'project_id': floating_ip['project_id'],
'instance_uuid': instance_uuid}
floating_ip_info['floating_ip_info'].append(result)
return floating_ip_info
def create(self, req, body):
"""Bulk create floating ips."""
context = req.environ['nova.context']
authorize(context)
if 'floating_ips_bulk_create' not in body:
raise webob.exc.HTTPUnprocessableEntity()
params = body['floating_ips_bulk_create']
LOG.debug(params)
if 'ip_range' not in params:
raise webob.exc.HTTPUnprocessableEntity()
ip_range = params['ip_range']
pool = params.get('pool', CONF.default_floating_pool)
interface = params.get('interface', CONF.public_interface)
try:
ips = ({'address': str(address),
'pool': pool,
'interface': interface}
for address in self._address_to_hosts(ip_range))
except exception.InvalidInput as exc:
raise webob.exc.HTTPBadRequest(explanation=exc.format_message())
try:
db.floating_ip_bulk_create(context, ips)
except exception.FloatingIpExists as exc:
raise webob.exc.HTTPBadRequest(explanation=exc.format_message())
return {"floating_ips_bulk_create": {"ip_range": ip_range,
"pool": pool,
"interface": interface}}
def update(self, req, id, body):
"""Bulk delete floating IPs."""
context = req.environ['nova.context']
authorize(context)
if id != "delete":
raise webob.exc.HTTPNotFound("Unknown action")
try:
ip_range = body['ip_range']
except (TypeError, KeyError):
raise webob.exc.HTTPUnprocessableEntity()
try:
ips = ({'address': str(address)}
for address in self._address_to_hosts(ip_range))
except exception.InvalidInput as exc:
raise webob.exc.HTTPBadRequest(explanation=exc.format_message())
db.floating_ip_bulk_destroy(context, ips)
return {"floating_ips_bulk_delete": ip_range}
def _address_to_hosts(self, addresses):
"""
Iterate over hosts within an address range.
If an explicit range specifier is missing, the parameter is
interpreted as a specific individual address.
"""
try:
return [netaddr.IPAddress(addresses)]
except ValueError:
net = netaddr.IPNetwork(addresses)
if net.size < 4:
reason = _("/%s should be specified as single address(es) "
"not in cidr format") % net.prefixlen
raise exception.InvalidInput(reason=reason)
else:
return net.iter_hosts()
except netaddr.AddrFormatError as exc:
raise exception.InvalidInput(reason=str(exc))
class Floating_ips_bulk(extensions.ExtensionDescriptor):
"""Bulk handling of Floating IPs."""
name = "FloatingIpsBulk"
alias = "os-floating-ips-bulk"
namespace = ("http://docs.openstack.org/compute/ext/"
"floating_ips_bulk/api/v2")
updated = "2012-10-29T13:25:27-06:00"
def __init__(self, ext_mgr):
ext_mgr.register(self)
def get_resources(self):
resources = []
resource = extensions.ResourceExtension('os-floating-ips-bulk',
FloatingIPBulkController())
resources.append(resource)
return resources