Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / neutron / port_views.py @ 633f6952

History | View | Annotate | Download (5.4 kB)

1
from django.http import HttpResponse
2
from django.utils import simplejson as json
3
from django.db import transaction
4
from django.db.models import Q
5
from synnefo.db.pools import EmptyPool
6
from synnefo.db.utils import validate_mac
7
from django.conf import settings
8
from snf_django.lib import api
9
from snf_django.lib.api import utils
10
from synnefo.logic import backend
11
from django.template.loader import render_to_string
12
from synnefo.api import util
13
from models import NetworkInterface, SecurityGroup
14

    
15
from logging import getLogger
16

    
17
log = getLogger(__name__)
18

    
19

    
20
def demux(request):
21
    if request.method == 'GET':
22
        #return HttpResponse("list ports")
23
        return list_ports(request)
24
    elif request.method == 'POST':
25
        #return create_port(request)
26
        return HttpResponse("create port")
27
    else:
28
        return api.api_method_not_allowed(request)
29

    
30

    
31
def port_demux(request, offset):
32

    
33
    if request.method == 'GET':
34
        #return HttpResponse("get single port")
35
        return get_port(request,offset)
36
    elif request.method == 'DELETE':
37
        #return HttpResponse("delete port")
38
        return delete_port(request,offset)
39
    elif request.method == 'PUT':
40
        #return HttpResponse("put port")
41
        return update_port(request,offset)
42
    else:
43
        return api.api_method_not_allowed(request)
44

    
45

    
46
@api.api_method(http_method='GET', user_required=True, logger=log)
47
def list_ports(request, detail=False):
48

    
49
    log.debug('list_ports detail=%s', detail)
50

    
51
    user_ports = NetworkInterface.objects.filter(network__userid=request.user_uniq)
52

    
53
    user_ports = utils.filter_modified_since(request, objects=user_ports)
54

    
55
    ports = [port_to_dict(network, detail)
56
        for port in user_ports.order_by('id')]
57

    
58
    if request.serialization == 'xml':
59
        data = render_to_string('list_networks.xml', {
60
            "ports": ports})
61
    else:
62
        data = json.dumps({'ports': ports})
63

    
64
    return HttpResponse(data, status=200)
65

    
66

    
67
@api.api_method(http_method='GET', user_required=True, logger=log)
68
def get_port(request, port_id):
69
    log.debug('get_port_details %s', port_id)
70
    port = get_port_fromdb(port_id, request.user_uniq)
71

    
72
    #needs discussion
73
    if port.deleted:
74
        raise api.faults.BadRequest("Port has been deleted.")
75
    else:
76
        portdict = port_to_dict(port)
77
    return render_port(request, portdict)
78

    
79

    
80

    
81
@api.api_method(http_method='DELETE', user_required=True, logger=log)
82
@transaction.commit_on_success
83
def delete_port(request, port_id):
84
    log.info('delete_port %s', port_id)
85
    port = get_port_fromdb(port_id, request.user_uniq, for_update=True)
86

    
87

    
88
    if port.deleted:
89
        raise api.faults.BadRequest("Network has been deleted.")
90

    
91

    
92
    '''
93
    skip the backend part...
94
    release the ips associated with the port
95
    '''
96

    
97
    #the following has to leave when fix the backend thing
98
    port.deleted = True
99
    port.save()
100

    
101
    return HttpResponse(status=204)
102

    
103

    
104
@api.api_method(http_method='PUT', user_required=True, logger=log)
105
def update_port(request, port_id):
106
    '''
107
    You can update only name, admin_state_up, security_groups
108
    '''
109
    port = get_port_fromdb(port_id, request.user_uniq, for_update=True)
110
    info = utils.get_request_dict(request)
111
    try:
112
        info = info["port"]
113
    except KeyError:
114
        raise api.faults.BadRequest("Malformed request")
115

    
116
    try:
117
        name = info['name']
118
        port.name = name
119
    except KeyError:
120
        pass
121
    sg_list = []
122
    try:
123
        s_groups = info['security_groups']
124
        #validate security groups
125
        # like get security group from db
126
        for gid in s_groups:
127
            try:
128
                sg = SecurityGroup.objects.get(id=int(gid))
129
                sg_list.append(sg)
130
            except (ValueError, SecurityGroup.DoesNotExist):
131
                raise api.faults.ItemNotFound("Not valid security group")
132

    
133
        #clear the old security groups
134
        port.security_groups.clear()
135

    
136
        #add the new groups
137
        for group in sg_list:
138
            port.security_groups.add(group)
139
    except KeyError:
140
        pass
141

    
142
    port.save()
143
    portdict = port_to_dict(port)
144
    return render_port(request, portdict, 200)
145

    
146

    
147

    
148
#util functions
149

    
150

    
151
def port_to_dict(port, detail=True):
152
    d = {'id': str(port.id), 'name': port.name}
153
    if detail:
154
        d['user_id'] = port.network.userid
155
        d['tenant_id'] = port.network.userid
156
        d['device_id'] = port.machine.id
157
        d['admin_state_up'] = "true"
158
        d['mac_address'] = port.mac
159
        d['status'] = port.state
160
        if port.subnet:
161
            d['fixed_ips'] = [{"ip_address" :port.ipv4, "subnet" :port.subnet.id}]
162
        else:
163
            d['fixed_ips'] = []
164
        d['security_groups'] = [str(sg.id) for sg in port.security_groups.all()]
165
    return d
166

    
167

    
168

    
169
def render_port(request, portdict, status=200):
170
    if request.serialization == 'xml':
171
        data = render_to_string('network.xml', {'port': portdict})
172
    else:
173
        data = json.dumps({'port': portdict})
174
    return HttpResponse(data, status=status)
175

    
176
def get_port_fromdb(port_id, user_id, for_update=False):
177
    """
178
    Return a NetworkInteface instance or raise ItemNotFound.
179
    This is the same as util.get_network
180
    """
181
    try:
182
        port_id = int(port_id)
183
        objects = NetworkInterface.objects
184
        if for_update:
185
            objects = objects.select_for_update()
186

    
187
        return objects.get(network__userid=user_id, id=port_id)
188
    except (ValueError, NetworkInterface.DoesNotExist):
189
        raise api.faults.ItemNotFound('Port not found.')