Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (8.4 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 d6b24130 Marios Kogias
def demux(request):
23 d6b24130 Marios Kogias
    if request.method == 'GET':
24 d6b24130 Marios Kogias
        #return HttpResponse("in network get")
25 d6b24130 Marios Kogias
        return list_networks(request)
26 d6b24130 Marios Kogias
    elif request.method == 'POST':
27 d6b24130 Marios Kogias
        #return create_network(request)
28 d6b24130 Marios Kogias
        return HttpResponse("in network post")
29 d6b24130 Marios Kogias
    else:
30 d6b24130 Marios Kogias
        return api.api_method_not_allowed(request)
31 d6b24130 Marios Kogias
32 d6b24130 Marios Kogias
def network_demux(request,offset):
33 d6b24130 Marios Kogias
34 d6b24130 Marios Kogias
    if request.method == 'GET':
35 d6b24130 Marios Kogias
        return get_network(request,offset)
36 d6b24130 Marios Kogias
        #return HttpResponse("in network det get")
37 d6b24130 Marios Kogias
    elif request.method == 'DELETE':
38 d6b24130 Marios Kogias
        return delete_network(request,offset)
39 d6b24130 Marios Kogias
        #return HttpResponse("in network det delete")
40 d6b24130 Marios Kogias
    elif request.method == 'PUT':
41 d6b24130 Marios Kogias
        #return update_network(request,offset)
42 d6b24130 Marios Kogias
        return HttpResponse("in network det put")
43 d6b24130 Marios Kogias
    else:
44 d6b24130 Marios Kogias
        return api.api_method_not_allowed(request)
45 d6b24130 Marios Kogias
46 d6b24130 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
47 d6b24130 Marios Kogias
def list_networks(request):
48 d6b24130 Marios Kogias
    log.debug('list_networks')
49 d6b24130 Marios Kogias
50 d6b24130 Marios Kogias
    user_networks = Network.objects.filter(Q(userid=request.user_uniq) |
51 d6b24130 Marios Kogias
            Q(public=True))
52 d6b24130 Marios Kogias
53 d6b24130 Marios Kogias
    user_networks = user_networks.filter(deleted=False)
54 d6b24130 Marios Kogias
55 d6b24130 Marios Kogias
    networks = [network_to_dict(network)
56 d6b24130 Marios Kogias
                for network in user_networks.order_by('id')]
57 d6b24130 Marios Kogias
58 d6b24130 Marios Kogias
    if request.serialization == 'xml':
59 d6b24130 Marios Kogias
        data = render_to_string('list_networks.xml', {
60 d6b24130 Marios Kogias
            'networks': networks })
61 d6b24130 Marios Kogias
    else:
62 d6b24130 Marios Kogias
        data = json.dumps({'networks': networks})
63 d6b24130 Marios Kogias
64 d6b24130 Marios Kogias
    return HttpResponse(data, status=200)
65 d6b24130 Marios Kogias
66 d6b24130 Marios Kogias
@api.api_method(http_method='POST', user_required=True, logger=log)
67 d6b24130 Marios Kogias
@transaction.commit_manually
68 d6b24130 Marios Kogias
def create_network (request):
69 d6b24130 Marios Kogias
    '''
70 d6b24130 Marios Kogias
    This operation does not require a rest body. If specified, the body might
71 d6b24130 Marios Kogias
    include one or more of the following attributes:
72 d6b24130 Marios Kogias

73 d6b24130 Marios Kogias
    name: a string specifying a symbolic name for the network, which is not
74 d6b24130 Marios Kogias
        required to be unique;
75 d6b24130 Marios Kogias

76 d6b24130 Marios Kogias
    admin_state_up: a bool value specifying the administrative status of the network;
77 d6b24130 Marios Kogias

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