SLA plugin code updated & SLA app folder cleaned
[myslice.git] / sla / slicetabsla.py
1 from __future__ import print_function
2
3 # this somehow is not used anymore - should it not be ?
4 import ast
5 from datetime import datetime
6 import pytz
7 from django.template import RequestContext
8 from django.shortcuts import render_to_response
9 from django.shortcuts import render
10 from django import forms
11 import re
12
13 from unfold.loginrequired import LoginRequiredView, FreeAccessView
14 from unfold.page import Page
15 from sla.slaclient import restclient
16 from sla.slaclient import wsag_model
17 import wsag_helper
18 from myslice.theme import ThemeView
19 # from sla import SLAPlugin
20 from django.core.urlresolvers import reverse
21 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
22
23 import slaclient.service.fed4fire.fed4fireservice as fed4fireservice
24 from django.http import HttpResponse
25
26 from myslice.settings import logger, SLA_COLLECTOR_URL
27
28
29 # class AgreementsFilter(object):
30 # def __init__(self, status=None, provider=None, consumer=None):
31 #         self.status = status
32 #         self.provider = provider
33 #         self.consumer = consumer
34 #
35 #     def __repr__(self):
36 #         return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
37 #             self.status, self.provider, self.consumer
38 #         )
39 #
40 #     @staticmethod
41 #     def _check(expectedvalue, actualvalue):
42 #         if expectedvalue is None or expectedvalue == '':
43 #             return True
44 #         else:
45 #             return actualvalue == expectedvalue
46 #
47 #     def check(self, agreement):
48 #         """Check if this agreement satisfy the filter.
49 #
50 #         The agreement must be previously annotated
51 #         """
52 #         guaranteestatus = agreement.guaranteestatus
53 #         provider = agreement.context.provider
54 #         consumer = agreement.context.consumer
55 #         return (
56 #             AgreementsFilter._check(self.status, guaranteestatus) and
57 #             AgreementsFilter._check(self.provider, provider) and
58 #             AgreementsFilter._check(self.consumer, consumer)
59 #         )
60
61
62 # class FilterForm(forms.Form):
63 #     _attrs = {'class': 'form-control'}
64 #     exclude = ()
65 #     status = forms.ChoiceField(
66 #         choices=[
67 #             ('', 'All'),
68 #             (wsag_model.AgreementStatus.StatusEnum.FULFILLED, 'Fulfilled'),
69 #             (wsag_model.AgreementStatus.StatusEnum.VIOLATED, 'Violated'),
70 #             (wsag_model.AgreementStatus.StatusEnum.NON_DETERMINED, 'Non determined')],
71 #         widget=forms.Select(attrs=_attrs),
72 #         required=False
73 #     )
74 #     provider = forms.CharField(
75 #         widget=forms.TextInput(attrs=_attrs),
76 #         required=False
77 #     )
78 #     consumer = forms.CharField(
79 #         widget=forms.TextInput(attrs=_attrs),
80 #         required=False
81 #     )
82
83
84 class SLAView(FreeAccessView, ThemeView):
85     template_name = 'slice-tab-sla.html'
86
87     def get(self, request, slicename):
88
89         page = Page(request)
90
91         # logger.debug("SLA slice name: {}".format(slicename))
92
93         # consumer_id = None
94         agreement_id = None
95         enforcements = {}
96         violations = {}
97         keys = ['provider', 'agreement',
98                 'date', 'status', 'result',
99                 'ok', 'slivers']
100         ag_info = []
101
102         # filter_ = None
103         # form = FilterForm(request.GET)
104         # if form.is_valid():
105         #     filter_ = _get_filter_from_form(form)
106
107         # consumer_id = _get_consumer_id(request)
108
109         # agreements = _get_agreements(agreement_id, consumer_id=consumer_id, filter_=filter_)
110         agreements = _get_agreements_by_slice(slicename)
111
112         for agreement in agreements:
113             row = []
114             provider = agreement.context.provider
115             row.append(provider)  # Provider
116             row.append(agreement)  # Agreement
117             row.append(agreement.context.time_formatted())  # Date
118
119             enf = _get_enforcement(agreement.agreement_id, provider)
120             logger.debug("SLA AAAAA: {}".format(agreement.guaranteestatus))
121
122             if enf.enabled == 'true':
123                 row.append('Evaluating')  # Status
124                 row.append('')  # Result
125                 row.append('')  # Ok
126             else:
127                 if agreement.guaranteestatus == "NON_DETERMINED":
128                     row.append('Provisioned')  # Status
129                     row.append('')  # Result
130                     row.append('')  # Ok
131
132                 else:
133                     row.append('Finished')  # Status
134
135                     violations_list = _get_agreement_violations(agreement.agreement_id, provider, "GT_Performance")
136
137                     if len(violations_list) > 0:
138                         value = '%.2f' % float(violations_list[0].actual_value)
139                         row.append('%d' % (float(value) * 100))  # Result
140                     else:
141                         row.append('100')  # Result
142
143                     if agreement.guaranteestatus == "VIOLATED":
144                         row.append('false')  # Ok
145
146                     if agreement.guaranteestatus == "FULFILLED":
147                         row.append('true')  # Ok
148
149             for _, terms in agreement.guaranteeterms.items():
150                 try:
151                     s = ast.literal_eval(terms.scopes[0].scope.lstrip())
152                     logger.debug('SLA scope: {}'.format(s))
153                     row.append(s)
154                     break
155                 except Exception as e:
156                     logger.debug("SLA EXCEPTION: {}".format(e.message))
157
158             ag_info.append(dict(zip(keys, row)))
159
160         template_env = {}
161         # write something of our own instead
162         # more general variables expected in the template
163         template_env['title'] = 'SLA Agreements'
164         template_env['agreements'] = agreements
165         template_env['username'] = request.user
166         template_env['slicename'] = slicename
167         template_env['enforcements'] = enforcements
168         template_env['last_violation_list'] = violations
169         template_env['ag_info'] = ag_info
170
171         # the prelude object in page contains a summary of the requirements() for all plugins
172         # define {js,css}_{files,chunks}
173         prelude_env = page.prelude_env()
174         template_env.update(prelude_env)
175
176         return render_to_response(self.template_name, template_env, context_instance=RequestContext(request))
177
178
179 # class AgreementsFilter(object):
180 #     def __init__(self, status=None, provider=None, consumer=None):
181 #         self.status = status
182 #         self.provider = provider
183 #         self.consumer = consumer
184 #
185 #     def __repr__(self):
186 #         return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
187 #             self.status, self.provider, self.consumer
188 #         )
189 #
190 #     @staticmethod
191 #     def _check(expectedvalue, actualvalue):
192 #         if expectedvalue is None or expectedvalue == '':
193 #             return True
194 #         else:
195 #             return actualvalue == expectedvalue
196 #
197 #     def check(self, agreement):
198 #         """Check if this agreement satisfy the filter.
199 #
200 #         The agreement must be previously annotated
201 #         """
202 #         guaranteestatus = agreement.guaranteestatus
203 #         provider = agreement.context.provider
204 #         consumer = agreement.context.consumer
205 #         return (
206 #             AgreementsFilter._check(self.status, guaranteestatus) and
207 #             AgreementsFilter._check(self.provider, provider) and
208 #             AgreementsFilter._check(self.consumer, consumer)
209 #         )
210
211
212 # class ContactForm(forms.Form):
213 #     subject = forms.CharField(max_length=100)
214 #     message = forms.CharField()
215 #     sender = forms.EmailField()
216 #     cc_myself = forms.BooleanField(required=False)
217
218
219 def _get_agreements_client():
220     return restclient.Factory.agreements()
221
222
223 def _get_violations_client():
224     return restclient.Factory.violations()
225
226
227 def _get_enforcements_client():
228     return restclient.Factory.enforcements()
229
230
231 def _get_consumer_id(request):
232     return request.user
233
234
235 def _get_agreement(agreement_id):
236     agreements_client = _get_agreements_client()
237     agreement, response = agreements_client.getbyid(agreement_id)
238     return agreement
239
240
241 def _get_enforcement(agreement_id, testbed):
242     enforcements_client = _get_enforcements_client()
243     enforcement, response = enforcements_client.getbyagreement(agreement_id, testbed)
244     return enforcement
245
246
247 # def _get_filter_from_form(form):
248 #
249 #     data = form.cleaned_data
250 #     result = AgreementsFilter(
251 #         data["status"], data["provider"], data["consumer"])
252 #     return result
253
254 def agreement_term_violations(request, agreement_id, guarantee_name):
255     page = Page(request)
256     prelude_env = page.prelude_env()
257
258     annotator = wsag_helper.AgreementAnnotator()
259     agreement = _get_agreement(agreement_id)
260     violations = _get_agreement_violations(agreement_id, guarantee_name)
261     annotator.annotate_agreement(agreement)
262
263     slicename = request.POST.get('slicename')
264
265     paginator = Paginator(violations, 25)  # Show 25 violations per page
266     page_num = request.GET.get('page')
267
268     try:
269         violation_page = paginator.page(page_num)
270     except PageNotAnInteger:
271         # If page is not an integer, deliver first page.
272         violation_page = paginator.page(1)
273     except EmptyPage:
274         # If page is out of range (e.g. 9999), deliver first page.
275         violation_page = paginator.page(1)
276
277     context = {
278         'agreement_id': agreement_id,
279         'guarantee_term': agreement.guaranteeterms[guarantee_name],
280         'violations': violation_page,
281         'agreement': agreement,
282         'slicename': slicename,
283         'last_violation': violations[-1].actual_value
284     }
285
286     context.update(prelude_env)
287
288     return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
289
290
291 #     return render(request, 'violations_template.html', context)
292
293
294 # TODO Change function to class
295 def agreement_details(request, agreement_id):
296     page = Page(request)
297     prelude_env = page.prelude_env()
298
299     annotator = wsag_helper.AgreementAnnotator()
300     agreement = _get_agreement(agreement_id)
301     violations = _get_agreement_violations(agreement_id)
302     status = _get_agreement_status(agreement_id)
303     annotator.annotate_agreement(agreement, status, violations)
304
305     violations_by_date = wsag_helper.get_violations_bydate(violations)
306     context = {
307         'agreement_id': agreement_id,
308         'agreement': agreement,
309         'status': status,
310         'violations_by_date': violations_by_date
311     }
312
313     context.update(prelude_env)
314
315     return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
316     #return render(request, 'agreement_detail.html', context)
317
318
319 # def _get_agreements(agreement_id, slice=None, provider_id=None, consumer_id=None, filter_=None):
320 #
321 #     agreements_client = _get_agreements_client()
322 #     if agreement_id is None:
323 #         if consumer_id is not None:
324 #             agreements, response = agreements_client.getbyconsumer(consumer_id)
325 #         elif provider_id is not None:
326 #             agreements, response = agreements_client.getbyprovider(provider_id)
327 #         elif slice is not None:
328 #             agreements_client = _get_agreements_client("slice")
329 #             agreements, response = agreements_client.getbyslice(slice)
330 #         else:
331 #             raise ValueError(
332 #                 "Invalid values: consumer_id and provider_id are None")
333 #     else:
334 #         agreement, response = agreements_client.getbyid(agreement_id)
335 #         agreements = [agreement]
336 #
337 #     annotator = wsag_helper.AgreementAnnotator()
338 #     for agreement in agreements:
339 #         id_ = agreement.agreement_id
340 #         testbed = agreement.context.provider
341 #         status = _get_agreement_status(id_, testbed)
342 #         annotator.annotate_agreement(agreement, status)
343 #
344 #     if filter_ is not None:
345 #         print "FILTERING ", repr(filter_)
346 #         agreements = filter(filter_.check, agreements)
347 #     else:
348 #         print "NOT FILTERING"
349 #     return agreements
350
351 def _get_agreements_by_slice(slice):
352     agreements_client = _get_agreements_client()
353     agreements, response = agreements_client.getbyslice(slice)
354
355     annotator = wsag_helper.AgreementAnnotator()
356     for agreement in agreements:
357         id_ = agreement.agreement_id
358         testbed = agreement.context.provider
359         status = _get_agreement_status(id_, testbed)
360         annotator.annotate_agreement(agreement, status)
361
362     return agreements
363
364
365 # def _get_agreements_by_consumer(consumer_id):
366 #
367 #     agreements_client = _get_agreements_client()
368 #     agreements, response = agreements_client.getbyconsumer(consumer_id)
369 #     return agreements
370
371 def _get_agreement_status(agreement_id, testbed):
372     agreements_client = _get_agreements_client()
373     status, response = agreements_client.getstatus(agreement_id, testbed)
374     return status
375
376
377 def _get_agreement_violations(agreement_id, testbed, term=None):
378     violations_client = _get_violations_client()
379     violations, response = violations_client.getbyagreement(agreement_id, testbed, term)
380     return violations
381
382
383 class Testbeds(FreeAccessView, ThemeView):
384     def get(self, request, *args, **kwargs):
385         c = restclient.Client(SLA_COLLECTOR_URL)
386         #url = settings.SLA_MANAGER_URL.replace("/sla","")
387         #c = restclient.Client(url)
388         # print "**** URL ******", url
389         SLAtestbeds = c.get("testbeds/")
390         # Future work: get SLA description for each testbed
391
392         return HttpResponse(SLAtestbeds.text, content_type="application/json", status=SLAtestbeds.status_code)
393
394
395 class CreateAgreement(LoginRequiredView, ThemeView):
396     def post(self, request, *args, **kwargs):
397
398         c = restclient.Client(SLA_COLLECTOR_URL)
399         data = request.POST.copy()
400
401         testbed_urn_regex = r"\+(.*?)\+"
402         pattern = re.compile(testbed_urn_regex)
403         testbed_urn = pattern.search(data["SLIVER_INFO_AGGREGATE_URN"]).group(1)
404
405         tstmp = data["SLIVER_INFO_EXPIRATION"]
406
407         dt = datetime.fromtimestamp(float(tstmp))
408         gmt_2 = pytz.timezone("Etc/GMT-2") # FIXME: hardcoded for demo purposes
409         dlocal = gmt_2.localize(dt).isoformat()
410
411         data["SLIVER_INFO_EXPIRATION"] = dlocal
412
413         logger.debug("SLA Agreement parameters: {}".format(data))
414
415         try:
416             response = c.post("agreements/create/", data=data, testbed=testbed_urn)
417         except Exception as e:
418             import traceback, sys
419
420             traceback.print_exc(file=sys.stdout)
421             logger.debug("SLA ERROR {}".format(e.message))
422
423         return HttpResponse(response.text, status=response.status_code)