SLA plugin: fixed template shown in dialog
[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 json
7 import pytz
8 from django.template import RequestContext
9 from django.shortcuts import render_to_response
10 from django.shortcuts import render
11 from django import forms
12 import re
13
14 from unfold.loginrequired import LoginRequiredView, FreeAccessView
15 from unfold.page import Page
16 from sla.slaclient import restclient
17 from sla.slaclient import wsag_model
18 import wsag_helper
19 from myslice.theme import ThemeView
20 # from sla import SLAPlugin
21 from django.core.urlresolvers import reverse
22 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
23
24 import slaclient.service.fed4fire.fed4fireservice as fed4fireservice
25 from django.http import HttpResponse
26
27 from myslice.settings import logger, SLA_COLLECTOR_URL
28
29 class SLAView(FreeAccessView, ThemeView):
30     template_name = 'slice-tab-sla.html'
31
32     def get(self, request, slicename):
33
34         page = Page(request)
35
36         agreement_id = None
37         enforcements = {}
38         violations = {}
39         keys = ['provider', 'agreement',
40                 'date', 'status', 'result',
41                 'ok', 'slivers']
42         ag_info = []
43
44         agreements = _get_agreements_by_slice(slicename)
45
46         for agreement in agreements:
47             row = []
48             provider = agreement.context.provider
49             row.append(provider)  # Provider
50             row.append(agreement)  # Agreement
51             row.append(agreement.context.time_formatted())  # Date
52
53             enf = _get_enforcement(agreement.agreement_id, provider)
54
55             if enf.enabled == 'true':
56                 row.append('Evaluating')  # Status
57                 row.append('')  # Result
58                 row.append('')  # Ok
59             else:
60                 if agreement.guaranteestatus == "NON_DETERMINED":
61                     row.append('Provisioned')  # Status
62                     row.append('')  # Result
63                     row.append('')  # Ok
64
65                 else:
66                     row.append('Finished')  # Status
67
68                     violations_list = _get_agreement_violations(agreement.agreement_id, provider, "GT_Performance")
69
70                     if len(violations_list) > 0:
71                         value = '%.2f' % float(violations_list[0].actual_value)
72                         row.append('%d' % (float(value) * 100))  # Result
73                     else:
74                         row.append('100')  # Result
75
76                     if agreement.guaranteestatus == "VIOLATED":
77                         row.append('false')  # Ok
78
79                     if agreement.guaranteestatus == "FULFILLED":
80                         row.append('true')  # Ok
81
82             for _, terms in agreement.guaranteeterms.items():
83                 try:
84                     s = ast.literal_eval(terms.scopes[0].scope.lstrip())
85                     logger.debug('SLA scope: {}'.format(s))
86                     row.append(s)
87                     break
88                 except Exception as e:
89                     logger.debug("SLA EXCEPTION: {}".format(e.message))
90
91             ag_info.append(dict(zip(keys, row)))
92
93         template_env = {}
94         # write something of our own instead
95         # more general variables expected in the template
96         template_env['title'] = 'SLA Agreements'
97         template_env['agreements'] = agreements
98         template_env['username'] = request.user
99         template_env['slicename'] = slicename
100         template_env['enforcements'] = enforcements
101         template_env['last_violation_list'] = violations
102         template_env['ag_info'] = ag_info
103
104         # the prelude object in page contains a summary of the requirements() for all plugins
105         # define {js,css}_{files,chunks}
106         prelude_env = page.prelude_env()
107         template_env.update(prelude_env)
108
109         return render_to_response(self.template_name, template_env, context_instance=RequestContext(request))
110
111
112 def _get_agreements_client():
113     return restclient.Factory.agreements()
114
115
116 def _get_violations_client():
117     return restclient.Factory.violations()
118
119
120 def _get_enforcements_client():
121     return restclient.Factory.enforcements()
122
123
124 def _get_consumer_id(request):
125     return request.user
126
127
128 def _get_agreement(agreement_id):
129     agreements_client = _get_agreements_client()
130     agreement, response = agreements_client.getbyid(agreement_id)
131     return agreement
132
133
134 def _get_enforcement(agreement_id, testbed):
135     enforcements_client = _get_enforcements_client()
136     enforcement, response = enforcements_client.getbyagreement(agreement_id, testbed)
137     return enforcement
138
139
140 def agreement_term_violations(request, agreement_id, guarantee_name):
141     page = Page(request)
142     prelude_env = page.prelude_env()
143
144     annotator = wsag_helper.AgreementAnnotator()
145     agreement = _get_agreement(agreement_id)
146     violations = _get_agreement_violations(agreement_id, guarantee_name)
147     annotator.annotate_agreement(agreement)
148
149     slicename = request.POST.get('slicename')
150
151     paginator = Paginator(violations, 25)  # Show 25 violations per page
152     page_num = request.GET.get('page')
153
154     try:
155         violation_page = paginator.page(page_num)
156     except PageNotAnInteger:
157         # If page is not an integer, deliver first page.
158         violation_page = paginator.page(1)
159     except EmptyPage:
160         # If page is out of range (e.g. 9999), deliver first page.
161         violation_page = paginator.page(1)
162
163     context = {
164         'agreement_id': agreement_id,
165         'guarantee_term': agreement.guaranteeterms[guarantee_name],
166         'violations': violation_page,
167         'agreement': agreement,
168         'slicename': slicename,
169         'last_violation': violations[-1].actual_value
170     }
171
172     context.update(prelude_env)
173
174     return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
175
176
177 # TODO Change function to class
178 def agreement_details(request, agreement_id):
179     page = Page(request)
180     prelude_env = page.prelude_env()
181
182     annotator = wsag_helper.AgreementAnnotator()
183     agreement = _get_agreement(agreement_id)
184     violations = _get_agreement_violations(agreement_id)
185     status = _get_agreement_status(agreement_id)
186     annotator.annotate_agreement(agreement, status, violations)
187
188     violations_by_date = wsag_helper.get_violations_bydate(violations)
189     context = {
190         'agreement_id': agreement_id,
191         'agreement': agreement,
192         'status': status,
193         'violations_by_date': violations_by_date
194     }
195
196     context.update(prelude_env)
197
198     return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
199     #return render(request, 'agreement_detail.html', context)
200
201
202 def _get_agreements_by_slice(slice):
203     agreements_client = _get_agreements_client()
204     agreements, response = agreements_client.getbyslice(slice)
205
206     annotator = wsag_helper.AgreementAnnotator()
207     for agreement in agreements:
208         id_ = agreement.agreement_id
209         testbed = agreement.context.provider
210         status = _get_agreement_status(id_, testbed)
211         annotator.annotate_agreement(agreement, status)
212
213     return agreements
214
215
216 def _get_agreement_status(agreement_id, testbed):
217     agreements_client = _get_agreements_client()
218     status, response = agreements_client.getstatus(agreement_id, testbed)
219     return status
220
221
222 def _get_agreement_violations(agreement_id, testbed, term=None):
223     violations_client = _get_violations_client()
224     violations, response = violations_client.getbyagreement(agreement_id, testbed, term)
225     return violations
226
227
228 class Testbeds(FreeAccessView, ThemeView):
229     def get(self, request, *args, **kwargs):
230         c = restclient.Client(SLA_COLLECTOR_URL)
231         #url = settings.SLA_MANAGER_URL.replace("/sla","")
232         #c = restclient.Client(url)
233         # print "**** URL ******", url
234         SLAtestbeds = c.get("testbeds/")
235         # Future work: get SLA description for each testbed
236
237         return HttpResponse(SLAtestbeds.text, content_type="application/json", status=SLAtestbeds.status_code)
238
239
240 class AgreementTemplates(FreeAccessView, ThemeView):
241     def get(self, request, *args, **kwargs):
242         c = restclient.Templates(SLA_COLLECTOR_URL)
243         testbed = kwargs.get('testbed', None)
244
245         #logger.debug("AAAAA testbed: {}".format(testbed))
246
247         templates, response = c.getall(testbed)
248         service_level_objectives = []
249
250         #logger.debug("BBBBB templates: {}".format(templates))
251
252         for template in templates:
253             service_level_objectives.append(
254                 [v.servicelevelobjective for v in template.guaranteeterms.values()])
255
256         logger.debug("CCCCC slo: {}".format(service_level_objectives))
257
258         return HttpResponse(service_level_objectives, content_type="application/json", status=response.status_code)
259
260 class CreateAgreement(LoginRequiredView, ThemeView):
261     def post(self, request, *args, **kwargs):
262
263         c = restclient.Client(SLA_COLLECTOR_URL)
264         data = request.POST.copy()
265
266         testbed_urn_regex = r"\+(.*?)\+"
267         pattern = re.compile(testbed_urn_regex)
268         testbed_urn = pattern.search(data["SLIVER_INFO_AGGREGATE_URN"]).group(1)
269
270         # Fix for django QueryDict list parameters
271         slivers = data.getlist("SLIVER_INFO_URN[]")
272         data["SLIVER_INFO_URN"] = slivers
273         del data["SLIVER_INFO_URN[]"]
274
275         # Timestamp to ISO date + timezone
276         tstmp = data["SLIVER_INFO_EXPIRATION"]
277         dt = datetime.fromtimestamp(float(tstmp))
278         # gmt_2 = pytz.timezone("Etc/GMT-2")
279         # dlocal = gmt_2.localize(dt).isoformat()
280         dlocal = dt.isoformat() + "CET" # FIXME: hardcoded for demo purposes
281         data["SLIVER_INFO_EXPIRATION"] = dlocal
282
283         # logger.debug("SLA Agreement parameters: {}".format(data.dict()))
284         # import pdb; pdb.set_trace()
285
286         try:
287             response = c.post("agreementslist/", data=json.dumps(data),
288                               headers={"accept": "application/json",
289                                  "content-type": "application/json"})
290         except Exception as e:
291             # import traceback, sys
292             #
293             # traceback.print_exc(file=sys.stdout)
294             logger.debug("SLA Error: CreateAgreement {}".format(e.message))
295
296         return HttpResponse(response.text, status=response.status_code)