Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / neutron / network_views.py @ 0dae1b9f

History | View | Annotate | Download (8.5 kB)

1 d6b24130 Marios Kogias
from django.http import HttpResponse
2 d6b24130 Marios Kogias
from django.utils import simplejson as json
3 d6b24130 Marios Kogias
from django.db import transaction
4 d6b24130 Marios Kogias
from django.db.models import Q
5 d6b24130 Marios Kogias
from synnefo.db.pools import EmptyPool
6 d6b24130 Marios Kogias
from synnefo.db.utils import validate_mac
7 d6b24130 Marios Kogias
from django.conf import settings
8 d6b24130 Marios Kogias
from snf_django.lib import api
9 d6b24130 Marios Kogias
from snf_django.lib.api import utils
10 d6b24130 Marios Kogias
from synnefo.logic import backend
11 d6b24130 Marios Kogias
from django.template.loader import render_to_string
12 d6b24130 Marios Kogias
from synnefo.api import util
13 d6b24130 Marios Kogias
from models import Network
14 d6b24130 Marios Kogias
15 d6b24130 Marios Kogias
from logging import getLogger
16 d6b24130 Marios Kogias
17 d6b24130 Marios Kogias
from synnefo import quotas
18 d6b24130 Marios Kogias
19 d6b24130 Marios Kogias
20 d6b24130 Marios Kogias
log = getLogger(__name__)
21 d6b24130 Marios Kogias
22 d6e16760 Marios Kogias
23 d6b24130 Marios Kogias
def demux(request):
24 d6b24130 Marios Kogias
    if request.method == 'GET':
25 d6b24130 Marios Kogias
        #return HttpResponse("in network get")
26 d6b24130 Marios Kogias
        return list_networks(request)
27 d6b24130 Marios Kogias
    elif request.method == 'POST':
28 b0cda6f9 Marios Kogias
        return create_network(request)
29 b0cda6f9 Marios Kogias
        #return HttpResponse("in network post")
30 d6b24130 Marios Kogias
    else:
31 d6b24130 Marios Kogias
        return api.api_method_not_allowed(request)
32 d6b24130 Marios Kogias
33 d6e16760 Marios Kogias
34 d6e16760 Marios Kogias
def network_demux(request, offset):
35 d6b24130 Marios Kogias
36 d6b24130 Marios Kogias
    if request.method == 'GET':
37 d6e16760 Marios Kogias
        return get_network(request, offset)
38 d6b24130 Marios Kogias
        #return HttpResponse("in network det get")
39 d6b24130 Marios Kogias
    elif request.method == 'DELETE':
40 d6e16760 Marios Kogias
        return delete_network(request, offset)
41 d6b24130 Marios Kogias
        #return HttpResponse("in network det delete")
42 d6b24130 Marios Kogias
    elif request.method == 'PUT':
43 d6e16760 Marios Kogias
        return update_network(request, offset)
44 b0cda6f9 Marios Kogias
        #return HttpResponse("in network det put")
45 d6b24130 Marios Kogias
    else:
46 d6b24130 Marios Kogias
        return api.api_method_not_allowed(request)
47 d6b24130 Marios Kogias
48 d6e16760 Marios Kogias
49 d6b24130 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
50 d6b24130 Marios Kogias
def list_networks(request):
51 d6b24130 Marios Kogias
    log.debug('list_networks')
52 d6b24130 Marios Kogias
53 d6e16760 Marios Kogias
    user_networks = Network.objects.filter(
54 d6e16760 Marios Kogias
        Q(userid=request.user_uniq) | Q(public=True))
55 d6b24130 Marios Kogias
56 d6b24130 Marios Kogias
    user_networks = user_networks.filter(deleted=False)
57 d6b24130 Marios Kogias
58 d6b24130 Marios Kogias
    networks = [network_to_dict(network)
59 d6b24130 Marios Kogias
                for network in user_networks.order_by('id')]
60 d6b24130 Marios Kogias
61 d6b24130 Marios Kogias
    if request.serialization == 'xml':
62 d6b24130 Marios Kogias
        data = render_to_string('list_networks.xml', {
63 d6e16760 Marios Kogias
            'networks': networks})
64 d6b24130 Marios Kogias
    else:
65 d6b24130 Marios Kogias
        data = json.dumps({'networks': networks})
66 d6b24130 Marios Kogias
67 d6b24130 Marios Kogias
    return HttpResponse(data, status=200)
68 d6b24130 Marios Kogias
69 d6e16760 Marios Kogias
70 d6b24130 Marios Kogias
@api.api_method(http_method='POST', user_required=True, logger=log)
71 d6b24130 Marios Kogias
@transaction.commit_manually
72 d6e16760 Marios Kogias
def create_network(request):
73 d6b24130 Marios Kogias
    '''
74 d6b24130 Marios Kogias
    This operation does not require a rest body. If specified, the body might
75 d6b24130 Marios Kogias
    include one or more of the following attributes:
76 d6b24130 Marios Kogias

77 d6b24130 Marios Kogias
    name: a string specifying a symbolic name for the network, which is not
78 d6b24130 Marios Kogias
        required to be unique;
79 d6b24130 Marios Kogias

80 d6e16760 Marios Kogias
    admin_state_up: a bool value specifying the administrative status of
81 d6e16760 Marios Kogias
        the network;
82 d6b24130 Marios Kogias

83 d6b24130 Marios Kogias
    2 more attirbutes for administrative users (not supported)
84 d6b24130 Marios Kogias
    '''
85 d6b24130 Marios Kogias
    try:
86 d6b24130 Marios Kogias
        user_id = request.user_uniq
87 d6b24130 Marios Kogias
        if request.raw_post_data:
88 d6b24130 Marios Kogias
            req = utils.get_request_dict(request)
89 d6b24130 Marios Kogias
            log.info('create_network %s', req)
90 d6b24130 Marios Kogias
            try:
91 d6e16760 Marios Kogias
                d = req['network']
92 d6e16760 Marios Kogias
                name = d['name']
93 d6b24130 Marios Kogias
            except KeyError:
94 d6e16760 Marios Kogias
                raise api.faults.BadRequest("Malformed request")
95 d6b24130 Marios Kogias
96 d6b24130 Marios Kogias
            flavor = d.get("type", None)
97 d6b24130 Marios Kogias
            if flavor is None:
98 d6b24130 Marios Kogias
                #raise faults.BadRequest("Missing request parameter 'type'")
99 d6b24130 Marios Kogias
                # set default flavor
100 d6b24130 Marios Kogias
                #FIX ME!!!
101 d6e16760 Marios Kogias
                flavor = "MAC_FILTERED"
102 d6b24130 Marios Kogias
                log.info("not found flavor")
103 d6b24130 Marios Kogias
            elif flavor not in Network.FLAVORS.keys():
104 d6e16760 Marios Kogias
                raise api.faults.BadRequest("Invalid network type '%s'"
105 d6e16760 Marios Kogias
                                            % flavor)
106 d6b24130 Marios Kogias
                log.info("found flavor 1")
107 d6b24130 Marios Kogias
            elif flavor not in settings.API_ENABLED_NETWORK_FLAVORS:
108 d6b24130 Marios Kogias
                log.info("found flavor2")
109 d6e16760 Marios Kogias
                msg = "Can not create network of type '%s'"
110 d6e16760 Marios Kogias
                raise api.faults.Forbidden(msg % flavor)
111 d6e16760 Marios Kogias
            # Get and validate flavor. Flavors are still exposed
112 d6e16760 Marios Kogias
            #as 'type' in the API.
113 d6b24130 Marios Kogias
        else:
114 d6b24130 Marios Kogias
            name = ""
115 d6e16760 Marios Kogias
            flavor = "MAC_FILTERED"   # this is the default FIX ME
116 d6b24130 Marios Kogias
117 d6b24130 Marios Kogias
        try:
118 b0cda6f9 Marios Kogias
            #mode, link, mac_prefix, tags = util.values_from_flavor(flavor)
119 b0cda6f9 Marios Kogias
120 b0cda6f9 Marios Kogias
            #validate_mac(mac_prefix + "0:00:00:00")
121 d6b24130 Marios Kogias
            network = Network.objects.create(
122 d6b24130 Marios Kogias
                name=name,
123 d6b24130 Marios Kogias
                userid=user_id,
124 d6b24130 Marios Kogias
                flavor=flavor,
125 d6e16760 Marios Kogias
                #mode=mode,
126 d6e16760 Marios Kogias
                #link=link,
127 d6e16760 Marios Kogias
                #mac_prefix=mac_prefix,
128 d6e16760 Marios Kogias
                #tags=tags,
129 d6b24130 Marios Kogias
                action='CREATE',
130 d6b24130 Marios Kogias
                state='ACTIVE')
131 d6b24130 Marios Kogias
        except EmptyPool:
132 d6e16760 Marios Kogias
            msg = "Failed to allocate resources for network of type: %s"
133 d6e16760 Marios Kogias
            log.error(msg, flavor)
134 d6e16760 Marios Kogias
            raise api.faults.ServiceUnavailable("Failed to allocate network\
135 d6e16760 Marios Kogias
                  resources")
136 d6b24130 Marios Kogias
137 d6b24130 Marios Kogias
        # Issue commission to Quotaholder and accept it since at the end of
138 d6b24130 Marios Kogias
        # this transaction the Network object will be created in the DB.
139 d6b24130 Marios Kogias
        # Note: the following call does a commit!
140 d6b24130 Marios Kogias
        #quotas.issue_and_accept_commission(network)
141 d6b24130 Marios Kogias
        # COME BACK....
142 d6b24130 Marios Kogias
143 d6b24130 Marios Kogias
    except:
144 d6b24130 Marios Kogias
        transaction.rollback()
145 d6b24130 Marios Kogias
        log.info("roll")
146 d6b24130 Marios Kogias
        raise
147 d6b24130 Marios Kogias
    else:
148 d6b24130 Marios Kogias
        transaction.commit()
149 d6b24130 Marios Kogias
        log.info("commit")
150 d6b24130 Marios Kogias
    networkdict = network_to_dict(network)
151 d6b24130 Marios Kogias
    response = render_network(request, networkdict, status=201)
152 d6b24130 Marios Kogias
153 d6b24130 Marios Kogias
    return response
154 d6b24130 Marios Kogias
155 d6e16760 Marios Kogias
156 d6b24130 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
157 d6e16760 Marios Kogias
def get_network(request, network_id):
158 d6b24130 Marios Kogias
    log.debug('get_network_details %s', network_id)
159 d6b24130 Marios Kogias
    net = get_network_fromdb(network_id, request.user_uniq)
160 d6b24130 Marios Kogias
161 d6b24130 Marios Kogias
    #needs discussion
162 d6b24130 Marios Kogias
    if net.deleted:
163 d6b24130 Marios Kogias
        raise api.faults.BadRequest("Network has been deleted.")
164 d6b24130 Marios Kogias
    else:
165 d6b24130 Marios Kogias
        netdict = network_to_dict(net)
166 d6b24130 Marios Kogias
        return render_network(request, netdict)
167 d6b24130 Marios Kogias
168 d6e16760 Marios Kogias
169 d6b24130 Marios Kogias
@api.api_method(http_method='DELETE', user_required=True, logger=log)
170 d6b24130 Marios Kogias
@transaction.commit_on_success
171 d6e16760 Marios Kogias
def delete_network(request, network_id):
172 d6b24130 Marios Kogias
    log.info('delete_network %s', network_id)
173 d6b24130 Marios Kogias
    net = get_network_fromdb(network_id, request.user_uniq, for_update=True)
174 d6b24130 Marios Kogias
175 d6b24130 Marios Kogias
    log.info(net.name)
176 d6b24130 Marios Kogias
    if net.public:
177 d6b24130 Marios Kogias
        raise api.faults.Forbidden('Can not delete the public network.')
178 d6b24130 Marios Kogias
179 d6b24130 Marios Kogias
    if net.deleted:
180 d6b24130 Marios Kogias
        raise api.faults.BadRequest("Network has been deleted.")
181 d6b24130 Marios Kogias
182 d6b24130 Marios Kogias
    if net.machines.all():  # Nics attached on network
183 d6e16760 Marios Kogias
        #raise api.faults.NetworkInUse('Machines are connected to network.')
184 d6e16760 Marios Kogias
        return HttpResponse("Network in use", status=409)
185 d6b24130 Marios Kogias
186 d6b24130 Marios Kogias
    net.action = 'DESTROY'
187 d6b24130 Marios Kogias
    net.save()
188 d6b24130 Marios Kogias
    '''
189 d6b24130 Marios Kogias
    skip the backend part...
190 d6b24130 Marios Kogias
    backend_networks = net.backend_networks.exclude(operstate="DELETED")
191 d6b24130 Marios Kogias
    for bnet in backend_networks:
192 d6b24130 Marios Kogias
        backend.delete_network(net, bnet.backend)
193 d6b24130 Marios Kogias
    if not backend_networks:
194 d6b24130 Marios Kogias
        backend.update_network_state(net)
195 d6b24130 Marios Kogias
    '''
196 d6b24130 Marios Kogias
197 d6b24130 Marios Kogias
    #the following has to leave when fix the backend thing
198 d6b24130 Marios Kogias
    net.deleted = True
199 d6b24130 Marios Kogias
    net.save()
200 d6b24130 Marios Kogias
201 d6b24130 Marios Kogias
    return HttpResponse(status=204)
202 d6b24130 Marios Kogias
203 d6b24130 Marios Kogias
204 d6b24130 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
205 d6e16760 Marios Kogias
def update_network(request, network_id):
206 d6b24130 Marios Kogias
    '''
207 d6b24130 Marios Kogias
    You can update only name and admin_state_up
208 d6b24130 Marios Kogias
    '''
209 d6b24130 Marios Kogias
    net = get_network_fromdb(network_id, request.user_uniq, for_update=True)
210 d6b24130 Marios Kogias
    info = utils.get_request_dict(request)
211 d6b24130 Marios Kogias
212 d6e16760 Marios Kogias
    updatable = set(["name", "admin_state_up"])
213 d6b24130 Marios Kogias
    try:
214 d6e16760 Marios Kogias
        new_vals = info["network"]
215 d6b24130 Marios Kogias
    except Keyerror:
216 d6b24130 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
217 d6b24130 Marios Kogias
218 d6e16760 Marios Kogias
    for key, val in new_vals.iteritems():
219 d6b24130 Marios Kogias
        if key in updatable:
220 d6e16760 Marios Kogias
            setattr(net, key, val)
221 d6b24130 Marios Kogias
        else:
222 d6b24130 Marios Kogias
            raise api.faults.BadRequest("Wrong field update")
223 d6e16760 Marios Kogias
    net.save()
224 d6b24130 Marios Kogias
    netdict = network_to_dict(net)
225 d6b24130 Marios Kogias
    return render_network(request, netdict, 200)
226 d6b24130 Marios Kogias
227 d6e16760 Marios Kogias
228 d6b24130 Marios Kogias
def network_to_dict(network):
229 d6b24130 Marios Kogias
    d = {'id': str(network.id), 'name': network.name}
230 d6b24130 Marios Kogias
    d['links'] = util.network_to_links(network.id)
231 d6b24130 Marios Kogias
    d['user_id'] = network.userid
232 d6b24130 Marios Kogias
    d['tenant_id'] = network.userid
233 d6b24130 Marios Kogias
    d['type'] = network.flavor
234 d6b24130 Marios Kogias
    d['updated'] = utils.isoformat(network.updated)
235 d6b24130 Marios Kogias
    d['created'] = utils.isoformat(network.created)
236 d6b24130 Marios Kogias
    d['status'] = network.state
237 d6b24130 Marios Kogias
    d['public'] = network.public
238 d6b24130 Marios Kogias
    d['admin_state_up'] = "true"
239 0dae1b9f Dionysis Grigoropoulos
    subnet_cidr = [s.id for s in network.subnet_set.all()]
240 d6b24130 Marios Kogias
    d['subnets'] = subnet_cidr
241 d6b24130 Marios Kogias
    return d
242 d6b24130 Marios Kogias
243 d6b24130 Marios Kogias
244 d6b24130 Marios Kogias
def render_network(request, networkdict, status=200):
245 d6b24130 Marios Kogias
    if request.serialization == 'xml':
246 d6b24130 Marios Kogias
        data = render_to_string('network.xml', {'network': networkdict})
247 d6b24130 Marios Kogias
    else:
248 d6b24130 Marios Kogias
        data = json.dumps({'network': networkdict})
249 d6b24130 Marios Kogias
    return HttpResponse(data, status=status)
250 d6b24130 Marios Kogias
251 d6b24130 Marios Kogias
252 d6b24130 Marios Kogias
def get_network_fromdb(network_id, user_id, for_update=False):
253 d6b24130 Marios Kogias
    """
254 d6b24130 Marios Kogias
    Return a Network instance or raise ItemNotFound.
255 d6b24130 Marios Kogias
    This is the same as util.get_network
256 d6b24130 Marios Kogias
    """
257 d6b24130 Marios Kogias
    try:
258 d6b24130 Marios Kogias
        network_id = int(network_id)
259 d6b24130 Marios Kogias
        objects = Network.objects
260 d6b24130 Marios Kogias
        if for_update:
261 d6b24130 Marios Kogias
            objects = objects.select_for_update()
262 d6b24130 Marios Kogias
        return objects.get(Q(userid=user_id) | Q(public=True), id=network_id)
263 d6b24130 Marios Kogias
    except (ValueError, Network.DoesNotExist):
264 d6b24130 Marios Kogias
        raise api.faults.ItemNotFound('Network not found.')