174 lines
5.5 KiB
Python
174 lines
5.5 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2011 OpenStack LLC.
|
|
# Copyright 2011 Grid Dynamics
|
|
# Copyright 2011 Eldar Nugaev, Kirill Shileev, Ilya Alekseyev
|
|
#
|
|
# 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
|
|
from webob import exc
|
|
|
|
from nova import exception
|
|
from nova import network
|
|
from nova import rpc
|
|
from nova.api.openstack import faults
|
|
from nova.api.openstack import extensions
|
|
|
|
|
|
def _translate_floating_ip_view(floating_ip):
|
|
result = {'id': floating_ip['id'],
|
|
'ip': floating_ip['address']}
|
|
if 'fixed_ip' in floating_ip:
|
|
result['fixed_ip'] = floating_ip['fixed_ip']['address']
|
|
else:
|
|
result['fixed_ip'] = None
|
|
if 'instance' in floating_ip:
|
|
result['instance_id'] = floating_ip['instance']['id']
|
|
else:
|
|
result['instance_id'] = None
|
|
return {'floating_ip': result}
|
|
|
|
|
|
def _translate_floating_ips_view(floating_ips):
|
|
return {'floating_ips': [_translate_floating_ip_view(floating_ip)
|
|
for floating_ip in floating_ips]}
|
|
|
|
|
|
class FloatingIPController(object):
|
|
"""The Floating IPs API controller for the OpenStack API."""
|
|
|
|
_serialization_metadata = {
|
|
'application/xml': {
|
|
"attributes": {
|
|
"floating_ip": [
|
|
"id",
|
|
"ip",
|
|
"instance_id",
|
|
"fixed_ip",
|
|
]}}}
|
|
|
|
def __init__(self):
|
|
self.network_api = network.API()
|
|
super(FloatingIPController, self).__init__()
|
|
|
|
def show(self, req, id):
|
|
"""Return data about the given floating ip."""
|
|
context = req.environ['nova.context']
|
|
|
|
try:
|
|
floating_ip = self.network_api.get_floating_ip(context, id)
|
|
except exception.NotFound:
|
|
return faults.Fault(exc.HTTPNotFound())
|
|
|
|
return _translate_floating_ip_view(floating_ip)
|
|
|
|
def index(self, req):
|
|
context = req.environ['nova.context']
|
|
|
|
floating_ips = self.network_api.list_floating_ips(context)
|
|
|
|
return _translate_floating_ips_view(floating_ips)
|
|
|
|
def create(self, req, body):
|
|
context = req.environ['nova.context']
|
|
|
|
try:
|
|
address = self.network_api.allocate_floating_ip(context)
|
|
ip = self.network_api.get_floating_ip_by_ip(context, address)
|
|
except rpc.RemoteError as ex:
|
|
# NOTE(tr3buchet) - why does this block exist?
|
|
if ex.exc_type == 'NoMoreFloatingIps':
|
|
raise exception.NoMoreFloatingIps()
|
|
else:
|
|
raise
|
|
|
|
return {'allocated': {
|
|
"id": ip['id'],
|
|
"floating_ip": ip['address']}}
|
|
|
|
def delete(self, req, id):
|
|
context = req.environ['nova.context']
|
|
|
|
ip = self.network_api.get_floating_ip(context, id)
|
|
self.network_api.release_floating_ip(context, address=ip)
|
|
|
|
return {'released': {
|
|
"id": ip['id'],
|
|
"floating_ip": ip['address']}}
|
|
|
|
def associate(self, req, id, body):
|
|
""" /floating_ips/{id}/associate fixed ip in body """
|
|
context = req.environ['nova.context']
|
|
floating_ip = self._get_ip_by_id(context, id)
|
|
|
|
fixed_ip = body['associate_address']['fixed_ip']
|
|
|
|
try:
|
|
self.network_api.associate_floating_ip(context,
|
|
floating_ip, fixed_ip)
|
|
except rpc.RemoteError:
|
|
raise
|
|
|
|
return {'associated':
|
|
{
|
|
"floating_ip_id": id,
|
|
"floating_ip": floating_ip,
|
|
"fixed_ip": fixed_ip}}
|
|
|
|
def disassociate(self, req, id, body):
|
|
""" POST /floating_ips/{id}/disassociate """
|
|
context = req.environ['nova.context']
|
|
floating_ip = self.network_api.get_floating_ip(context, id)
|
|
address = floating_ip['address']
|
|
fixed_ip = floating_ip['fixed_ip']['address']
|
|
|
|
try:
|
|
self.network_api.disassociate_floating_ip(context, address)
|
|
except rpc.RemoteError:
|
|
raise
|
|
|
|
return {'disassociated': {'floating_ip': address,
|
|
'fixed_ip': fixed_ip}}
|
|
|
|
def _get_ip_by_id(self, context, value):
|
|
"""Checks that value is id and then returns its address."""
|
|
return self.network_api.get_floating_ip(context, value)['address']
|
|
|
|
|
|
class Floating_ips(extensions.ExtensionDescriptor):
|
|
def get_name(self):
|
|
return "Floating_ips"
|
|
|
|
def get_alias(self):
|
|
return "os-floating-ips"
|
|
|
|
def get_description(self):
|
|
return "Floating IPs support"
|
|
|
|
def get_namespace(self):
|
|
return "http://docs.openstack.org/ext/floating_ips/api/v1.1"
|
|
|
|
def get_updated(self):
|
|
return "2011-06-16T00:00:00+00:00"
|
|
|
|
def get_resources(self):
|
|
resources = []
|
|
|
|
res = extensions.ResourceExtension('os-floating-ips',
|
|
FloatingIPController(),
|
|
member_actions={
|
|
'associate': 'POST',
|
|
'disassociate': 'POST'})
|
|
resources.append(res)
|
|
|
|
return resources
|