}
}
-AUTHENTICATION_BACKENDS = ( 'auth.manifoldbackend.ManifoldBackend','django.contrib.auth.backends.ModelBackend' )
+AUTHENTICATION_BACKENDS = ('auth.manifoldbackend.ManifoldBackend',
+ 'django.contrib.auth.backends.ModelBackend')
### the view to redirect malformed (i.e. with a wrong CSRF) incoming requests
# without this setting django will return a 403 forbidden error, which is fine
####SLA#####
-SLA_MANAGER_URL = "http://157.193.215.125:4000/sla-service"
-SLA_MANAGER_USER = "normal_user"
-SLA_MANAGER_PASSWORD = "password"
\ No newline at end of file
+#SLA_MANAGER_URL = "http://157.193.215.125:4000/sla-service"
+# SLA_MANAGER_USER = "normal_user"
+# SLA_MANAGER_PASSWORD = "password"
+SLA_MANAGER_URL = "http://172.24.76.98:8080/sla"
+SLA_MANAGER_USER = ""
+SLA_MANAGER_PASSWORD = ""
{
flagDouble = true;
promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the WiLab2 resources during the sliver lifetime</p>');
- promt.append(wilabForm);
+ //promt.append(wilabForm);
promt.append('<br />');
}
if(flagVW)
//promt.append(wallmessage);
flagDouble = true;
promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>');
- promt.append(wallForm);
+ //promt.append(wallForm);
promt.append('<br />');
}
"user": username,
"expiration_time": new Date().toISOString()
});
-
+
$('#slamodal-wilab2').modal('hide');
accepted_sla["wilab2"] = true;
- manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
+ //manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
}
$('#modal-body').empty();
});
"""REST client to SLA Manager.
-Contains a generic rest client and wrappers over this generic client
+Contains a generic rest client and wrappers over this generic client
for each resource.
Each resource client implements business-like() functions, but
returns a tuple (output, requests.Response)
-The resource clients are initialized with the rooturl and a path, which
+The resource clients are initialized with the rooturl and a path, which
are combined to build the resource url. The path is defaulted to the known
resource path. So, for example, to create a agreements client:
"""
-_PROVIDERS_PATH = "providerso"
-_AGREEMENTS_PATH = "agreementso"
-_TEMPLATES_PATH = "templateso"
-_VIOLATIONS_PATH = "violationso"
+_PROVIDERS_PATH = "providers"
+_AGREEMENTS_PATH = "agreements"
+_TEMPLATES_PATH = "templates"
+_VIOLATIONS_PATH = "violations"
_ENFORCEMENTJOBS_PATH = "enforcements"
rooturl = settings.SLA_MANAGER_URL
-# SLA_MANAGER_USER = "normal_user"
-# SLA_MANAGER_PASSWORD = "password"
class Factory(object):
@staticmethod
def agreements():
- """Returns aREST client for Agreements
+ """Returns a REST client for Agreements
:rtype : Agreements
"""
@staticmethod
def providers():
- """Returns aREST client for Providers
+ """Returns a REST client for Providers
:rtype : Providers
"""
@staticmethod
def violations():
- """Returns aREST client for Violations
+ """Returns a REST client for Violations
:rtype : Violations
"""
@staticmethod
def templates():
- """Returns aREST client for Violations
+ """Returns a REST client for Violations
:rtype : Violations
"""
@staticmethod
def enforcements():
- """Returns aREST client for Enforcements jobs
+ """Returns a REST client for Enforcements jobs
:rtype : Enforcements
"""
return Enforcements(rooturl)
+
class Client(object):
def __init__(self, root_url):
Returns a requests.Response
:rtype : request.Response
- :param str path: remaining path from root url;
+ :param str path: remaining path from root url;
empty if desired path equal to rooturl.
:param kwargs: arguments to requests.get
-
- Example:
+
+ Example:
c = Client("http://localhost:8080/service")
c.get("/resource", headers = { "accept": "application/json" })
"""
url = _buildpath_(self.rooturl, path)
- kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER, settings.SLA_MANAGER_PASSWORD)
+ url = url + "?testbed=iminds" # TODO remove hardcoded string
+ #kwargs['params']['testbed'] = 'iminds'
+
+ if "headers" not in kwargs:
+ kwargs["headers"] = {"accept": "application/xml"}
+ # kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER,
+ # settings.SLA_MANAGER_PASSWORD)
result = requests.get(url, **kwargs)
- print "GET {} {} {}".format(
- result.url, result.status_code, result.text[0:70])
+ #print "GET {} {} {}".format(
+ # result.url, result.status_code, result.text[0:70])
return result
-
+
def post(self, path, data=None, **kwargs):
"""Just a wrapper over request.post, just in case
)
"""
url = _buildpath_(self.rooturl, path)
- kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER, settings.SLA_MANAGER_PASSWORD)
+ url = url + "?testbed=iminds" # TODO remove hardcoded string
+ # kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER,
+ # settings.SLA_MANAGER_PASSWORD)
+ if "headers" not in kwargs:
+ kwargs = {"accept": "application/xml",
+ "content-type": "application/xml"}
result = requests.post(url, data, **kwargs)
location = result.headers["location"] \
if "location" in result.headers else "<null>"
result.url, result.status_code, location)
return result
-
class _Resource(object):
content_type = r.headers.get('content-type', '')
- print("content-type = " + content_type)
+ #print("content-type = " + content_type)
if content_type == 'application/json':
result = r.json()
elif content_type == 'application/xml':
r = self.res.client.get(path, headers={'accept': 'application/json'})
json_obj = r.json()
-
+
status = wsag_model.AgreementStatus.json_decode(json_obj)
return status, r
-
+
def create(self, agreement):
"""Create a new agreement
"""
return self.res.create(agreement)
+
class Templates(object):
def __init__(self, root_url, path=_TEMPLATES_PATH):
"""
self.res.create(template)
+
class Providers(object):
def __init__(self, root_url, path=_PROVIDERS_PATH):
body = provider.to_xml()
return self.res.create(body)
+
class Violations(object):
def __init__(self, root_url, path=_VIOLATIONS_PATH):
violations from all terms will be returned
:rtype: list[wsag_model.Violation]
"""
+
return self.res.get(
{"agreementId": agreement_id, "guaranteeTerm": term})
"""Get the enforcement of an agreement.
:param str agreement_id:
-
+
:rtype: list[wsag_model.Enforcement]
"""
- return self.res.getbyid(agreement_id)
+ return self.res.getbyid(agreement_id)
def _buildpath_(*paths):
#
global rooturl
rooturl = "http://127.0.0.1:8080/sla-service"
-
c = Factory.templates()
#r = c.getall()
#r = c.getbyconsumer('RandomClient')
r = c.getbyid("template02")
-
print r
if __name__ == "__main__":
main()
-
-
It is intended as backend service for a rest interface.\r
\r
The json input must work together with the templates to form a valid template\r
- or agreement for Xifi (be careful!)\r
+ or agreement for fed4fire (be careful!)\r
\r
-This (very simple) service is coupled to the way xifi is interpreting\r
+This (very simple) service is coupled to the way fed4fire is interpreting\r
ws-agreement.\r
\r
\r
from sla.slaclient import restclient\r
from sla.slaclient.templates.fed4fire.django.factory import Factory as TemplateFactory\r
import sla.slaclient.templates.fed4fire as fed4fire\r
-from time import localtime, strftime\r
+#from time import localtime, strftime\r
import uuid\r
+import dateutil.parser\r
+\r
+\r
class ServiceContext(object):\r
- def __init__(self, restfactory = None, templatefactory=None):\r
+ def __init__(self, restfactory=None, templatefactory=None):\r
"""\r
:type restfactory: restclient.Factory\r
"""\r
\r
client_agreements = context.restfactory.agreements()\r
return client_agreements.create(slaagreement)\r
- \r
+\r
\r
def createagreementsimplified(template_id, user, expiration_time):\r
- context = ServiceContext(\r
- restclient.Factory(),\r
- TemplateFactory()\r
- )\r
- \r
- agreement = {\r
- "agreement_id": str(uuid.uuid4()),\r
- "template_id": template_id,\r
- "expiration_time": expiration_time,\r
- "consumer": user,\r
- }\r
- \r
- json_data = json.dumps(agreement)\r
-\r
- return createagreement(json_data, context)\r
- \r
+ context = ServiceContext(\r
+ restclient.Factory(),\r
+ TemplateFactory()\r
+ )\r
+\r
+ print "Expiration time: ", expiration_time\r
+\r
+ time = dateutil.parser.parse(expiration_time)\r
+ print "ISO FORMAT: ", time.strftime('%Y-%m-%dT%H:%M:%S%Z')\r
+\r
+ agreement = {\r
+ "agreement_id": str(uuid.uuid4()),\r
+ "template_id": template_id,\r
+ "expiration_time": time.strftime('%Y-%m-%dT%H:%M:%S%Z'),\r
+ "consumer": user,\r
+ }\r
+\r
+ json_data = json.dumps(agreement)\r
+\r
+ return createagreement(json_data, context)\r
+\r
+\r
def main():\r
- createagreementsimplified("iMindsServiceWiLab2", "virtualwall", "2014-04-34T23:12:12")\r
+ createagreementsimplified("iMindsServiceWiLab2",\r
+ "virtualwall",\r
+ "2014-04-34T23:12:12")\r
\r
\r
if __name__ == "__main__":\r
main()\r
- \r
- \r
}\r
"""\r
d = json.loads(json_data)\r
- if "expiration_time" in d:\r
- d["expiration_time"] = dateutil.parser.parse(d["expiration_time"])\r
\r
t = AgreementInput(\r
agreement_id=d.get("agreement_id", None),\r
# -*- coding: utf-8 -*-\r
-"""Template system for xifi project.\r
+"""Template system for fed4fire project.\r
\r
The specific template system is configured with the factory module variable.\r
\r
data = sla.slaclient.templates.fed4fire.TemplateInput(template_id="template-test")\r
slatemplate_xml = sla.slaclient.templates.fed4fire.render_slatemplate(data)\r
\r
-Notes about agreements in XiFi:\r
+Notes about agreements in fed4fire:\r
The ws-agreement specification does not address where to place the name/id\r
of the service (as known outside SLA) being defined in the\r
agreement/template xml. So, it has been defined an element\r
The guarantee terms, service description terms, etc, use the attribute\r
serviceName to reference (internally in the xml) the service. So, there\r
could be more than one serviceName in a xml (as opposed to the former\r
- serviceId). In Xifi, there is only one service per agreement, so we\r
+ serviceId). In fed4fire, there is only one service per agreement, so we\r
can give serviceId and serviceName the same value.\r
\r
A ServiceReference defines how a serviceName is known externally: a\r
(they are used to describe the service to be instantiated), so we can\r
extrapolate the location as the "abstract location of the metric".\r
\r
- In summary, in XiFi, the service properties will hold the metrics being\r
+ In summary, in fed4fire, the service properties will hold the metrics being\r
monitored for a service.\r
\r
And the guarantee terms hold the constraints that are being enforced for\r
</wsag:ServiceLevelObjective>\r
</wsag:GuaranteeTerm>\r
\r
- * Name is a name for the guarantee term. In Xifi, the name will have the\r
+ * Name is a name for the guarantee term. In fed4fire, the name will have the\r
value "GT_<metric_name>"\r
* ServiceName is an internal reference in the agreement to the service\r
being enforced, as an agreement can created for more than one service.\r
- In Xifi, to my knowledge, one service: one agreement, so this service\r
+ In fed4fire, to my knowledge, one service: one agreement, so this service\r
name is not really important.\r
* KpiName is a name given to the constraint, and I am using the same name\r
as the service property used in the constraint. This makes more sense\r
print "render_slaagreement"\r
template = _getfactory().slaagreement()\r
#pdb.set_trace()\r
- rendered = template.render(data) \r
+ rendered = template.render(data)\r
return rendered\r
\r
\r
self.template_id = template_id\r
self.expiration_time = expiration_time\r
self.expiration_time_iso = \\r
- expiration_time.isoformat() if expiration_time else None\r
+ expiration_time if expiration_time else None\r
self.service_properties = service_properties\r
self.guarantee_terms = guarantee_terms\r
\r
from datetime import datetime
+from dateutil import tz
+import dateutil.parser
"""Contains the bean models for the SlaManager xml/json types
"""
repr(self.provider),
repr(self.consumer),
repr(self.service))
-
+
def service_formatted(self):
return self.service.replace('_', ' ')
return self.template_id.replace('Service', ' - ')
def time_formatted(self):
- import dateutil.parser
+ from_zone = tz.tzutc()
+ to_zone = tz.tzlocal()
time = dateutil.parser.parse(self.expirationtime)
+ time = time.replace(tzinfo=from_zone)
+ time = time.astimezone(to_zone)
return time.strftime('%d-%m-%Y at %H:%M:%S')
class Property(object):
self.location = ""
def __repr__(self):
- str_ = "<Property(name={}, servicename={}, metric={}, location={})>"
+ str_ = "<Property(name={}, servicename={}, \
+ metric={}, location={})>"
return str_.format(
repr(self.name),
repr(self.servicename),
self.customservicelevel = ""
def __repr__(self):
- s = "<ServiceLevelObjective(kpiname={}, customservicelevel={})>"
+ s = "<ServiceLevelObjective(kpiname={}, \
+ customservicelevel={})>"
return s.format(
repr(self.kpiname),
repr(self.customservicelevel)
class Template(Agreement):
- #egarrido this code has been copied from xifi and has not beeing tested
def __init__(self):
super(Template, self).__init__()
self.template_id = ""
return ("<Enforcement(agreement_id={}, enabled={})>".format(
self.agreement_id,
self.enabled)
- )
+ )
+
class AgreementStatus(object):
return (
"<AgreementStatus( agreement_id={}, guaranteestatus={}, " +
"guaranteeterms={})>").format(
- self.agreement_id,
- self.guaranteestatus,
- repr(self.guaranteeterms))
+ self.agreement_id,
+ self.guaranteestatus,
+ repr(self.guaranteeterms))
@staticmethod
def json_decode(json_obj):
self.uuid = ""
self.contract_uuid = ""
self.service_scope = ""
+ self.service_name = ""
self.metric_name = ""
self.datetime = datetime.utcnow()
self.actual_value = 0
def __repr__(self):
- return ("<Violation(uuid={}, agremeent_id={}, service_scope={}, " +
- "metric_name={}, datetime={}, actual_value={})>".format(
+ return ("<Violation(uuid={}, datetime={}, contract_uuid={}, \
+ service_name={}, service_scope={}, metric_name={}, \
+ actual_value={})>\n".format(
self.uuid,
+ self.datetime,
self.contract_uuid,
+ self.service_name,
self.service_scope,
self.metric_name,
- self.datetime,
self.actual_value)
- )
+ )
def format_time(self):
- # return datetime.strptime(self.datetime.datetime.utcnow,'%Y-%m-%d %H:%M:%S')
# return str(datetime.fromtimestamp(self.datetime))
return str(self.datetime)
return ("<Provider(uuid={}, name={})>".format(
self.uuid,
self.name)
- )
+ )
+
def to_xml(self):
xml = "<provider><uuid>{}</uuid><name>{}</name></provider>""".format(
self.uuid,
out = wsag_model.Provider.from_dict(json_obj)
"""
result = Provider(d["uuid"], d["name"])
- return result
+ return result
The converters are designed to be pluggable: see ListConverter.
-Usage:
+Usage:
c = AnyConverter() or
c = ListConverter(AnyOtherConverter())
"""
-from xml.etree import ElementTree
-from xml.etree.ElementTree import Element
+try:
+ # Much faster and lighter library (C implementation)
+ from xml.etree import cElementTree as ElementTree
+except ImportError:
+ from xml.etree import ElementTree
+
import dateutil.parser
from wsag_model import Agreement
def convert(self, xmlroot):
result = []
- for item in xmlroot.find("items"): # loop through "items" children
+ # Converter for the old xml structure
+ # for item in xmlroot.find("items"): # loop through "items" children
+ # inner = self.innerconverter.convert(item)
+ # result.append(inner)
+ # return result
+
+ for item in xmlroot: # loop through children
inner = self.innerconverter.convert(item)
result.append(inner)
return result
result.enabled = xmlroot.find("enabled").text
return result
+
class ViolationConverter(Converter):
"""Converter for a violation.
Input:
<violation>
- <uuid>ce0e148f-dfac-4492-bb26-ad2e9a6965ec</uuid>
- <contract_uuid>agreement04</contract_uuid>
- <service_scope></service_scope>
- <metric_name>Performance</metric_name>
- <datetime>2014-01-14T11:28:22Z</datetime>
- <actual_value>0.09555700123360344</actual_value>
+ <uuid>1d94627e-c318-41ba-9c45-42c95b67cc32</uuid>
+ <contract_uuid>26e5d5b6-f5a1-4eb3-bc91-606e8f24fb09</contract_uuid>
+ <service_name>servicename1</service_name>
+ <service_scope>test1</service_scope>
+ <metric_name>UpTime</metric_name>
+ <datetime>2014-07-17T09:32:00+02:00</datetime>
+ <actual_value>0.0</actual_value>
</violation>
Output:
result = Violation()
result.uuid = xmlroot.find("uuid").text
result.contract_uuid = xmlroot.find("contract_uuid").text
+ result.service_name = xmlroot.find("service_name").text
result.service_scope = xmlroot.find("service_scope").text
result.metric_name = xmlroot.find("metric_name").text
result.actual_value = xmlroot.find("actual_value").text
dt_str = xmlroot.find("datetime").text
result.datetime = dateutil.parser.parse(dt_str)
+
return result
"""Converter for an ws-agreement agreement or template.
"""
super(AgreementConverter, self).__init__()
- self._namespaces = {
+ self._namespaces = {
"wsag": "http://www.ggf.org/namespaces/ws-agreement",
"sla": "http://sla.atos.eu",
- "xifi": "http://sla.xifi.eu"
}
self.agreement_tags = (
"{{{}}}Agreement".format(self._namespaces["wsag"]),
isns = (attrname[0] == '{')
#
- # Handle qnamed request:
+ # Handle qnamed request:
# attrname = {uri}name
#
if isns:
import json
import traceback
+from math import ceil
class Rol:
agreement_id = None
enforcements = {}
violations = {}
+ keys = ['provider','agreement','date','status','result','ok']
+ ag_info = []
filter_ = None
form = FilterForm(request.GET)
if form.is_valid():
- print "IS VALID"
- filter_ = _get_filter_from_form(form)
+ filter_ = _get_filter_from_form(form)
consumer_id = _get_consumer_id(request)
-
+
agreements = _get_agreements(agreement_id, consumer_id=consumer_id, filter_=filter_)
-
+
for agreement in agreements:
+ row = []
+ row.append(agreement.context.provider) # Provider
+ row.append(agreement) # Agreement
+ row.append(agreement.context.time_formatted()) # Date
+
enf = _get_enforcement(agreement.agreement_id)
+
if enf.enabled == 'true':
- enforcements[agreement.agreement_id] = "ACTIVE"
- else:
- enforcements[agreement.agreement_id] = "UNACTIVE"
- violations_list = _get_agreement_violations(agreement.agreement_id, "GT_Performance")
-
- if len(violations_list):
- violations[agreement.agreement_id] = float(violations_list[0]["actualValue"])*100
+ row.append('Evaluating') # Status
+ row.append('') # Result
+ row('') # Ok
else:
- violations[agreement.agreement_id] = 100
+ if agreement.guaranteestatus == "NON_DETERMINED":
+ row.append('Provisioned') # Status
+ row.append('') # Result
+ row.append('') # Ok
+
+ else:
+ row.append('Finished') # Status
+
+ violations_list = _get_agreement_violations(agreement.agreement_id, "GT_Performance")
+
+ if len(violations_list) > 0:
+ value = '%.2f'%float(violations_list[0].actual_value)
+ row.append('%d'%(float(value)*100)) # Result
+ else:
+ row.append('100') # Result
+
+ if agreement.guaranteestatus == "VIOLATED":
+ row.append('false') # Ok
+
+ if agreement.guaranteestatus == "FULFILLED":
+ row.append('true') # Ok
+
+ ag_info.append(dict(zip(keys,row)))
+
+ # enf = _get_enforcement(agreement.agreement_id)
+ # if enf.enabled == 'true':
+ # enforcements[agreement.agreement_id] = "ACTIVE"
+ # else:
+ # enforcements[agreement.agreement_id] = "UNACTIVE"
+ # violations_list = _get_agreement_violations(agreement.agreement_id, "GT_Performance")
+
+ # if len(violations_list):
+ # violations[agreement.agreement_id] = float(violations_list[0]["actualValue"])*100
+ # else:
+ # violations[agreement.agreement_id] = 100
template_env = {}
# write something of our own instead
template_env['slicename'] = slicename
template_env['enforcements'] = enforcements
template_env['last_violation_list'] = violations
-
+ template_env['ag_info'] = ag_info
+
+
# the prelude object in page contains a summary of the requirements() for all plugins
# define {js,css}_{files,chunks}
prelude_env = page.prelude_env()
template_env.update(prelude_env)
-
- return render_to_response (self.template_name, template_env, context_instance=RequestContext(request))
+
+ return render_to_response(self.template_name, template_env, context_instance=RequestContext(request))
class AgreementsFilter(object):
except EmptyPage:
# If page is out of range (e.g. 9999), deliver first page.
violation_page = paginator.page(1)
-
- print "\n******************"
- print violations[-1]
- print "******************\n"
-
+
context = {
'agreement_id': agreement_id,
'guarantee_term': agreement.guaranteeterms[guarantee_name],
#import pdb; pdb.set_trace()
print "------------------------------------------------1"
data = {}
- for key, value in request.DATA.items():
+ for key, value in request.DATA.items(): # jgarcia review this
new_key = key
data[new_key] = value
<div class="col-md-9">
<div class="row" id="agreements">
- <table class="table dataTable" id="sla_table" >
- <thead>
- <tr class="header">
- <th colspan="2">Provider</th>
- <!-- <th>Testbed</th>
- <th>Slice_Id</th>
- <th>Agreement</th>
- <th>Metric</th>
- <th>Violations</th>
- <th>Result</th> -->
- </tr>
- </thead>
- <tbody>
+
- <tr class="header">
- <td><span class="glyphicon glyphicon-chevron-down"></span></td>
- <td>iMinds</td>
- </tr>
-
-
- {% for a in agreements %}
-
+{% for row in ag_info %}
<!-- Modal - columns selector -->
-<div class="modal fade" id="agreementModal{{a.agreement_id}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+<div class="modal fade" id="agreementModal{{row.agreement.agreement_id}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<style type="text/css" scoped>
.modal-lg {
</div>
<div class="modal-body">
- <dt>Agreement Id</dt>
- <dd>{{ a.agreement_id|default:" " }}</dd>
- <dt>Provider</dt>
- <dd>{{ a.context.provider|default:" " }}</dd>
- <dt>Experimenter</dt>
- <dd>{{ a.context.consumer|default:" " }}</dd>
- <dt>Service</dt>
- <dd>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the resources during the sliver lifetime</dd>
- <dt>Testbed</dt>
- <dd>{{ a.context.testbed_formatted }}</dd>
- <dt>Accepted on:</dt>
- <dd>{{ a.context.time_formatted|default:" " }}</dd>
+ <dt>Agreement Id</dt>
+ <dd>{{ row.agreement.agreement_id|default:" " }}</dd>
+ <dt>Provider</dt>
+ <dd>{{ row.provider|default:" " }}</dd>
+ <dt>Experimenter</dt>
+ <dd>{{ row.agreement.context.consumer|default:" " }}</dd>
+ <dt>Service</dt>
+ <dd>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the resources during the sliver lifetime</dd>
+ <dt>Testbed</dt>
+ <dd>{{ row.agreement.context.testbed_formatted }}</dd>
+ <dt>Accepted on:</dt>
+ <dd>{{ row.date|default:" " }}</dd>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
-
- <tr>
- {% if a.guaranteestatus == "VIOLATED" %}
- <td class="glyphicon glyphicon-remove-sign" style="color:red;"></td>
- {% elif a.guaranteestatus == "FULFILLED" %}
- <td class="glyphicon glyphicon-ok-sign" style="color:green;"></td>
+
+{% endfor %}
+
+ <table class="display table table-bordered row-border" id="sla_table">
+
+ <thead>
+ <tr>
+ <th>Provider</th>
+ <th>Agreement</th>
+ <th>Date</th>
+ <th>Status</th>
+ <th>Result</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for row in ag_info %}
+
+ <tr>
+
+ <td>{{ row.provider }}</td>
+
+ <td><a class="agreement-detail" data-toggle="modal" data-target="#agreementModal{{row.agreement.agreement_id}}">{{ row.agreement.context.template_id }}</a></td>
+
+ <td>{{ row.date }}</td>
+ <td>{{ row.status }}</td>
+ {% if row.ok == "true" %}
+ <td class="success">99% uptime for {{ row.result }}% resources</td>
+ {% elif row.ok == "false" %}
+ <td class="danger">99% uptime for {{ row.result }}% resources</td>
{% else %}
<td></td>
- {% endif %}
- <td>{{ a.context.template_id }}</td>
- <td>{{ a.context.time_formatted }}</td>
-
- {% with a.agreement_id as key %}
-
- <td>
- <!-- <a class="agreement-detail" href="{% url "agreement_details" a.agreement_id %}" data-toggle="modal" data-target="#agreementModal">View Agreement</a> -->
- <!-- <a class="agreement-detail" href="#" data-agreement="{{ a.agreement_id }}">View Agreement</a> -->
- <a class="agreement-detail" data-toggle="modal" data-target="#agreementModal{{a.agreement_id}}">View Agreement</a>
- </td>
-
- {% for k,v in enforcements.items %}
- {% if key == k %}
- <td>
- {% if v == "ACTIVE" %}
- In progress
- {% elif v == "UNACTIVE" %}
- Disabled
- {% endif %}
- </td>
-
- {% if a.guaranteestatus == "VIOLATED" and v == "UNACTIVE" %}
- <td style="font-weight: bold">
- Result: 99% uptime for
- {% for vi, value in last_violation_list.items %}
- {% if a.agreement_id == vi %}
- {{ value }}%
- {% endif %}
- {% endfor %}
- resources
- </td>
- {% elif a.guaranteestatus == "FULFILLED" and v == "UNACTIVE" %}
- <td style="font-weight: bold">
- Result: 99% uptime for
- {% for vi, value in last_violation_list.items %}
- {% if a.agreement_id == vi %}
- {{ value }}%
- {% endif %}
- {% endfor %}
- resources
- </td>
- {% endif %}
- {% endif %}
-
- {% endfor %}
-
- <!-- <td>{{slicename}}</td> -->
-
-
+ {% endif %}
+ <!-- {% if row.ok == "false" %}
+ <td class="glyphicon glyphicon-remove-sign" style="color:red;"></td>
+ {% elif row.ok == "true" %}
+ <td class="glyphicon glyphicon-ok-sign" style="color:green;"></td>
+ {% else %}
+ <td></td>
+ {% endif %} -->
-
-
- {% endwith %}
- <!-- {% for tname,t in a.guaranteeterms.items %}
- <td> {{ t.servicelevelobjective.kpiname }}</td>
- <td>
- {% if t.status == "VIOLATED" %}
-
- <a class="violation-detail" href="{% url "agreement_term_violations" a.agreement_id t.name %}" data-toggle="modal" data-target="#violationModal">View Violations</a>
- <a class="violation-detail" href="#"
- data-agreement="{{ a.agreement_id }}"
- data-violation="{{ t.name }}">View Violations</a>
- <a class="violation-detail" href="#" data-agreement="{{ a.agreement_id }}" data-violation="{{ t.name }}">{{last_violation_list}}</a>
- {{ t.name }}
-
- {% endif %}
- </td>
- <td id="status" style="display:none;">
- {{ a.statusclass }}
- </td>
- {% endfor %} -->
-
-
-
</tr>
-
{% endfor %}
</tbody>
<script>
$(document).ready(function() {
+
+ $('#sla_table').dataTable({
+ "aoColumns": [
+ null,
+ null,
+ null,
+ null,
+ { "orderSequence": [ "desc", "asc" ] }
+ ]
+ });
+
$('a.violation-detail').click(function () {
var a = $(this).data('agreement');
var v = $(this).data('violation');
from sla import slicetabsla
urlpatterns = patterns('',
- url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
- url(r'^(?P<slicename>[^/]+)/?$', slicetabsla.SLAView.as_view(), name="agreements_summary"),
- url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/detail$', slicetabsla.agreement_details, name='agreement_details'),
- url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/guarantees/(?P<guarantee_name>\w+)/violations$', slicetabsla.agreement_term_violations, name='agreement_term_violations'),
- url(r'^agreements/simplecreate/?$', slicetabsla.AgreementSimple.as_view(), name="agreementsimple"),
-)
-
+ url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
+ url(r'^(?P<slicename>[^/]+)/?$', slicetabsla.SLAView.as_view(), name="agreements_summary"),
+ url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/detail$', slicetabsla.agreement_details, name='agreement_details'),
+ url(r'^agreements/(?P<agreement_id>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/guarantees/(?P<guarantee_name>\w+)/violations$', slicetabsla.agreement_term_violations, name='agreement_term_violations'),
+ url(r'^agreements/simplecreate/?$', slicetabsla.AgreementSimple.as_view(), name="agreementsimple"),
+)
\ No newline at end of file