Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / floating_ips.py @ 47c27955

History | View | Annotate | Download (9.3 kB)

1 59183afc Christos Stavrakakis
# Copyright 2013 GRNET S.A. All rights reserved.
2 59183afc Christos Stavrakakis
#
3 59183afc Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 59183afc Christos Stavrakakis
# without modification, are permitted provided that the following
5 59183afc Christos Stavrakakis
# conditions are met:
6 59183afc Christos Stavrakakis
#
7 59183afc Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 59183afc Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 59183afc Christos Stavrakakis
#      disclaimer.
10 59183afc Christos Stavrakakis
#
11 59183afc Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 59183afc Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 59183afc Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 59183afc Christos Stavrakakis
#      provided with the distribution.
15 59183afc Christos Stavrakakis
#
16 59183afc Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 59183afc Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 59183afc Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 59183afc Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 59183afc Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 59183afc Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 59183afc Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 59183afc Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 59183afc Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 59183afc Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 59183afc Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 59183afc Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 59183afc Christos Stavrakakis
#
29 59183afc Christos Stavrakakis
# The views and conclusions contained in the software and
30 59183afc Christos Stavrakakis
# documentation are those of the authors and should not be
31 59183afc Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 59183afc Christos Stavrakakis
# or implied, of GRNET S.A.
33 59183afc Christos Stavrakakis
34 59183afc Christos Stavrakakis
from django.conf.urls.defaults import patterns
35 59183afc Christos Stavrakakis
from django.db import transaction
36 59183afc Christos Stavrakakis
from django.http import HttpResponse
37 59183afc Christos Stavrakakis
from django.utils import simplejson as json
38 59183afc Christos Stavrakakis
39 59183afc Christos Stavrakakis
from snf_django.lib import api
40 59183afc Christos Stavrakakis
from snf_django.lib.api import faults, utils
41 59183afc Christos Stavrakakis
from synnefo.api import util
42 0292883e Christos Stavrakakis
from synnefo.logic import ips
43 fde2c1f7 Christos Stavrakakis
from synnefo.db.models import Network, IPAddress
44 59183afc Christos Stavrakakis
45 59183afc Christos Stavrakakis
from logging import getLogger
46 59183afc Christos Stavrakakis
log = getLogger(__name__)
47 59183afc Christos Stavrakakis
48 e4f484da Marios Kogias
'''
49 7d368e73 Christos Stavrakakis
ips_urlpatterns = patterns(
50 59183afc Christos Stavrakakis
    'synnefo.api.floating_ips',
51 59183afc Christos Stavrakakis
    (r'^(?:/|.json|.xml)?$', 'demux'),
52 59183afc Christos Stavrakakis
    (r'^/(\w+)(?:.json|.xml)?$', 'floating_ip_demux'),
53 59183afc Christos Stavrakakis
)
54 59183afc Christos Stavrakakis

55 7d368e73 Christos Stavrakakis
pools_urlpatterns = patterns(
56 7d368e73 Christos Stavrakakis
    "synnefo.api.floating_ips",
57 7d368e73 Christos Stavrakakis
    (r'^(?:/|.json|.xml)?$', 'list_floating_ip_pools'),
58 7d368e73 Christos Stavrakakis
)
59 e4f484da Marios Kogias
'''
60 e4f484da Marios Kogias
61 e4f484da Marios Kogias
ips_urlpatterns = patterns(
62 e4f484da Marios Kogias
    'synnefo.api.floating_ips',
63 e4f484da Marios Kogias
    (r'^(?:/|.json|.xml)?$', 'demux'),
64 e4f484da Marios Kogias
    (r'^/detail(?:.json|.xml)?$', 'list_floating_ips', {'detail': True}),
65 e4f484da Marios Kogias
    (r'^/(\w+)(?:/|.json|.xml)?$', 'floating_ip_demux'))
66 7d368e73 Christos Stavrakakis
67 59183afc Christos Stavrakakis
68 59183afc Christos Stavrakakis
def demux(request):
69 59183afc Christos Stavrakakis
    if request.method == 'GET':
70 59183afc Christos Stavrakakis
        return list_floating_ips(request)
71 59183afc Christos Stavrakakis
    elif request.method == 'POST':
72 59183afc Christos Stavrakakis
        return allocate_floating_ip(request)
73 59183afc Christos Stavrakakis
    else:
74 2aba7764 Sofia Papagiannaki
        return api.api_method_not_allowed(request,
75 2aba7764 Sofia Papagiannaki
                                          allowed_methods=['GET', 'POST'])
76 59183afc Christos Stavrakakis
77 59183afc Christos Stavrakakis
78 59183afc Christos Stavrakakis
def floating_ip_demux(request, floating_ip_id):
79 59183afc Christos Stavrakakis
    if request.method == 'GET':
80 59183afc Christos Stavrakakis
        return get_floating_ip(request, floating_ip_id)
81 59183afc Christos Stavrakakis
    elif request.method == 'DELETE':
82 59183afc Christos Stavrakakis
        return release_floating_ip(request, floating_ip_id)
83 e4f484da Marios Kogias
    elif request.method == 'PUT':
84 e4f484da Marios Kogias
        return update_floating_ip(request, floating_ip_id)
85 59183afc Christos Stavrakakis
    else:
86 2aba7764 Sofia Papagiannaki
        return api.api_method_not_allowed(request,
87 2aba7764 Sofia Papagiannaki
                                          allowed_methods=['GET', 'DELETE'])
88 59183afc Christos Stavrakakis
89 59183afc Christos Stavrakakis
90 59183afc Christos Stavrakakis
def ip_to_dict(floating_ip):
91 fde2c1f7 Christos Stavrakakis
    machine_id = None
92 e4f484da Marios Kogias
    port_id = None
93 fde2c1f7 Christos Stavrakakis
    if floating_ip.nic is not None:
94 fde2c1f7 Christos Stavrakakis
        machine_id = floating_ip.nic.machine_id
95 e4f484da Marios Kogias
        port_id = floating_ip.nic.id
96 e4f484da Marios Kogias
    return {"fixed_ip_address": None,
97 59183afc Christos Stavrakakis
            "id": str(floating_ip.id),
98 59183afc Christos Stavrakakis
            "instance_id": str(machine_id) if machine_id else None,
99 e4f484da Marios Kogias
            "floating_ip_address": floating_ip.address,
100 03d430b5 Christos Stavrakakis
            "port_id": str(port_id) if port_id else None,
101 7219c7a3 Christos Stavrakakis
            "floating_network_id": str(floating_ip.network_id),
102 7219c7a3 Christos Stavrakakis
            "deleted": floating_ip.deleted}
103 59183afc Christos Stavrakakis
104 59183afc Christos Stavrakakis
105 1cbe2522 Christos Stavrakakis
@api.api_method(http_method="GET", user_required=True, logger=log,
106 1cbe2522 Christos Stavrakakis
                serializations=["json"])
107 59183afc Christos Stavrakakis
def list_floating_ips(request):
108 59183afc Christos Stavrakakis
    """Return user reserved floating IPs"""
109 59183afc Christos Stavrakakis
    log.debug("list_floating_ips")
110 59183afc Christos Stavrakakis
111 59183afc Christos Stavrakakis
    userid = request.user_uniq
112 fde2c1f7 Christos Stavrakakis
    floating_ips = IPAddress.objects.filter(userid=userid, deleted=False,
113 fde2c1f7 Christos Stavrakakis
                                            floating_ip=True).order_by("id")\
114 fde2c1f7 Christos Stavrakakis
                                    .select_related("nic")
115 b6bc4afa Christos Stavrakakis
    floating_ips = utils.filter_modified_since(request, objects=floating_ips)
116 59183afc Christos Stavrakakis
117 59183afc Christos Stavrakakis
    floating_ips = map(ip_to_dict, floating_ips)
118 59183afc Christos Stavrakakis
119 59183afc Christos Stavrakakis
    request.serialization = "json"
120 53b0ea25 Christos Stavrakakis
    data = json.dumps({"floatingips": floating_ips})
121 59183afc Christos Stavrakakis
122 59183afc Christos Stavrakakis
    return HttpResponse(data, status=200)
123 59183afc Christos Stavrakakis
124 59183afc Christos Stavrakakis
125 1cbe2522 Christos Stavrakakis
@api.api_method(http_method="GET", user_required=True, logger=log,
126 1cbe2522 Christos Stavrakakis
                serializations=["json"])
127 59183afc Christos Stavrakakis
def get_floating_ip(request, floating_ip_id):
128 59183afc Christos Stavrakakis
    """Return information for a floating IP."""
129 59183afc Christos Stavrakakis
    userid = request.user_uniq
130 fde2c1f7 Christos Stavrakakis
    floating_ip = util.get_floating_ip_by_id(userid, floating_ip_id)
131 59183afc Christos Stavrakakis
    request.serialization = "json"
132 53b0ea25 Christos Stavrakakis
    data = json.dumps({"floatingip": ip_to_dict(floating_ip)})
133 59183afc Christos Stavrakakis
    return HttpResponse(data, status=200)
134 59183afc Christos Stavrakakis
135 59183afc Christos Stavrakakis
136 1cbe2522 Christos Stavrakakis
@api.api_method(http_method='POST', user_required=True, logger=log,
137 1cbe2522 Christos Stavrakakis
                serializations=["json"])
138 fde2c1f7 Christos Stavrakakis
@transaction.commit_on_success
139 59183afc Christos Stavrakakis
def allocate_floating_ip(request):
140 59183afc Christos Stavrakakis
    """Allocate a floating IP."""
141 59183afc Christos Stavrakakis
    req = utils.get_request_dict(request)
142 e4f484da Marios Kogias
    floating_ip_dict = api.utils.get_attribute(req, "floatingip",
143 14402edc Christos Stavrakakis
                                               required=True, attr_type=dict)
144 59183afc Christos Stavrakakis
    log.info('allocate_floating_ip %s', req)
145 59183afc Christos Stavrakakis
146 59183afc Christos Stavrakakis
    userid = request.user_uniq
147 47c27955 Giorgos Korfiatis
    project = floating_ip_dict.get("project", None)
148 e4f484da Marios Kogias
149 e4f484da Marios Kogias
    # the network_pool is a mandatory field
150 4edfc376 Christos Stavrakakis
    network_id = api.utils.get_attribute(floating_ip_dict,
151 4edfc376 Christos Stavrakakis
                                         "floating_network_id",
152 14402edc Christos Stavrakakis
                                         required=False,
153 14402edc Christos Stavrakakis
                                         attr_type=(basestring, int))
154 4edfc376 Christos Stavrakakis
    if network_id is None:
155 47c27955 Giorgos Korfiatis
        floating_ip = ips.create_floating_ip(userid, project=project)
156 4edfc376 Christos Stavrakakis
    else:
157 4edfc376 Christos Stavrakakis
        try:
158 4edfc376 Christos Stavrakakis
            network_id = int(network_id)
159 4edfc376 Christos Stavrakakis
        except ValueError:
160 4edfc376 Christos Stavrakakis
            raise faults.BadRequest("Invalid networkd ID.")
161 4edfc376 Christos Stavrakakis
162 4edfc376 Christos Stavrakakis
        network = util.get_network(network_id, userid, for_update=True,
163 4edfc376 Christos Stavrakakis
                                   non_deleted=True)
164 4edfc376 Christos Stavrakakis
        address = api.utils.get_attribute(floating_ip_dict,
165 4edfc376 Christos Stavrakakis
                                          "floating_ip_address",
166 14402edc Christos Stavrakakis
                                          required=False,
167 14402edc Christos Stavrakakis
                                          attr_type=basestring)
168 47c27955 Giorgos Korfiatis
        floating_ip = ips.create_floating_ip(userid, network, address,
169 47c27955 Giorgos Korfiatis
                                             project=project)
170 fde2c1f7 Christos Stavrakakis
171 fde2c1f7 Christos Stavrakakis
    log.info("User '%s' allocated floating IP '%s'", userid, floating_ip)
172 59183afc Christos Stavrakakis
    request.serialization = "json"
173 53b0ea25 Christos Stavrakakis
    data = json.dumps({"floatingip": ip_to_dict(floating_ip)})
174 59183afc Christos Stavrakakis
    return HttpResponse(data, status=200)
175 59183afc Christos Stavrakakis
176 59183afc Christos Stavrakakis
177 1cbe2522 Christos Stavrakakis
@api.api_method(http_method='DELETE', user_required=True, logger=log,
178 1cbe2522 Christos Stavrakakis
                serializations=["json"])
179 59183afc Christos Stavrakakis
@transaction.commit_on_success
180 59183afc Christos Stavrakakis
def release_floating_ip(request, floating_ip_id):
181 59183afc Christos Stavrakakis
    """Release a floating IP."""
182 59183afc Christos Stavrakakis
    userid = request.user_uniq
183 59183afc Christos Stavrakakis
    log.info("release_floating_ip '%s'. User '%s'.", floating_ip_id, userid)
184 fde2c1f7 Christos Stavrakakis
185 fde2c1f7 Christos Stavrakakis
    floating_ip = util.get_floating_ip_by_id(userid, floating_ip_id,
186 fde2c1f7 Christos Stavrakakis
                                             for_update=True)
187 0292883e Christos Stavrakakis
    ips.delete_floating_ip(floating_ip)
188 59183afc Christos Stavrakakis
    log.info("User '%s' released IP '%s", userid, floating_ip)
189 59183afc Christos Stavrakakis
190 59183afc Christos Stavrakakis
    return HttpResponse(status=204)
191 7d368e73 Christos Stavrakakis
192 7d368e73 Christos Stavrakakis
193 e4f484da Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log,
194 e4f484da Marios Kogias
                serializations=["json"])
195 e4f484da Marios Kogias
@transaction.commit_on_success
196 e4f484da Marios Kogias
def update_floating_ip(request, floating_ip_id):
197 e4f484da Marios Kogias
    """Update a floating IP."""
198 1fb3293d Christos Stavrakakis
    raise faults.NotImplemented("Updating a floating IP is not supported.")
199 d610698e Christos Stavrakakis
    #userid = request.user_uniq
200 d610698e Christos Stavrakakis
    #log.info("update_floating_ip '%s'. User '%s'.", floating_ip_id, userid)
201 d610698e Christos Stavrakakis
202 d610698e Christos Stavrakakis
    #req = utils.get_request_dict(request)
203 d610698e Christos Stavrakakis
    #info = api.utils.get_attribute(req, "floatingip", required=True)
204 d610698e Christos Stavrakakis
205 d610698e Christos Stavrakakis
    #device_id = api.utils.get_attribute(info, "device_id", required=False)
206 d610698e Christos Stavrakakis
207 d610698e Christos Stavrakakis
    #floating_ip = util.get_floating_ip_by_id(userid, floating_ip_id,
208 d610698e Christos Stavrakakis
    #                                         for_update=True)
209 d610698e Christos Stavrakakis
    #if device_id:
210 d610698e Christos Stavrakakis
    #    # attach
211 d610698e Christos Stavrakakis
    #    vm = util.get_vm(device_id, userid)
212 d610698e Christos Stavrakakis
    #    nic, floating_ip = servers.create_nic(vm, ipaddress=floating_ip)
213 d610698e Christos Stavrakakis
    #    backend.connect_to_network(vm, nic)
214 d610698e Christos Stavrakakis
    #else:
215 d610698e Christos Stavrakakis
    #    # dettach
216 d610698e Christos Stavrakakis
    #    nic = floating_ip.nic
217 d610698e Christos Stavrakakis
    #    if not nic:
218 d610698e Christos Stavrakakis
    #        raise faults.BadRequest("The floating IP is not associated\
219 d610698e Christos Stavrakakis
    #                                with any device")
220 d610698e Christos Stavrakakis
    #    vm = nic.machine
221 d610698e Christos Stavrakakis
    #    servers.disconnect(vm, nic)
222 d610698e Christos Stavrakakis
    #return HttpResponse(status=202)
223 e4f484da Marios Kogias
224 e4f484da Marios Kogias
225 fde2c1f7 Christos Stavrakakis
# Floating IP pools
226 1cbe2522 Christos Stavrakakis
@api.api_method(http_method='GET', user_required=True, logger=log,
227 1cbe2522 Christos Stavrakakis
                serializations=["json"])
228 7d368e73 Christos Stavrakakis
def list_floating_ip_pools(request):
229 fde2c1f7 Christos Stavrakakis
    networks = Network.objects.filter(public=True, floating_ip_pool=True,
230 fde2c1f7 Christos Stavrakakis
                                      deleted=False)
231 b6bc4afa Christos Stavrakakis
    networks = utils.filter_modified_since(request, objects=networks)
232 d610698e Christos Stavrakakis
    floating_ip_pools = map(network_to_floating_ip_pool, networks)
233 7d368e73 Christos Stavrakakis
    request.serialization = "json"
234 d610698e Christos Stavrakakis
    data = json.dumps({"floating_ip_pools": floating_ip_pools})
235 7d368e73 Christos Stavrakakis
    request.serialization = "json"
236 7d368e73 Christos Stavrakakis
    return HttpResponse(data, status=200)
237 fde2c1f7 Christos Stavrakakis
238 fde2c1f7 Christos Stavrakakis
239 fde2c1f7 Christos Stavrakakis
def network_to_floating_ip_pool(network):
240 fde2c1f7 Christos Stavrakakis
    """Convert a 'Network' object to a floating IP pool dict."""
241 fde2c1f7 Christos Stavrakakis
    total, free = network.ip_count()
242 fde2c1f7 Christos Stavrakakis
    return {"name": str(network.id),
243 fde2c1f7 Christos Stavrakakis
            "size": total,
244 7219c7a3 Christos Stavrakakis
            "free": free,
245 7219c7a3 Christos Stavrakakis
            "deleted": network.deleted}