Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
[myslice.git] / sla / wsag_helper.py
1 import re\r
2 import datetime\r
3 \r
4 from slaclient import wsag_model\r
5 from slaclient.wsag_model import AgreementStatus\r
6 from slaclient.wsag_model import Violation\r
7 \r
8 \r
9 VIOLATED = AgreementStatus.StatusEnum.VIOLATED\r
10 NON_DETERMINED = AgreementStatus.StatusEnum.NON_DETERMINED\r
11 FULFILLED = AgreementStatus.StatusEnum.FULFILLED\r
12 \r
13 \r
14 def get_violations_bydate(violations):\r
15     """Returns a list of violations per date, from a list of violations\r
16 \r
17     :param violations list[Violation]:\r
18     :rtype: list\r
19     """\r
20     d = dict()\r
21     for v in violations:\r
22         assert isinstance(v, Violation)\r
23         date = v.datetime.date()\r
24         if not date in d:\r
25             d[date] = []\r
26         d[date].append(v)\r
27 \r
28     result = [(key, d[key]) for key in sorted(d.keys(), reverse=True)]\r
29     return result\r
30 \r
31 \r
32 class AgreementAnnotator(object):\r
33     """Annotates an agreement with the following attributes:\r
34 \r
35     agreement.guaranteestatus\r
36     agreement.statusclass\r
37     agreement.guaranteeterms[*].status\r
38     agreement.guaranteeterms[*].statusclass\r
39     agreement.guaranteeterms[*].nviolations\r
40     agreement.guaranteeterms[*].servicelevelobjetive.bounds\r
41 \r
42     """\r
43     def __init__(self):\r
44         pass\r
45 \r
46     @staticmethod\r
47     def _get_statusclass(status):\r
48         if status is None or status == "" or status == NON_DETERMINED:\r
49             return "non-determined"\r
50         return "success" if status == FULFILLED else "error"\r
51 \r
52     @staticmethod\r
53     def _parse_bounds(servicelevel):\r
54 #         pattern = re.compile(".*BETWEEN *[(]?(.*), *([^)]*)[)]?")\r
55         pattern = re.compile(".*GT *([+-]?\\d*\\.\\d+)(?![-+0-9\\.])")\r
56         constraint = eval(servicelevel.strip(' \t\n\r'))\r
57         m = pattern.match(constraint['constraint'])\r
58         return m.groups()\r
59 \r
60     def _annotate_guaranteeterm(self, term, violations):\r
61         #\r
62         # Annotate a guarantee term: set bounds and violations\r
63         #\r
64         level = term.servicelevelobjective.customservicelevel\r
65         bounds = AgreementAnnotator._parse_bounds(level)\r
66         term.servicelevelobjective.bounds = bounds\r
67 \r
68         #\r
69         # set status attribute if not set before\r
70         #\r
71         if not hasattr(term, 'status'):\r
72             term.status = wsag_model.AgreementStatus.StatusEnum.NON_DETERMINED\r
73         #\r
74         # TODO: efficiency\r
75         #\r
76         n = 0\r
77         for violation in violations:\r
78             if violation.metric_name == term.servicelevelobjective.kpiname:\r
79                 n += 1\r
80         term.nviolations = n\r
81 \r
82     def _annotate_guaranteeterm_by_status(\r
83             self, agreement, termstatus, violations):\r
84         #\r
85         # Annotate a guarantee term: it is different from the previous\r
86         # one in that this takes the status into account.\r
87         #\r
88         name = termstatus.name\r
89         status = termstatus.status\r
90 \r
91         term = agreement.guaranteeterms[name]\r
92         term.status = status\r
93         term.statusclass = AgreementAnnotator._get_statusclass(status)\r
94         self._annotate_guaranteeterm(term, violations)\r
95 \r
96     def annotate_agreement(self, agreement, status=None, violations=()):\r
97 \r
98         """Annotate an agreement with certain values needed in the templates\r
99 \r
100         :param wsag_model.Agreement agreement: agreement to annotate\r
101         :param wsag_model.AgreementStatus status: status of the agreement.\r
102         :param violations: list of agreement's violations\r
103             (wsag_model.Violation[])\r
104         """\r
105         a = agreement\r
106 \r
107         if status is not None:\r
108             a.guaranteestatus = status.guaranteestatus\r
109             a.statusclass = self._get_statusclass(status.guaranteestatus)\r
110             for termstatus in status.guaranteeterms:\r
111                 self._annotate_guaranteeterm_by_status(\r
112                     agreement, termstatus, violations)\r
113         else:\r
114             a.guaranteestatus = NON_DETERMINED\r
115             for termname, term in agreement.guaranteeterms.items():\r
116                 self._annotate_guaranteeterm(term, violations)\r