Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / api / quotas.py @ a4398c8c

History | View | Annotate | Download (7.3 kB)

1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from django.utils import simplejson as json
35
from django.views.decorators.csrf import csrf_exempt
36
from django.http import HttpResponse
37

    
38
from synnefo.lib.db.transaction import commit_on_success_strict
39
from astakos.api.util import json_response
40
from astakos.im.api import api_method as generic_api_method
41
from astakos.im.api.user import api_method as user_api_method
42
from astakos.im.api.service import api_method as service_api_method
43
from astakos.im.api.faults import BadRequest, InternalServerError
44
from astakos.im.quotas import get_user_quotas, get_resources
45

    
46
import astakos.quotaholder.exception as qh_exception
47
from astakos.quotaholder.callpoint import QuotaholderDjangoDBCallpoint
48
qh = QuotaholderDjangoDBCallpoint()
49

    
50

    
51
@user_api_method(http_method='GET', token_required=True)
52
def quotas(request, user=None):
53
    result = get_user_quotas(user)
54
    return json_response(result)
55

    
56

    
57
@generic_api_method(http_method='GET')
58
def resources(request):
59
    result = get_resources()
60
    return json_response(result)
61

    
62

    
63
@csrf_exempt
64
def commissions(request):
65
    method = request.method
66
    if method == 'GET':
67
        return get_pending_commissions(request)
68
    elif method == 'POST':
69
        return issue_commission(request)
70
    else:
71
        raise BadRequest('Method not allowed.')
72

    
73

    
74
@service_api_method(http_method='GET', token_required=True)
75
def get_pending_commissions(request):
76
    data = request.GET
77
    client_key = str(request.service_instance)
78

    
79
    result = qh.get_pending_commissions(clientkey=client_key)
80
    return json_response(result)
81

    
82

    
83
@csrf_exempt
84
@service_api_method(http_method='POST', token_required=True)
85
def issue_commission(request):
86
    data = request.raw_post_data
87
    input_data = json.loads(data)
88

    
89
    client_key = str(request.service_instance)
90
    provisions = input_data['provisions']
91
    force = input_data.get('force', False)
92
    auto_accept = input_data.get('auto_accept', False)
93

    
94
    try:
95
        result = _issue_commission(clientkey=client_key,
96
                                   provisions=provisions,
97
                                   force=force,
98
                                   accept=auto_accept)
99
        data = {"serial": result}
100
        status_code = 201
101
    except (qh_exception.NoCapacityError,
102
            qh_exception.NoQuantityError) as e:
103
        status_code = 413
104
        body = {"message": e.message,
105
                "code": status_code,
106
                "data": e.data,
107
                }
108
        data = {"overLimit": body}
109
    except qh_exception.NoHoldingError as e:
110
        status_code = 404
111
        body = {"message": e.message,
112
                "code": status_code,
113
                "data": e.data,
114
                }
115
        data = {"itemNotFound": body}
116
    except qh_exception.InvalidDataError as e:
117
        status_code = 400
118
        body = {"message": e.message,
119
                "code": status_code,
120
                }
121
        data = {"badRequest": body}
122

    
123
    return json_response(data, status_code=status_code)
124

    
125

    
126
@commit_on_success_strict()
127
def _issue_commission(clientkey, provisions, force, accept):
128
    serial = qh.issue_commission(clientkey=clientkey,
129
                                 provisions=provisions,
130
                                 force=force)
131
    if accept:
132
        done = qh.accept_commission(clientkey=clientkey,
133
                                    serial=serial)
134

    
135
    return serial
136

    
137

    
138
def failed_to_cloudfault(failed):
139
    serial, reason = failed
140
    if reason == 'NOTFOUND':
141
        body = {"code": 404,
142
                "message": "serial %s does not exist" % serial,
143
                }
144
        cloudfault = {"itemNotFound": body}
145
    elif reason == 'CONFLICT':
146
        body = {"code": 400,
147
                "message": "cannot both accept and reject serial %s" % serial,
148
                }
149
        cloudfault = {"badRequest": body}
150
    else:
151
        raise InternalServerError('Unexpected error')
152
    return (serial, cloudfault)
153

    
154

    
155
@csrf_exempt
156
@service_api_method(http_method='POST', token_required=True)
157
@commit_on_success_strict()
158
def resolve_pending_commissions(request):
159
    data = request.raw_post_data
160
    input_data = json.loads(data)
161

    
162
    client_key = str(request.service_instance)
163
    accept = input_data.get('accept', [])
164
    reject = input_data.get('reject', [])
165

    
166
    result = qh.resolve_pending_commissions(clientkey=client_key,
167
                                            accept_set=accept,
168
                                            reject_set=reject)
169
    accepted, rejected, failed = result
170
    cloudfaults = [failed_to_cloudfault(f) for f in failed]
171
    data = {'accepted': accepted,
172
            'rejected': rejected,
173
            'failed': cloudfaults
174
            }
175

    
176
    return json_response(data)
177

    
178

    
179
@service_api_method(http_method='GET', token_required=True)
180
def get_commission(request, serial):
181
    data = request.GET
182
    client_key = str(request.service_instance)
183
    serial = int(serial)
184

    
185
    try:
186
        data = qh.get_commission(clientkey=client_key,
187
                                 serial=serial)
188
        status_code = 200
189
        return json_response(data, status_code)
190
    except qh_exception.NoCommissionError as e:
191
        return HttpResponse(status=404)
192

    
193

    
194
@csrf_exempt
195
@service_api_method(http_method='POST', token_required=True)
196
@commit_on_success_strict()
197
def serial_action(request, serial):
198
    data = request.raw_post_data
199
    input_data = json.loads(data)
200
    serial = int(serial)
201

    
202
    client_key = str(request.service_instance)
203

    
204
    accept = 'accept' in input_data
205
    reject = 'reject' in input_data
206

    
207
    if accept == reject:
208
        raise BadRequest('Specify either accept or reject action.')
209

    
210
    if accept:
211
        result = qh.accept_commission(clientkey=client_key,
212
                                      serial=serial)
213
    else:
214
        result = qh.reject_commission(clientkey=client_key,
215
                                      serial=serial)
216

    
217
    response = HttpResponse()
218
    if not result:
219
        response.status_code = 404
220

    
221
    return response