SLA and Service Directory code added
[myslice.git] / sla / wsag_helper.py
diff --git a/sla/wsag_helper.py b/sla/wsag_helper.py
new file mode 100755 (executable)
index 0000000..2256ea9
--- /dev/null
@@ -0,0 +1,116 @@
+import re\r
+import datetime\r
+\r
+from slaclient import wsag_model\r
+from slaclient.wsag_model import AgreementStatus\r
+from slaclient.wsag_model import Violation\r
+\r
+\r
+VIOLATED = AgreementStatus.StatusEnum.VIOLATED\r
+NON_DETERMINED = AgreementStatus.StatusEnum.NON_DETERMINED\r
+FULFILLED = AgreementStatus.StatusEnum.FULFILLED\r
+\r
+\r
+def get_violations_bydate(violations):\r
+    """Returns a list of violations per date, from a list of violations\r
+\r
+    :param violations list[Violation]:\r
+    :rtype: list\r
+    """\r
+    d = dict()\r
+    for v in violations:\r
+        assert isinstance(v, Violation)\r
+        date = v.datetime.date()\r
+        if not date in d:\r
+            d[date] = []\r
+        d[date].append(v)\r
+\r
+    result = [(key, d[key]) for key in sorted(d.keys(), reverse=True)]\r
+    return result\r
+\r
+\r
+class AgreementAnnotator(object):\r
+    """Annotates an agreement with the following attributes:\r
+\r
+    agreement.guaranteestatus\r
+    agreement.statusclass\r
+    agreement.guaranteeterms[*].status\r
+    agreement.guaranteeterms[*].statusclass\r
+    agreement.guaranteeterms[*].nviolations\r
+    agreement.guaranteeterms[*].servicelevelobjetive.bounds\r
+\r
+    """\r
+    def __init__(self):\r
+        pass\r
+\r
+    @staticmethod\r
+    def _get_statusclass(status):\r
+        if status is None or status == "" or status == NON_DETERMINED:\r
+            return "non-determined"\r
+        return "success" if status == FULFILLED else "error"\r
+\r
+    @staticmethod\r
+    def _parse_bounds(servicelevel):\r
+#         pattern = re.compile(".*BETWEEN *[(]?(.*), *([^)]*)[)]?")\r
+        pattern = re.compile(".*GT *([+-]?\\d*\\.\\d+)(?![-+0-9\\.])")\r
+        constraint = eval(servicelevel.strip(' \t\n\r'))\r
+        m = pattern.match(constraint['constraint'])\r
+        return m.groups()\r
+\r
+    def _annotate_guaranteeterm(self, term, violations):\r
+        #\r
+        # Annotate a guarantee term: set bounds and violations\r
+        #\r
+        level = term.servicelevelobjective.customservicelevel\r
+        bounds = AgreementAnnotator._parse_bounds(level)\r
+        term.servicelevelobjective.bounds = bounds\r
+\r
+        #\r
+        # set status attribute if not set before\r
+        #\r
+        if not hasattr(term, 'status'):\r
+            term.status = wsag_model.AgreementStatus.StatusEnum.NON_DETERMINED\r
+        #\r
+        # TODO: efficiency\r
+        #\r
+        n = 0\r
+        for violation in violations:\r
+            if violation.metric_name == term.servicelevelobjective.kpiname:\r
+                n += 1\r
+        term.nviolations = n\r
+\r
+    def _annotate_guaranteeterm_by_status(\r
+            self, agreement, termstatus, violations):\r
+        #\r
+        # Annotate a guarantee term: it is different from the previous\r
+        # one in that this takes the status into account.\r
+        #\r
+        name = termstatus.name\r
+        status = termstatus.status\r
+\r
+        term = agreement.guaranteeterms[name]\r
+        term.status = status\r
+        term.statusclass = AgreementAnnotator._get_statusclass(status)\r
+        self._annotate_guaranteeterm(term, violations)\r
+\r
+    def annotate_agreement(self, agreement, status=None, violations=()):\r
+\r
+        """Annotate an agreement with certain values needed in the templates\r
+\r
+        :param wsag_model.Agreement agreement: agreement to annotate\r
+        :param wsag_model.AgreementStatus status: status of the agreement.\r
+        :param violations: list of agreement's violations\r
+            (wsag_model.Violation[])\r
+        """\r
+        a = agreement\r
+\r
+        if status is not None:\r
+            a.guaranteestatus = status.guaranteestatus\r
+            a.statusclass = self._get_statusclass(status.guaranteestatus)\r
+            for termstatus in status.guaranteeterms:\r
+                self._annotate_guaranteeterm_by_status(\r
+                    agreement, termstatus, violations)\r
+        else:\r
+            a.guaranteestatus = NON_DETERMINED\r
+            for termname, term in agreement.guaranteeterms.items():\r
+                self._annotate_guaranteeterm(term, violations)\r