eclipse.preferences.version=1
+encoding//forge/forms.py=utf-8
+encoding//forge/views.py=utf-8
encoding//portal/django_passresetview.py=utf-8
encoding//portal/forms.py=utf-8
encoding//portal/migrations/0002_extend_slice.py=utf-8
encoding//portal/migrations/0008_extend_user.py=utf-8
encoding//portal/migrations/0009_initial.py=utf-8
encoding//portal/migrations/0010_project.py=utf-8
+encoding//portal/migrations/0011_join.py=utf-8
encoding//portal/models.py=utf-8
encoding//portal/urls.py=utf-8
encoding//portal/validationview.py=utf-8
+encoding//portal/views/__init__.py=utf-8
myfiles: force
@git ls-files | egrep -v 'insert(_|-)above|third-party/|to-be-integrated/'
+pyfiles: force
+ @git ls-files | grep '\.py$$'
+
# in general it's right to rely on the contents as reported by git
tags: force
$(MAKE-SILENT) myfiles | xargs etags
-This file documents the contents of this module
-change
-Last update 20 FEB. 2015
+Last update 18 MAR. 2015
Installation
=================================================================
+Complete Guide: http://trac.myslice.info/wiki/Manifold/Install
+
Recommended OS
===============
Debian GNU/Linux 7.5 (wheezy) x64
--- /dev/null
+Thierry Parmentelat <thierry.parmentelat@inria.fr>
+
+As of March 31 2015, the code should be mostly ready for django-1.7,
+with the following restrictions
+
+* migrations : django-1.7 comes with its own native migrations system
+ and so south is not needed/recommended any longer. So for now we have a
+ version of such native migrations that does a one-shot setup of a db
+ schema but this is stored in
+
+ portal/native_migrations
+
+ instead of the standard location
+
+ portal/migrations
+
+ because this one is still expected to hold south code with earlier djangos
+ You might need to rename native_migrations/ into migrations/ before
+ running manage.py migrate in the first place
+
+* testing quite a few issues related to 1.7 have been addressed but it
+ would be presomptuous to state that things were tested very
+ thoroughly, far from that.
+
+ So please use with care and let meknow of any additional issues
+
+
+
+
+
import time
import datetime
from myslice.configengine import ConfigEngine
+from myslice.settings import logger
+
config = ConfigEngine()
if config.activity and config.activity.apikey :
def logWrite(request, action, message, objects = None):
if not apikey :
- print "===============>> activity: no apikey"
+ logger.info("===============>> activity: no apikey")
return
if not secret :
- print "===============>> activity: no secret"
+ logger.info("===============>> activity: no secret")
return
timestamp = time.mktime(datetime.datetime.today().timetuple())
try :
result = urllib2.urlopen(server, urllib.urlencode(log))
- print "===============>> activity: %s <%s> %s" % (action, request.user,message)
+ logger.info("===============>> activity: {} <{}> {}".format(action, request.user,message))
content = result.read()
except urllib2.URLError as e:
- print "===============>> activity: connection to " + server + " impossible, could not log action"
- print e.strerror
- print ""
+ logger.error("===============>> activity: connection to {} impossible, could not log action".format(server))
+ logger.error(e.strerror)
def log(request, action, message, objects = None):
# Create a new thread in Daemon mode to send the log entry
t.start()
def getClientIp(request):
- x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
- if x_forwarded_for:
+ try :
+ x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
ip = x_forwarded_for.split(',')[0]
- else:
+ except:
ip = request.META.get('REMOTE_ADDR')
return ip
#
# sign the request with the secret key
def sign(secret, message):
- return hmac.new(secret, msg=message, digestmod=hashlib.sha256).hexdigest()
\ No newline at end of file
+ return hmac.new(secret, msg=message, digestmod=hashlib.sha256).hexdigest()
from django.http import HttpResponse
from rest import error
-import os,json
-import ConfigParser
-import string, random
+import os,json,string,random
+import logging,ConfigParser
from portal.models import MeasurementsDB
from manifold.core.query import Query, AnalyzedQuery
from manifoldapi.manifoldapi import execute_query
-from influxdb import InfluxDBClient
+logger = logging.getLogger(__name__)
+
+try :
+ from influxdb import InfluxDBClient
+except :
+ logger.error('can\'t import InfluxDBClient module')
def createDatabase(request, slicename):
result = {}
from myslice.settings import config, logger, DEBUG
+from portal.actions import authority_check_pis
+
+# from unfold.sessioncache import SessionCache
+
# Name my backend 'ManifoldBackend'
class ManifoldBackend:
sessions_result = api.forward(Query.create('local:session').to_dict())
sessions = sessions_result.ok_value()
if not sessions:
- logger.error("GetSession failed", sessions_result.error())
- return
+ logger.error("GetSession failed: {}".format(sessions_result.error()))
+ return None
session = sessions[0]
- logger.debug("SESSION : %s" % session)
+ logger.debug("SESSION : {}".format(session.keys()))
# Change to session authentication
api.auth = {'AuthMethod': 'session', 'session': session['session']}
+ #api.auth = session_auth
self.api = api
# Get account details
persons_result = api.forward(Query.get('local:user').to_dict())
persons = persons_result.ok_value()
if not persons:
- logger.error("GetPersons failed",persons_result.error())
- return
+ logger.error("GetPersons failed: {}".format(persons_result.error()))
+ return None
person = persons[0]
- logger.debug("PERSON : %s" % person)
- #logger.info("%s %s <%s> logged in" % (person['config']['first_name'], person['config']['last_name'], person['config']['email']))
-
+ logger.debug("PERSON : {}".format(person))
+
request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
- except ManifoldException, e:
- logger.error("Manifold Auth Backend: %s" % e.manifold_result)
- except Exception, e:
- logger.error("Manifold Auth Backend: %s" % e)
- #import traceback
- #traceback.print_exc()
+
+ #logger.info("{} {} <{}> logged in"\
+ # .format(person['config']['first_name'], person['config']['last_name'], person['config']['email']))
+
+ #SessionCache().store_auth(request, session_auth)
+
+ except ManifoldException as e:
+ logger.error("ManifoldException in Auth Backend: {}".format(e.manifold_result))
+ except Exception as e:
+ logger.error("Exception in Manifold Auth Backend: {}".format(e))
+ import traceback
+ logger.error(traceback.format_exc())
return None
try:
if 'lastname' in person:
user.last_name = person['lastname']
+ user.pi = authority_check_pis (request, user.email)
+ request.session['user'] = {'email':user.email,'pi':user.pi,'firstname':user.first_name,'lastname':user.last_name}
return user
# Required for your backend to work properly - unchanged in most scenarios
from django.contrib.auth import logout
from django.http import HttpResponseRedirect
+from myslice.settings import logger
+
import activity.user
# hard question : where should we redirect requests to logout if user is not logged in ?
# check that we're indeed logged in
if not request.user.is_authenticated():
return HttpResponseRedirect ('/')
- print "LOGGING OUT"
+ logger.info("LOGGING OUT")
# log user activity
activity.user.logout(request)
# Manifold API Python interface
-import copy, xmlrpclib, ssl
-from myslice.settings import config, logger, DEBUG
+import copy
+import xmlrpclib
+import ssl
from django.contrib import messages
from django.shortcuts import redirect
-from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException
+
from manifold.core.result_value import ResultValue
+from manifoldresult import ManifoldResult, ManifoldCode, ManifoldException, truncate_result
+
+# from unfold.sessioncache import SessionCache
-debug_deep=False
-#debug_deep=True
+from myslice.settings import config, logger
class ManifoldAPI:
# Manifold uses a self signed certificate
# https://www.python.org/dev/peps/pep-0476/
if hasattr(ssl, '_create_unverified_context'):
- self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True, context=ssl._create_unverified_context())
+ self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True,
+ context=ssl._create_unverified_context())
else :
self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True)
def func(*args, **kwds):
import time
-
start = time.time()
+
+ # the message to display
+ auth_message = "<AuthMethod not set in {}>".format(self.auth) if 'AuthMethod' not in self.auth \
+ else "[session]" if self.auth['AuthMethod'] == 'session' \
+ else "user:{}".format(self.auth['Username']) if self.auth['AuthMethod'] == 'password' \
+ else "anonymous" if self.auth['AuthMethod'] == 'anonymous' \
+ else "[???]" + "{}".format(self.auth)
+ end_message = "MANIFOLD <- {}( {}( {} ) ) with auth={} to {}"\
+ .format(methodName,
+ args[0]['action'] or '',
+ args[0]['object'] or '',
+ auth_message,
+ self.url)
try:
-
- #logger.debug("MANIFOLD %s( %s( %s ) ) to %s" % (methodName, args[0]['action'], args[0]['object'], self.url))
-
- if ('Username' in self.auth) :
- username = self.auth['Username']
- else :
- username = "-"
-
args += ({ 'authentication': self.auth },)
-
result = getattr(self.server, methodName)(*args, **kwds)
-
- logger.debug("MANIFOLD %s( %s( %s ) ) as %s to %s executed in %s seconds -> %s" %
- (methodName,
- args[0]['action'] or '',
- args[0]['object'] or '',
- username,
- self.url,
- (time.time() - start),
- args))
-
+ logger.debug("{} executed in {} seconds -> {}"\
+ .format(end_message, time.time() - start, truncate_result(result)))
return ResultValue(**result)
- except Exception, error:
- if True:
- print "===== xmlrpc catch-all exception:", error
- import traceback
- traceback.print_exc(limit=3)
+ except Exception as error:
+ logger.error("===== xmlrpc catch-all exception: {}".format(error))
+ import traceback
+ logger.error(traceback.format_exc(limit=3))
if "Connection refused" in error:
raise ManifoldException ( ManifoldResult (code=ManifoldCode.SERVER_UNREACHABLE,
- output="%s answered %s" % (self.url,error)))
+ output="{} answered {}".format(self.url, error)))
# otherwise
- logger.error("MANIFOLD %s( %s( %s ) ) as %s to %s executed in %s seconds -> %s" %
- (methodName,
- args[0]['action'] or '',
- args[0]['object'] or '',
- username,
- self.url,
- (time.time() - start),
- args))
- logger.error("MANIFOLD %s", error)
- raise ManifoldException ( ManifoldResult (code = ManifoldCode.SERVER_UNREACHABLE, output = "%s" % error) )
+ logger.error("{} FAILED - executed in {} seconds"\
+ .format(end_message, time.time() - start))
+ logger.error("MANIFOLD {}".format(error))
+ raise ManifoldException ( ManifoldResult (code = ManifoldCode.SERVER_UNREACHABLE,
+ output = "{}".format(error)))
return func
manifold_api = ManifoldAPI(auth = manifold_api_session_auth)
- logger.debug("MANIFOLD QUERY : %s" % " ".join(str(query).split()))
- #logger.debug("MANIFOLD DICT : %s" % query.to_dict())
+ logger.debug("MANIFOLD -> QUERY : {}".format(" ".join(str(query).split())))
result = manifold_api.forward(query.to_dict())
if result['code'] == 2:
# this is gross; at the very least we need to logout()
# but most importantly there is a need to refine that test, since
# code==2 does not necessarily mean an expired session
# XXX only if we know it is the issue
- del request.session['manifold']
+ #SessionCache().end_session(request)
# Flush django session
+ del request.session['manifold']
+
request.session.flush()
- #raise Exception, 'Error running query: %r' % result
+ #raise Exception, 'Error running query: {}'.format(result)
if result['code'] == 1:
- logger.warning("MANIFOLD : %s" % result['description'])
+ logger.warning("MANIFOLD : {}".format(result['description']))
# XXX Handle errors
#Error running query: {'origin': [0, 'XMLRPCAPI'], 'code': 2, 'description': 'No such session: No row was found for one()', 'traceback': 'Traceback (most recent call last):\n File "/usr/local/lib/python2.7/dist-packages/manifold/core/xmlrpc_api.py", line 68, in xmlrpc_forward\n user = Auth(auth).check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 245, in check\n return self.auth_method.check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 95, in check\n raise AuthenticationFailure, "No such session: %s" % e\nAuthenticationFailure: No such session: No row was found for one()\n', 'type': 2, 'ts': None, 'value': None}
return result['value']
def execute_query(request, query):
+
+ logger.debug("EXECUTE QUERY: request - {}".format(request.session.items()))
+
if not 'manifold' in request.session or not 'auth' in request.session['manifold']:
+ #manifold_api_session_auth = SessionCache().get_auth(request)
+ #if not manifold_api_session_auth:
request.session.flush()
#raise Exception, "User not authenticated"
host = request.get_host()
return redirect('/')
manifold_api_session_auth = request.session['manifold']['auth']
-
+
return _execute_query(request, query, manifold_api_session_auth)
def execute_admin_query(request, query):
admin_user, admin_password = config.manifold_admin_user_password()
+ if not admin_user or not admin_password:
+ logger.error("""CONFIG: you need to setup admin_user and admin_password in myslice.ini
+Some functions won't work properly until you do so""")
admin_auth = {'AuthMethod': 'password', 'Username': admin_user, 'AuthString': admin_password}
return _execute_query(request, query, admin_auth)
from manifoldresult import ManifoldException
from manifold.util.log import Log
-from myslice.settings import config, logger, DEBUG
+# from unfold.sessioncache import SessionCache
+
+from myslice.settings import config, logger
# register activity
import activity.slice
# expecting a POST
if request.method != 'POST':
- logger.error("MANIFOLDPROXY unexpected method %s -- exiting" % request.method)
- return HttpResponse ({"ret":0}, mimetype="application/json")
+ logger.error("MANIFOLDPROXY unexpected method {} -- exiting".format(request.method))
+ return HttpResponse ({"ret":0}, content_type="application/json")
# we only support json for now
# if needed in the future we should probably cater for
# format_in : how is the query encoded in POST
# format_out: how to serve the results
if format != 'json':
- logger.error("MANIFOLDPROXY unexpected format %s -- exiting" % format)
- return HttpResponse ({"ret":0}, mimetype="application/json")
+ logger.error("MANIFOLDPROXY unexpected format {} -- exiting".format(format))
+ return HttpResponse ({"ret":0}, content_type="application/json")
try:
# translate incoming POST request into a query object
- #logger.debug("MANIFOLDPROXY request.POST %s" % request.POST)
+ #logger.debug("MANIFOLDPROXY request.POST {}".format(request.POST))
manifold_query = Query()
#manifold_query = ManifoldQuery()
if 'manifold' in request.session:
manifold_api_session_auth = request.session['manifold']['auth']
else:
- return HttpResponse (json.dumps({'code':0,'value':[]}), mimetype="application/json")
+ #manifold_api_session_auth = SessionCache().get_auth(request)
+ #if not manifold_api_session_auth:
+ return HttpResponse (json.dumps({'code':0,'value':[]}), content_type="application/json")
if debug_empty and manifold_query.action.lower()=='get':
- return HttpResponse (json.dumps({'code':0,'value':[]}), mimetype="application/json")
+ return HttpResponse (json.dumps({'code':0,'value':[]}), content_type="application/json")
# actually forward
manifold_api= ManifoldAPI(auth=manifold_api_session_auth)
#
# resource reservation
if (manifold_query.action.lower() == 'update') :
- print result['value'][0]
+ logger.debug(result['value'][0])
if 'resource' in result['value'][0] :
for resource in result['value'][0]['resource'] :
activity.slice.resource(request,
json_answer=json.dumps(result)
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
- except Exception,e:
- logger.error("MANIFOLDPROXY %s" % e)
+ except Exception as e:
+ logger.error("MANIFOLDPROXY {}".format(e))
import traceback
- traceback.print_exc()
- return HttpResponse ({"ret":0}, mimetype="application/json")
+ logger.error(traceback.format_exc())
+ return HttpResponse ({"ret":0}, content_type="application/json")
####################
# see CSRF_FAILURE_VIEW in settings.py
# this however turns out disappointing/not very informative
failure_answer=[ "csrf_failure" ]
def csrf_failure(request, reason=""):
- print "CSRF failure with reason '%s'"%reason
- return HttpResponseForbidden (json.dumps (failure_answer), mimetype="application/json")
+ logger.error("CSRF failure with reason '{}'".format(reason))
+ return HttpResponseForbidden (json.dumps (failure_answer), content_type="application/json")
+# black magic to define enums
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
SERVER_UNREACHABLE=3,
)
+def truncate(result, length=50):
+ plain = "{}".format(result)
+ if len(plain) <= length-3:
+ return plain
+ else:
+ return plain[:(length-3)]+'...'
+
_messages_ = { -1 : "Unknown", 0: "OK", 1: "Session Expired", 2: "Not Implemented", 3: "Backend server unreachable"}
+def truncate_result(result, length=50):
+ self = result
+ code = self['code']
+ result = "[MFresult {} (code={})".format(_messages_.get(code, "???"), code)
+ if code == 0:
+ value = self['value']
+ if isinstance(value, list):
+ result += " [value=list with {} elts]".format(len(value))
+ elif isinstance(value, dict):
+ result += " [value=dict with keys {}]".format(value.keys())
+ else:
+ result += " [value={}: {}]".format(type(value).__name__, value)
+ elif 'output' in self:
+ result += " [output={}]".format(self['output'])
+ else:
+ result += "<no output>"
+ result += "]"
+ return truncate(result, 60)
+
# being a dict this can be used with json.dumps
class ManifoldResult (dict):
def __init__ (self, code=ManifoldCode.SUCCESS, value=None, output=""):
- self['code']=code
- self['value']=value
- self['output']=output
+ self['code'] = code
+ self['value'] = value
+ self['output'] = output
self['description'] = '' # Jordan: needed by javascript code
def from_json (self, json_string):
d=json.dumps(json_string)
- for k in ['code','value','output']:
- self[k]=d[k]
+ for k in ['code', 'value', 'output']:
+ self[k] = d[k]
# raw accessors
- def code (self): return self['code']
- def output (self): return self['output']
+ def code (self):
+ return self['code']
+ def output (self):
+ return self['output']
# this returns None if there's a problem, the value otherwise
def ok_value (self):
- if self['code']==ManifoldCode.SUCCESS:
+ if self['code'] == ManifoldCode.SUCCESS:
return self['value']
# both data in a single string
def error (self):
- return "code=%s -- %s"%(self['code'],self['output'])
+ return "code={} -- {}".format(self['code'], self['output'])
def __repr__ (self):
- code=self['code']
- result="[MFresult %s (code=%s)"%(_messages_.get(code,"???"),code)
- if code==0:
- value=self['value']
- if isinstance(value,list): result += " [value=list with %d elts]"%len(value)
- elif isinstance(value,dict): result += " [value=dict with keys %s]"%value.keys()
- else: result += " [value=%s: %s]"%(type(value).__name__,value)
- else:
- result += " [output=%s]"%self['output']
- result += "]"
- return result
+ return truncate_result(self, 60)
# probably simpler to use a single class and transport the whole result there
# instead of a clumsy set of derived classes
def __init__ (self, manifold_result):
self.manifold_result=manifold_result
def __repr__ (self):
- return "Manifold Exception %s"%(self.manifold_result.error())
+ return "<Manifold Exception {}>".format(self.manifold_result.error())
from django.contrib import messages
+from myslice.settings import logger
+
debug=False
#debug=True
# xxx need a way to export error messages to the UI
if result['code'] == 1: # warning
# messages.warning(request, result['description'])
- print ("METADATA WARNING -",request,result['description'])
+ logger.warning(("METADATA WARNING - {} {}".format(request,result['description'])))
elif result['code'] == 2:
# messages.error(request, result['description'])
- print ("METADATA ERROR -",request,result['description'])
+ logger.error(("METADATA ERROR - {} {}".format(request,result['description'])))
# XXX FAIL HERE XXX
return
return self.hash_by_object[object]['column'].sort()
def get_field_type(self, object, field):
- if debug: print "Temp fix for metadata::get_field_type() -> consider moving to manifold.core.metadata soon"
+ if debug:
+ logger.debug("Temp fix for metadata::get_field_type() -> consider moving to manifold.core.metadata soon")
return field
* RECORD STATES (for query_store)
******************************************************************************/
-var STATE_SET = 0;
-var STATE_VALUE = 1;
-var STATE_WARNINGS = 2;
-var STATE_VISIBLE = 3;
+var STATE_SET = 20;
+var STATE_VALUE = 21;
+var STATE_WARNINGS = 22;
+var STATE_VISIBLE = 23;
// ACTIONS
var STATE_SET_CHANGE = 0;
var CONSTRAINT_RESERVABLE_LEASE_MSG = "Configuration required: this resource needs to be scheduled";
+var CONSTRAINT_SLA = 1;
+
+var CONSTRAINT_SLA_MSG = "SLA acceptance required: testbed offers SLA for its resources"
+
// A structure for storing queries
function QueryExt(query, parent_query_ext, main_query_ext, update_query_ext, disabled, domain_query_ext) {
switch(query.object) {
case 'resource':
+
+ var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
// CONSTRAINT_RESERVABLE_LEASE
//
// +) If a reservable node is added to the slice, then it should have a corresponding lease
// XXX Not always a resource
var is_reservable = (record.exclusive == true);
if (is_reservable) {
- var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
+ // var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
if (event_type == STATE_SET_ADD) {
// We should have a lease_query associated
// XXX Need for a better function to manage warnings
var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+
+ /*manifold.query_store.set_record_state(query.query_uuid, record_key, STATE_WARNINGS, warnings);
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : record_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);*/
+
} else {
// Lease are defined, delete the warning in case it was set previously
delete warnings[CONSTRAINT_RESERVABLE_LEASE];
// Remove warnings attached to this resource
delete warnings[CONSTRAINT_RESERVABLE_LEASE];
}
-
- manifold.query_store.set_record_state(query.query_uuid, record_key, STATE_WARNINGS, warnings);
}
- /* This was redundant */
- // manifold.query_store.recount(query.query_uuid);
+ /*var urn_regexp = /\+(.*?)\+/;
+ var testbed_urn = urn_regexp.exec(record.urn)[1];
+ var has_sla = $.inArray(testbed_urn, localStorage.getItem("sla_testbeds").split(",")) != -1;
+
+ if (has_sla) {
+ // var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
+ if (event_type == STATE_SET_ADD) {
+ var warn = CONSTRAINT_SLA_MSG;
+ warnings[CONSTRAINT_SLA] = warn;
+ } else {
+ delete warnings[CONSTRAINT_SLA];
+ }
+ }*/
+
+ manifold.query_store.set_record_state(query.query_uuid, record_key, STATE_WARNINGS, warnings);
// Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
data = {
state: STATE_WARNINGS,
value : warnings
}
manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);
+
+ // JGLL: SLA code
+ /*get_testbeds_with_sla()
+ .done( function(testbeds) {
+ var urn_regexp = /\+(.*?)\+/;
+ var testbed_urn = urn_regexp.exec(record.urn)[1];
+
+ var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
+
+ if ($.inArray(testbed_urn, testbeds) != -1) {
+ // JGLL: Set a warning on resources covered by testbeds offering SLAs
+ // CONSTRAINT_SLA
+
+ if (event_type == STATE_SET_ADD) {
+ var warn = CONSTRAINT_SLA_MSG;
+ warnings[CONSTRAINT_SLA] = warn;
+ } else {
+ delete warnings[CONSTRAINT_SLA]
+ }
+ }
+
+ manifold.query_store.set_record_state(query.query_uuid, record_key, STATE_WARNINGS, warnings);
+
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : record_key,
+ op : null,
+ value : warnings
+ }
+
+ manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);
+ })
+ .fail( function(err) {
+ console.log("SLA - Error retrieving testbeds that support SLAs");
+ });*/
+
+ /* This was redundant */
+ // manifold.query_store.recount(query.query_uuid);
+
break;
case 'lease':
var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
- if (event_type == STATE_SET_ADD) {
+ if (event_type == STATE_SET_ADD || event_type == STATE_SET_IN_PENDING) {
// A lease is added, it removes the constraint
delete warnings[CONSTRAINT_RESERVABLE_LEASE];
} else {
// XXX Need for a better function to manage warnings
var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : resource_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
} else {
// Lease are defined, delete the warning in case it was set previously
delete warnings[CONSTRAINT_RESERVABLE_LEASE];
}
-
}
-
+ /* Adding a lease can remove a warning and reduce the unconfigured resources */
manifold.query_store.recount(resource_query.query_uuid);
-
- // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
- data = {
- state: STATE_WARNINGS,
- key : resource_key,
- op : null,
- value : warnings
- }
- manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
break;
}
query = query_ext.query;
switch(event_type) {
+ case STATUS_REMOVE_WARNING:
+ record = manifold.query_store.get_record(query_uuid, data.value);
+ this._enforce_constraints(query_ext, record, data.value, STATE_SET_REMOVE);
+ break;
// XXX At some point, should be renamed to RECORD_STATE_CHANGED
case FIELD_STATE_CHANGED:
__import__(component)
u.append( url(r'^%s/' % component, include('%s.urls' % component)) )
except Exception, e:
- logger.info("Cannot load component (%s): %s" % (component, e))
+ logger.error("Cannot load component ({}): {}".format(component, e))
else:
- logger.info("Loaded component %s" % component)
+ logger.info("Loaded component {}".format(component))
return u
[manifold]
url = https://portal.onelab.eu:7080/
+admin_user =
+admin_password =
+
+[myslice]
+theme = onelab
+debug = true
+httproot =
+dataroot =
+components = sla,influxdb,forge
+
+[database]
+# postgresql_psycopg2, mysql, sqlite3 or oracle
+engine = sqlite3
+#name = myslice
+name = /Users/parmentelat/git/myslice/unfold.sqlite3
+server =
+port =
+user =
+password =
+
+
+
+[activity]
+#server = http://athos.ipv6.lip6.fr/activity/push/log
+#apikey =
+#secret =
ROOT = os.path.realpath(os.path.dirname(__file__) + '/..')
except:
import traceback
- traceback.print_exc()
+ logger.error(traceback.format_exc())
from myslice.configengine import ConfigEngine
# DEBUG
if config.myslice.debug :
DEBUG = True
+ INTERNAL_IPS = ("127.0.0.1","132.227.84.195","132.227.78.191","132.227.84.191")
else :
DEBUG = False
# our django project
'myslice',
# the core of the UI
- 'auth',
+ 'localauth',
'manifoldapi',
'unfold',
# plugins
'plugins',
# views - more or less stable
'ui',
- # managing database migrations
- 'south',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# FORGE Plugin app
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'portal',
+ #'debug_toolbar',
]
+# with django-1.7 we leave south and use native migrations
+# managing database migrations
+import django
+major, minor, _, _, _ = django.VERSION
+if major == 1 and minor <= 6:
+ INSTALLED_APPS.append('south')
+
# this app won't load in a build environment
-if not building: INSTALLED_APPS.append ('rest')
+if not building:
+ INSTALLED_APPS.append ('rest')
for component in components.list() :
INSTALLED_APPS.append(component)
for aux in auxiliaries:
if os.path.isdir(os.path.join(ROOT,aux)):
- print("Using devel auxiliary",aux)
+ logger.info("Using devel auxiliary {}".format(aux))
INSTALLED_APPS.append(aux)
ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.
}
}
-AUTHENTICATION_BACKENDS = ('auth.manifoldbackend.ManifoldBackend',
+AUTHENTICATION_BACKENDS = ('localauth.manifoldbackend.ManifoldBackend',
'django.contrib.auth.backends.ModelBackend')
### the view to redirect malformed (i.e. with a wrong CSRF) incoming requests
####SLA#####
-SLA_MANAGER_URL = "http://157.193.215.125:4001/sla-collector/sla"
-#SLA_MANAGER_URL = "http://172.24.76.28:8000/sla"
-SLA_MANAGER_USER = "portal"
-SLA_MANAGER_PASSWORD = "password"
+SLA_COLLECTOR_URL = "http://157.193.215.125:4001/sla-collector/sla"
+SLA_COLLECTOR_USER = "portal"
+SLA_COLLECTOR_PASSWORD = "password"
# admin.autodiscover()
# to enable insert_above stuff
-from django.template.loader import add_to_builtins
+# add_to_builtins has changed location with django-1.7
+# also note this will probably go away some day
+try:
+ from django.template.loader import add_to_builtins
+except:
+ from django.template.base import add_to_builtins
add_to_builtins('insert_above.templatetags.insert_tags')
from settings import auxiliaries, INSTALLED_APPS
# seems to be what login_required uses to redirect ...
(r'^accounts/login/$', portal.homeview.HomeView.as_view()),
(r'^login/?$', portal.homeview.HomeView.as_view()),
- (r'^logout/?$', 'auth.views.logout_user'),
+ (r'^logout/?$', 'localauth.views.logout_user'),
#
# the manifold proxy
(r'^manifold/proxy/(?P<format>\w+)/?$', 'manifoldapi.manifoldproxy.proxy'),
(r'^credentials/(?P<action>[^/]+)/?$', 'rest.credentials.dispatch'),
(r'^cache/(?P<action>[^/]+)/?$', 'rest.cache.dispatch'),
(r'^initscript/(?P<action>[^/]+)/?$', 'rest.initscript.dispatch'),
+ (r'^authority/(?P<action>[^/]+)/?$', 'rest.authority.dispatch'),
#
# REST monitoring
(r'^monitor/services/?$', 'rest.monitor.servicesStatus'),
url(r'^portal/', include('portal.urls')),
# SLA
-# url(r'^sla/', include('sla.urls')),
+ #url(r'^sla/', include('sla.urls')),
]
urls.extend( components.urls() )
metadata = self.page.get_metadata()
md_fields = metadata.details_by_object('resource')
+ sla_column_info = {
+ 'name': 'sla_supported',
+ 'default': '',
+ 'is_array': False,
+ 'description': '',
+ 'type': 'bool',
+ 'qualifier': None
+ }
+
+ if sla_column_info not in md_fields['column']:
+ md_fields['column'].append(sla_column_info)
+
# XXX use django templating system here
for md_field in sorted(md_fields['column']):
if md_field['type'] == 'string':
class FilterStatusPlugin(Plugin):
- def __init__ (self, query=None, **settings):
+ def __init__ (self, query=None, query_lease=None, **settings):
Plugin.__init__ (self, **settings)
self.query = query
+ self.query_lease = query_lease
+ self.query_lease_uuid = query_lease.query_uuid
+
def template_file (self):
return "filter_status.html"
# query_uuid will pass self.query results to the javascript
# and will be available as "record" in :
# on_new_record: function(record)
- return ['plugin_uuid', 'domid', 'query_uuid']
+ return ['plugin_uuid', 'domid', 'query_uuid', 'query_lease_uuid']
def export_json_settings (self):
return True
/* Setup query and record handlers */
this.listen_query(options.query_uuid);
+ this.listen_query(options.query_lease_uuid, 'leases');
/* Setup click handlers */
this.elts('list-group-item').click({'instance': this}, this._on_click);
// XXX
},
+ on_leases_field_state_changed: function(data)
+ {
+ console.log('leases_field_state_changed');
+ this.on_field_state_changed(data);
+ },
on_field_state_changed: function(data)
{
var query_ext;
def __init__ (self, **settings):
Plugin.__init__(self, **settings)
- print "SETTINGS", settings
assert 'page' in settings, "You should specify page"
assert 'object' in settings, "You should specify object"
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class QueryGrid (Plugin):
"""A plugin for displaying a query as a list
if self.checkboxes:
# we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
if 'aoColumns' in self.datatables_options:
- print 'WARNING: querygrid uses aoColumnDefs, your aoColumns spec. is discarded'
+ logger.warning('WARNING: querygrid uses aoColumnDefs, your aoColumns spec. is discarded')
del self.datatables_options['aoColumns']
# set aoColumnDefs in datatables_options - might already have stuff in there
aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class QueryTable (Plugin):
"""A plugin for displaying a query as a list
_columns = columns
_hidden_columns = []
elif self.query:
- print "self.query.fields = ", self.query_all.fields
+ logger.debug("self.query.fields = {}".format(self.query_all.fields))
# Columns displayed by default
if self.default_fields is not None:
_columns = [field for field in self.default_fields if not field == 'urn']
if query_all:
# We need a list because sets are not JSON-serializable
if self.default_fields is not None:
- print self.query_all.fields
+ logger.debug(self.query_all.fields)
_hidden_columns = list(self.query_all.fields - set(self.default_fields))
else:
_hidden_columns = list(self.query_all.fields - self.query.fields)
_columns = []
_hidden_columns = []
- print "_columns=", _columns
+ logger.debug("_columns={}".format(_columns))
self.columns = { self.mapping.get(c, c) : c for c in _columns }
self.hidden_columns = { self.mapping.get(c, c) : c for c in _hidden_columns }
- print "self.columns", self.columns
- print "self.hidden_columns", self.hidden_columns
+ logger.debug("self.columns {}".format(self.columns))
+ logger.debug("self.hidden_columns {}".format(self.hidden_columns))
self.init_key=init_key
self.datatables_options=datatables_options
if self.checkboxes:
# we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
if 'aoColumns' in self.datatables_options:
- print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded'
+ logger.warning('WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded')
del self.datatables_options['aoColumns']
# set aoColumnDefs in datatables_options - might already have stuff in there
aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
resourceData['type'] = 'node ( Hardware: <a target="_blank" href="https://www.iot-lab.info/hardware/'+n[0]+'/">'+n[0]+'</a> )';
var coordinates = resourceData['testbed'];
} else {
- var logo = network_hrn;
+ var logo = resourceData['testbed'];
var resourceLocation = {
'longitude' : aData[13],
'latitude' : aData[23],
this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
break;
case STATE_SET_IN_PENDING:
- this.set_checkbox_from_data(data.key, true);
+ this.set_checkbox_from_data(data.value, true);
this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_ADDED);
break;
case STATE_SET_OUT_PENDING:
- this.set_checkbox_from_data(data.key, false);
+ this.set_checkbox_from_data(data.value, false);
this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_REMOVED);
break;
}
op : STATE_SET_ADD,
value: new_lease
}
+ prev_state = manifold.query_store.get_record_state($scope.instance.options.query_uuid, resource_urn, STATE_SET);
manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
+
/* Add to local cache also, unless we listen to events from outside */
- if (!(resource_urn in $scope._leases_by_resource))
+ if (!(resource_urn in $scope._leases_by_resource)){
$scope._leases_by_resource[resource_urn] = [];
+ /* Add the resource of the selected timeslot to the pending list */
+ data_resource = {
+ state: STATE_SET,
+ key : null,
+ op : STATE_SET_ADD,
+ value: resource_urn
+ };
+ /* Send the message to the list of resources, depending on the previous state */
+ prev_state = manifold.query_store.get_record_state($scope.instance.options.query_uuid, data_resource.value, STATE_SET);
+ if(jQuery.inArray(prev_state,[STATE_SET_OUT,STATE_SET_OUT_SUCCESS,STATE_SET_OUT_PENDING,STATE_SET_IN_FAILURE])>-1){
+ manifold.raise_event($scope.instance.options.query_uuid, FIELD_STATE_CHANGED, data_resource);
+ }
+ /* Remove the warning on resource as we have added Leases to it */
+ //manifold.raise_event($scope.instance.options.query_uuid, STATUS_REMOVE_WARNING, data_resource);
+ }
$scope._leases_by_resource[resource_urn].push(new_lease);
+
}
$scope._remove_lease = function(other)
op : STATE_SET_REMOVE,
value: other_key
}
+ prev_state = manifold.query_store.get_record_state($scope.instance.options.query_uuid, other.resource, STATE_SET);
manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);
- /* Remove from local cache also, unless we listen to events from outside */
+ /* Remove Lease from local cache also, unless we listen to events from outside */
$scope._leases_by_resource[other.resource] = $.grep($scope._leases_by_resource[other.resource], function(x) { return x != other; });
-
+ /* Last lease removed for this resource -> remove the resource from the list */
+ if($scope._leases_by_resource.hasOwnProperty(other.resource) && $scope._leases_by_resource[other.resource].length == 0){
+ /* remove resource from the list of selected resources */
+ data_resource = {
+ state: STATE_SET,
+ key : null,
+ op : STATE_SET_REMOVE,
+ value: other.resource
+ };
+
+ prev_state = manifold.query_store.get_record_state($scope.instance.options.query_uuid, data_resource.value, STATE_SET);
+ /* Remove Resource from local cache */
+ delete $scope._leases_by_resource[data_resource.value]
+ /* Send the message to the list of resources, depending on the previous state */
+ if(jQuery.inArray(prev_state,[STATE_SET_IN,STATE_SET_IN_SUCCESS,STATE_SET_IN_PENDING,STATE_SET_OUT_FAILURE])>-1){
+ manifold.raise_event($scope.instance.options.query_uuid, FIELD_STATE_CHANGED, data_resource);
+ //manifold.raise_event($scope.instance.options.query_uuid, STATUS_REMOVE_WARNING, data_resource);
+ }
+
+ }
}
$scope.select = function(index, model_lease, model_resource)
on_leases_filter_removed: function(filter) { this._get_scope().$apply(); },
on_leases_filter_clear: function() { this._get_scope().$apply(); },
- on_field_state_changed: function(data)
+ on_resources_field_state_changed: function(data)
{
- /*
- this._set_lease_slots(lease_key, lease);
-
+ console.log('on_resources_field_state_changed');
+ console.log(data);
switch(data.state) {
case STATE_SET:
switch(data.op) {
+ /*
case STATE_SET_IN:
case STATE_SET_IN_SUCCESS:
case STATE_SET_OUT_FAILURE:
- this.set_checkbox_from_data(data.value, true);
- this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
+ //this.set_checkbox_from_data(data.value, true);
+ //this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
break;
+ */
case STATE_SET_OUT:
case STATE_SET_OUT_SUCCESS:
case STATE_SET_IN_FAILURE:
- this.set_checkbox_from_data(data.value, false);
- this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_RESET);
+ // A resource has been removed
+ console.log(this._get_scope()._leases_by_resource);
+ s = this._get_scope();
+ // loop over the list of leases by resource cached
+ $.each(this._get_scope()._leases_by_resource, function(k,v){
+ // if the resource removed is in the list
+ // we need to remove all the leases corresponding to that resoruce
+ if(k == data.value){
+ console.log(k,v);
+ // loop each lease should be removed
+ $.each(v, function(i,lease){
+ console.log(i,lease);
+ s._remove_lease(lease);
+ });
+ }
+ });
break;
+ /*
case STATE_SET_IN_PENDING:
this.set_checkbox_from_data(data.key, true);
this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_ADDED);
this.set_checkbox_from_data(data.key, false);
this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_REMOVED);
break;
+ */
}
break;
-
+ /*
case STATE_WARNINGS:
this.change_status(data.key, data.value);
break;
+ */
}
- */
},
//alert("1");\r
</script>\r
</div>\r
+</div>
\ No newline at end of file
+#sla_dialog {
+ //margin-top: 2em;
+ margin-left: 1em;
+}
+
+#sla_offers div.row p {
+ line-height: 40px;
+}
+
+span.provider {
+ font-weight: bold;
+}
\ No newline at end of file
var SlaDialog = Plugin.extend({
+ accepted_slas: {},
+ queries: [],
+
/** XXX to check
* @brief Plugin constructor
* @param options : an associative array of setting values
/* GUI setup and event binding */
// call function
+ this.button_binding();
+
+ // Get testbeds with sla and store them in localStorage
+ //this.get_testbeds_with_sla();
+
+ },
+ get_testbeds_with_sla: function () {
+ return $.get('/sla/testbeds/', function(data) {
+ if (typeof(Storage) !== "undefined") {
+ if (!localStorage.getItem("sla_testbeds")) {
+ var testbeds = data;
+ localStorage.setItem("sla_testbeds", testbeds);
+ }
+ }
+ });
},
find_row: function(key)
return cols[0];
},
+ check_template_status: function() {
+ for (var testbed in this.accepted_slas) {
+ if (!this.accepted_slas[testbed]) { return false; }
+ }
+
+ return true;
+ },
+
/* PLUGIN EVENTS */
// on_show like in querytable
/* GUI EVENTS */
+ button_binding: function() {
+ var self = this;
+ $(".sla-accept-button").click(function() {
+ // set SLA as accepted and remove warnings
+ var id = $(this).closest(".row").attr("id");
+ self.accepted_slas[id] = true;
+ var is_ok = self.check_template_status();
+
+ $(".sla-alert").show();
+ $(this).button("complete");
+ $(this).prop("disabled", true);
+
+ if (is_ok) {
+ // remove warnings
+ // var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+ }
+ });
+
+ $(".sla-alert-close").click(function() {
+ $(this).closest(".sla-alert").hide();
+ });
+ },
+
+ create_sla: function(record) {
+ var self = this;
+
+ var urns = [];
+
+ if (record.resource.length != 0 && typeof record.resource[0] === "object") {
+
+ record.resource.forEach(function(r) {
+ if ($.inArray(r.component_id, record.resource) == -1) { // if not already selected
+ urns.push(r.component_id);
+ }
+ });
+
+ var data = {
+ "SLIVER_INFO_AGGREGATE_URN": record.resource[0].component_manager_id,
+ "SLIVER_INFO_EXPIRATION": record.lease[0].end_time, // FIXME: only working with leases
+ "SLIVER_INFO_SLICE_URN": record.slice_urn,
+ "SLIVER_INFO_CREATOR_URN": record.users[0],
+ "SLIVER_INFO_URN": urns,
+ "SLIVER_INFO_SLA_ID": self._getUUID()
+ };
+
+ console.log(data);
+
+ $.post("/sla/agreements/create/", data)
+ .done(function (response) {
+ console.log("SLA created");
+ });
+ }
+ },
+
uncheck: function(urn)
{
- $('#slamodal').on('hidden.bs.modal', function(e){
- $('#' + (urn).replace(/"/g,'')).click();
- console.log('#' + (data.value).replace(/"/g,''));
- });
+// $('#slamodal').on('hidden.bs.modal', function(e){
+// $('#' + (urn).replace(/"/g,'')).click();
+// console.log('#' + (data.value).replace(/"/g,''));
+// });
},
// a function to bind events here: click change
},
- on_field_state_changed: function(result)
+ on_field_state_changed: function(data)
{
- console.log("triggered state_changed: "+result);
+ var self = this;
// this.set_state(result, this.options.username);
+
+ switch(data.state) {
+ case STATE_SET:
+ switch(data.op) {
+ case STATE_SET_IN_PENDING:
+ if (typeof(data.value) == 'string') {
+ // data.value = urn
+ this._supports_sla(data.value)
+ .done( function(testbeds) {
+ var urn_regexp = /\+(.*?)\+/;
+ var urn = urn_regexp.exec(data.value)[1];
+ var pos = $.inArray(urn, testbeds);
+ if ( pos != -1) {
+ var id_ref = testbeds[pos].replace(/\.|:/g, "-");
+ $("#" + id_ref).data("urns").push(data.value);
+ $("#" + id_ref).show();
+ self.accepted_slas[id_ref] = false;
+ //$( "#sla_offers_list" ).append(
+ // $("<li>").text("Testbed " + testbeds[pos] + " offers SLA for its resources")
+ //);
+ }
+ });
+ }
+ break;
+ case STATE_SET_OUT:
+ // data.value = urn
+ if (typeof(data.value) == 'string') {
+ // data.value = urn
+ this._supports_sla(data.value)
+ .done( function(testbeds) {
+ var urn_regexp = /\+(.*?)\+/;
+ var urn = urn_regexp.exec(data.value)[1];
+ var pos = $.inArray(urn, testbeds);
+ if ( pos != -1) {
+ var id_ref = testbeds[pos].replace(/\.|:/g, "-");
+ var array = $("#" + id_ref).data("urns");
+ array.splice(array.indexOf(data.value), 1);
+
+ if ($("#" + id_ref).data("urns").length == 0) {
+ $("#" + id_ref).hide();
+ delete self.accepted_slas[id_ref];
+ $(".sla-accept-button").button("reset");
+ $(".sla-accept-button").prop("disabled", false);
+ }
+ //$( "#sla_offers_list" ).append(
+ // $("<li>").text("Testbed " + testbeds[pos] + " offers SLA for its resources")
+ //);
+ }
+ });
+ }
+ break;
+ }
+ break;
+
+ case STATE_WARNINGS:
+ // Add resource to SLA
+ // data.key = urn
+ // data.value = {1: "SLA acceptance required..."}
+ // this.change_status(data.key, data.value);
+ break;
+ }
},
// ... be sure to list all events here
on_new_record: function(record)
{
-
+ this.create_sla(record);
},
/* INTERNAL FUNCTIONS */
// only convention, not strictly enforced at the moment
},
+ _supports_sla: function(resource_urn) {
+ return $.ajax("/sla/testbeds/");
+ },
+
+
+
+ _getUUID: function() {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ });
+ },
+
});
/* Plugin registration */
<div id={{ domid }}>
-<div class="modal fade" id="slamodal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
- data-backdrop="static" data-keyboard="false">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title" id="myModalLabel">Selected testbed(s) provide the following SLAs</h4>
- </div>
- <div class="modal-body" id="modal-body">
- <table class="table" id="sla-modal-table">
- <thead>
- <tr>
- <th>Testbed</th>
- <th>SLA Description</th>
- <th>Accept</th>
- </tr>
- </thead>
- <tbody id="sla-table-body">
- </tbody>
- </table>
- </div>
- <div class="modal-footer">
- <button type="button" id="cancel_sla" class="btn btn-default" data-dismiss="modal">Cancel</button>
- <button type="button" id="submit_sla" class="btn btn-primary">Submit</button>
- </div>
+ <div id="sla_template_modal" class="modal fade">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+ <h4 class="modal-title">SLA Template description</h4>
+ </div>
+ <div class="modal-body">
+ <p>Testbed offers:</p>
+ <p>99% availability for 99% of the selected resources</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
</div>
- </div>
-</div>
-<!-- <div class="modal fade" id="slamodal-virtualwall" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
- data-backdrop="static" data-keyboard="false">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title" id="modalTitleId">Provider iMinds offers the following SLA</h4>
- </div>
- <div class="modal-body" id="modal-body">
- <p>SLA description</p>
- <p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>
- </div>
- <div class="modal-footer">
- <button type="button" id="dismiss_sla_vwall" class="btn btn-default" data-dismiss="modal">Dismiss</button>
- <button type="button" id="accept_sla_vwall" class="btn btn-primary">Accept</button>
- </div>
+ <div class="sla-alert" hidden="hidden">
+ <div class="alert alert-success fade in">
+ <a href="#" class="sla-alert-close">×</a>
+ <strong>Accepted!</strong> The SLA has been accepted.
+ </div>
</div>
- </div>
-</div> -->
-</div>
+ <div id="sla_offers" class="container">
+ <div id="fuseco-fokus-fraunhofer-de" class="row" data-urns="[]" style="display: none">
+ <div class="col-md-6">
+ <p>Testbed <span class="provider">fuseco.fokus.fraunhofer.de</span> offers the following SLA for its resources</p>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-info-button btn btn-default" data-toggle="modal" data-target="#sla_template_modal">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ Details
+ </button>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-accept-button btn btn-default" data-complete-text="Accepted" autocomplete="off">
+ <span class="glyphicon glyphicon-ok"></span>
+ Accept
+ </button>
+ </div>
+ </div>
+ <div id="omf-netmode" class="row" data-urns="[]" style="display: none">
+ <div class="col-md-6">
+ <p>Testbed <span class="provider">omf:netmode</span> offers the following SLA for its resources</p>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-info-button btn btn-default" data-toggle="modal" data-target="#sla_template_modal">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ Details
+ </button>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-accept-button btn btn-default" data-complete-text="Accepted" autocomplete="off">
+ <span class="glyphicon glyphicon-ok"></span>
+ Accept
+ </button>
+ </div>
+ </div>
+ <div id="wilab2-ilabt-iminds-be" class="row" data-urns="[]" style="display: none">
+ <div class="col-md-6">
+ <p>Testbed <span class="provider">wilab2.ilabt.iminds.be</span> offers the following SLA for its resources</p>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-info-button btn btn-default" data-toggle="modal" data-target="#sla_template_modal">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ Details
+ </button>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-accept-button btn btn-default" data-complete-text="Accepted" autocomplete="off">
+ <span class="glyphicon glyphicon-ok"></span>
+ Accept
+ </button>
+ </div>
+ </div>
+ <div id="wall2-ilabt-iminds-be" class="row" data-urns="[]" style="display: none">
+ <div class="col-md-6">
+ <p>Testbed <span class="provider">wall2.ilabt.iminds.be</span> offers the following SLA for its resources</p>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-info-button btn btn-default" data-toggle="modal" data-target="#sla_template_modal">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ Details
+ </button>
+ </div>
+ <div class="col-md-1">
+ <button class="sla-accept-button btn btn-default" data-complete-text="Accepted" autocomplete="off">
+ <span class="glyphicon glyphicon-ok"></span>
+ Accept
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class Univbris(Plugin):
def __init__ (self, query=None, **settings):
Plugin.__init__ (self, **settings)
self.query=query
- self.query_uuid = query.query_uuid if query else None
- print "called univbris plugin"
+ self.query_uuid = query.query_uuid if query else None
+ logger.info("called univbris plugin")
def template_file (self):
try:
return "univbris_welcome.html"
- except Exception:
- print "error template"
+ except Exception as e:
+ logger.error("error template {}".format(e))
def requirements (self):
reqs = {
- 'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
- "js/manifold.js", "js/manifold-query.js",
- "js/unfold-helper.js",
+ 'js_files' : [
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/manifold.js", "js/manifold-query.js",
+ "js/unfold-helper.js",
'js/univbris.js',
],
'css_files': [
# query_uuid will pass self.query results to the javascript
# and will be available as "record" in :
# on_new_record: function(record)
- return ['plugin_uuid', 'domid', 'query_uuid','init_key',]
+ return ['plugin_uuid', 'domid', 'query_uuid', 'init_key', ]
def export_json_settings (self):
return True
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class UnivbrisFoam (Plugin):
"""
# Until we have a proper way to access queries in Python
self.query_all = query_all
self.query_all_uuid = query_all.query_uuid if query_all else None
- self.sync_query_uuid = sync_query.query_uuid if sync_query else None
+ self.sync_query_uuid = sync_query.query_uuid if sync_query else None
self.checkboxes = checkboxes
# XXX We need to have some hidden columns until we properly handle dynamic queries
if columns is not None:
self.columns=columns
self.hidden_columns = []
elif self.query:
- self.columns = list (['testbed','head node id/port','tail node id/port','link type','selected'])
- #replace production
+ self.columns = list (['testbed','head node id/port','tail node id/port','link type','selected'])
+ #replace production
#self.columns = self.query.fields
if query_all:
#replace production
- self.hidden_columns = []
- # We need a list because sets are not JSON-serializable
+ self.hidden_columns = []
+ # We need a list because sets are not JSON-serializable
#self.hidden_columns = #list(self.query_all.fields - self.query.fields)
else:
self.hidden_columns = []
if self.checkboxes:
# we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
if 'aoColumns' in self.datatables_options:
- print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded'
+ logger.warning('WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded')
del self.datatables_options['aoColumns']
# set aoColumnDefs in datatables_options - might already have stuff in there
aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class UnivbrisFv (Plugin):
"""
self.columns=columns
self.hidden_columns = []
elif self.query:
- self.columns = list (['Flowspace Name', 'Edit', 'Delete'])
- #replace production
+ self.columns = list (['Flowspace Name', 'Edit', 'Delete'])
+ #replace production
#self.columns = self.query.fields
if query_all:
#replace production
- self.hidden_columns = []
- # We need a list because sets are not JSON-serializable
+ self.hidden_columns = []
+ # We need a list because sets are not JSON-serializable
#self.hidden_columns = #list(self.query_all.fields - self.query.fields)
else:
self.hidden_columns = []
self.columns = []
self.hidden_columns = []
- self.columns = list (['Flowspace Name', 'Edit', 'Delete'])
+ self.columns = list (['Flowspace Name', 'Edit', 'Delete'])
self.init_key=init_key
self.datatables_options=datatables_options
# if checkboxes were required, we tell datatables about this column's type
if self.checkboxes:
# we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
if 'aoColumns' in self.datatables_options:
- print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded'
+ logger.warning('WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded')
del self.datatables_options['aoColumns']
# set aoColumnDefs in datatables_options - might already have stuff in there
aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
def requirements (self):
reqs = {
'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
- "js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js", "js/jquery.jeditable.js",
+ "js/dataTables.js", "js/dataTables.bootstrap.js",
+ "js/with-datatables.js", "js/jquery.jeditable.js",
"js/manifold.js", "js/manifold-query.js",
"js/unfold-helper.js",
# querytable.js needs to be loaded after dataTables.js as it extends
# dataTableExt.afnSortData
- # "js/jquery-ui.min.js" "js/jquery.dataTables.editable.js", "js/jquery.validate.js",
+ # "js/jquery-ui.min.js" "js/jquery.dataTables.editable.js", "js/jquery.validate.js",
"js/univbrisfv.js",#"js/univbrisfv.js",
] ,
'css_files': [ "css/dataTables.bootstrap.css",
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class UnivbrisTopo(Plugin):
def __init__ (self, query=None, **settings):
Plugin.__init__ (self, **settings)
self.query=query
- self.query_uuid = query.query_uuid if query else None
- print "called univbris topo plugin"
+ self.query_uuid = query.query_uuid if query else None
+ logger.info("called univbris topo plugin")
def template_file (self):
- try:
- return "univbris_topology.html"
- except:
- print "error template"
+ try:
+ return "univbris_topology.html"
+ except Exception as e :
+ logger.error("error template {}".format(e))
def requirements (self):
reqs = {
- 'js_files' : [ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
- "js/manifold.js", "js/manifold-query.js",
- "js/unfold-helper.js",
+ 'js_files' : [
+ "js/spin-presets.js", "js/spin.min.js", "js/jquery.spin.js",
+ "js/manifold.js", "js/manifold-query.js",
+ "js/unfold-helper.js",
'js/univbristopo.js', 'js/d3.v2.min.js','js/tooltip.topology.js',
],
'css_files': [
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class UnivbrisVtam (Plugin):
def __init__ (self, query=None, query_all=None, sync_query=None,
checkboxes=False, columns=None,
datatables_options={}, **settings):
Plugin.__init__ (self, **settings)
self.query = query
- self.query_uuid = query.query_uuid if query else None
+ self.query_uuid = query.query_uuid if query else None
# Until we have a proper way to access queries in Python
self.query_all = query_all
self.query_all_uuid = query_all.query_uuid if query_all else None
- self.sync_query_uuid = sync_query.query_uuid if sync_query else None
+ self.sync_query_uuid = sync_query.query_uuid if sync_query else None
self.checkboxes = checkboxes
# XXX We need to have some hidden columns until we properly handle dynamic queries
if columns is not None:
self.columns=columns
self.hidden_columns = []
elif self.query:
- self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete'])
- #replace production
+ self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete'])
+ #replace production
#self.columns = self.query.fields
if query_all:
#replace production
- self.hidden_columns = []
- # We need a list because sets are not JSON-serializable
+ self.hidden_columns = []
+ # We need a list because sets are not JSON-serializable
#self.hidden_columns = #list(self.query_all.fields - self.query.fields)
else:
self.hidden_columns = []
self.columns = []
self.hidden_columns = []
- self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete'])
+ self.columns = list (['Testbed', 'Virtualization Server', 'VM name', 'Delete'])
self.init_key=init_key
self.datatables_options=datatables_options
# if checkboxes were required, we tell datatables about this column's type
if self.checkboxes:
# we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
if 'aoColumns' in self.datatables_options:
- print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded'
+ logger.warning('WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded')
del self.datatables_options['aoColumns']
# set aoColumnDefs in datatables_options - might already have stuff in there
aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
# expose this so we can mention the backend URL on the welcome page
def default_env (self):
return {
- 'MANIFOLD_URL':ConfigEngine().manifold_url(),
- }
+ 'MANIFOLD_URL':ConfigEngine().manifold_url(),
+ }
def post (self,request):
env = self.default_env()
env['theme'] = self.theme
env['section'] = "About"
- env['username']=the_user(request)
+ env['username'] = the_user(request)
env['topmenu_items'] = topmenu_items(None, request)
- if state: env['state'] = state
- elif not env['username']: env['state'] = None
+ if state:
+ env['state'] = state
+ elif not env['username']:
+ env['state'] = None
# use one or two columns for the layout - not logged in users will see the login prompt
- env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
-
+ env['layout_1_or_2'] = "layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
return render_to_response(self.template, env, context_instance=RequestContext(request))
class Account:
def __init__ (self, platform_id, user_id):
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config').filter_by('platform_id', '==', platform_id).filter_by('user_id', '==', user_id)
+ account_query = Query().get('local:account')\
+ .select('user_id','platform_id','auth_type','config')\
+ .filter_by('platform_id', '==', platform_id)\
+ .filter_by('user_id', '==', user_id)
- account_details = execute_query(self.request, account_query)
+ account_details = execute_query(self.request, account_query)
self.user_id = account_details['user_id']
self.platform_id = account_details['platform_id']
self.auth_type = account_details['auth_type']
self.config = account_details['config']
- account_config = json.loads(account_details['config'])
+ account_config = json.loads(account_details['config'])
self.usr_hrn = account_config.get('user_hrn',None)
self.pub_key = account_config.get('user_public_key',None)
-from unfold.loginrequired import LoginRequiredAutoLogoutView
-#
-#
-from manifold.core.query import Query
-from manifoldapi.manifoldapi import execute_query
-from portal.actions import manifold_update_user, manifold_update_account, manifold_add_account, manifold_delete_account, sfa_update_user, sfa_get_user, clear_user_creds
#
-from unfold.page import Page
-from ui.topmenu import topmenu_items_live, the_user
+import json, os, re, itertools, time
+from OpenSSL import crypto
+from Crypto.PublicKey import RSA
+
#
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
-from myslice.configengine import ConfigEngine
-from myslice.theme import ThemeView
+#
+from manifold.core.query import Query
+from manifoldapi.manifoldapi import execute_query
+
+from unfold.loginrequired import LoginRequiredAutoLogoutView
+from unfold.page import Page
+from ui.topmenu import topmenu_items_live, the_user
+from portal.actions import (
+ manifold_update_user, manifold_update_account, manifold_add_account,
+ manifold_delete_account, sfa_update_user, sfa_get_user, clear_user_creds, get_myslice_account, get_myslice_platform, get_registry_url, get_jfed_identity )
from portal.account import Account, get_expiration
-#
-import json, os, re, itertools, time
-from OpenSSL import crypto
-from Crypto.PublicKey import RSA
+
+from myslice.settings import logger
+from myslice.configengine import ConfigEngine
+from myslice.theme import ThemeView
# requires login
class AccountView(LoginRequiredAutoLogoutView, ThemeView):
metadata = page.get_metadata()
page.expose_js_metadata()
- page.add_js_files ( [ "js/jquery.validate.js", "js/my_account.register.js", "js/my_account.edit_profile.js","js/jquery-ui.js" ] )
+ page.add_js_files ( [ "js/jquery.validate.js", "js/my_account.register.js",
+ "js/my_account.edit_profile.js","js/jquery-ui.js" ] )
page.add_css_files ( [ "css/onelab.css", "css/account_view.css","css/plugin.css" ] )
# Execute a Query to delegate credentials if necessary
pub_key_list.append(account_pub_key)
user_status_list.append(user_status)
# combining 5 lists into 1 [to render in the template]
- principal_acc_list = [{'platform_name': t[0], 'account_type': t[1], 'delegation_type': t[2], 'usr_hrn':t[3], 'usr_pubkey':t[4], 'user_status':t[5],}
- for t in zip(platform_name_list, account_type_list, delegation_type_list, usr_hrn_list, pub_key_list, user_status_list)]
+ principal_acc_list = [
+ {'platform_name' : pn, 'account_type' : at,
+ 'delegation_type' : dt, 'usr_hrn' : uh,
+ 'usr_pubkey' : up, 'user_status' : us,}
+ for pn, at, dt, uh, up, us in zip(platform_name_list, account_type_list, delegation_type_list,
+ usr_hrn_list, pub_key_list, user_status_list)
+ ]
# to hide private key row if it doesn't exist
if 'myslice' in platform_detail['platform']:
account_config = json.loads(account_detail['config'])
platform_list = [{'platform_no_access': t[0]}
for t in itertools.izip_longest(total_platform_list)]
-
- ## check user is pi or not
- # platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- # account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- # platform_details = execute_query(self.request, platform_query)
- # account_details = execute_query(self.request, account_query)
- # for platform_detail in platform_details:
- # for account_detail in account_details:
- # if platform_detail['platform_id'] == account_detail['platform_id']:
- # if 'config' in account_detail and account_detail['config'] is not '':
- # account_config = json.loads(account_detail['config'])
- # if 'myslice' in platform_detail['platform']:
- # acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- # assigning values
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
-
# check if the user has creds or not
if acc_user_cred == {} or acc_user_cred == 'N/A':
user_cred = 'no_creds'
context['ref_acc'] = ref_acc_list
context['platform_list'] = platform_list
context['my_users'] = my_users
- context['pi'] = pi
context['user_cred'] = user_cred
context['my_slices'] = my_slices
context['my_auths'] = my_auths
context['theme'] = self.theme
context['section'] = "User account"
# context ['firstname'] = config['firstname']
+
+ context['request'] = self.request
+
prelude_env = page.prelude_env()
context.update(prelude_env)
return context
@login_required
-def get_myslice_platform(request):
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled','config').filter_by('platform','==','myslice')
- platform_details = execute_query(request, platform_query)
- for platform_detail in platform_details:
- return platform_detail
-
-@login_required
-def get_myslice_account(request):
- platform_myslice = get_myslice_platform(request)
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config').filter_by('platform_id','==',platform_myslice['platform_id'])
- account_details = execute_query(request, account_query)
- for account_detail in account_details:
- return account_detail
-
-@login_required
-#my_acc form value processing
def account_process(request):
from sfa.trust.credential import Credential
from sfa.trust.certificate import Keypair
if user_email == request.user.email:
authorize_query = True
else:
- print "SECURITY: %s tried to update %s" % (user_email, request.user.email)
+ logger.error("SECURITY: {} tried to update {}".format(user_email, request.user.email))
messages.error(request, 'You are not authorized to modify another user.')
return HttpResponseRedirect("/portal/account/")
- except Exception,e:
- print "Exception = %s" % e
+ except Exception as e:
+ logger.error("exception in account_process {}".format(e))
for account_detail in account_details:
for platform_detail in platform_details:
# Add reference account to the platforms
- if 'add_'+platform_detail['platform'] in request.POST or request.POST['button_value'] == 'add_'+platform_detail['platform']:
+ if 'add_'+platform_detail['platform'] in request.POST\
+ or request.POST['button_value'] == 'add_'+platform_detail['platform']:
platform_id = platform_detail['platform_id']
- user_params = {'platform_id': platform_id, 'user_id': user_id, 'auth_type': "reference", 'config': '{"reference_platform": "myslice"}'}
+ user_params = {'platform_id': platform_id, 'user_id': user_id,
+ 'auth_type': "reference",
+ 'config': '{"reference_platform": "myslice"}'}
manifold_add_account(request,user_params)
messages.info(request, 'Reference Account is added to the selected platform successfully!')
return HttpResponseRedirect("/portal/account/")
# Delete reference account from the platforms
- if 'delete_'+platform_detail['platform'] in request.POST or request.POST['button_value'] == 'delete_'+platform_detail['platform']:
+ if 'delete_'+platform_detail['platform'] in request.POST\
+ or request.POST['button_value'] == 'delete_'+platform_detail['platform']:
platform_id = platform_detail['platform_id']
user_params = {'user_id':user_id}
manifold_delete_account(request,platform_id, user_id, user_params)
response['Content-Disposition'] = 'attachment; filename="auth_credential.txt"'
return response
-
+ account_detail = get_myslice_account(request)
if 'submit_name' in request.POST:
edited_first_name = request.POST['fname']
updated_config = json.dumps(config)
user_params = {'config': updated_config}
else: # it's needed if the config is empty
- user_config['config']= '{"firstname":"' + edited_first_name + '", "lastname":"'+ edited_last_name + '", "authority": "Unknown Authority"}'
+ user_config['config'] = '{{"firstname":"{}", "lastname":"{}", "authority": "Unknown Authority"}}'\
+ .format(edited_first_name, edited_last_name)
user_params = {'config': user_config['config']}
# updating config local:user in manifold
manifold_update_user(request, request.user.email,user_params)
for user_pass in user_details:
user_pass['password'] = edited_password
#updating password in local:user
- user_params = { 'password': user_pass['password']}
- manifold_update_user(request,request.user.email,user_params)
+ user_params = { 'password' : user_pass['password']}
+ manifold_update_user(request, request.user.email, user_params)
# return HttpResponse('Success: Password Changed!!')
- messages.success(request, 'Sucess: Password Updated.')
+ messages.success(request, 'Success: Password Updated.')
return HttpResponseRedirect("/portal/account/")
# XXX TODO: Factorize with portal/registrationview.py
# XXX TODO: Factorize with portal/joinview.py
elif 'generate' in request.POST:
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- private = RSA.generate(1024)
- private_key = json.dumps(private.exportKey())
- public = private.publickey()
- public_key = json.dumps(public.exportKey(format='OpenSSH'))
- # updating manifold local:account table
- account_config = json.loads(account_detail['config'])
- # preserving user_hrn
- user_hrn = account_config.get('user_hrn','N/A')
- keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}'
- #updated_config = json.dumps(account_config)
- # updating manifold
- #user_params = { 'config': keypair, 'auth_type':'managed'}
- #manifold_update_account(request, user_id, user_params)
- # updating sfa
- public_key = public_key.replace('"', '');
- user_pub_key = {'keys': public_key}
-
- sfa_update_user(request, user_hrn, user_pub_key)
- result_sfa_user = sfa_get_user(request, user_hrn, public_key)
- try:
- if 'keys' in result_sfa_user and result_sfa_user['keys'][0] == public_key:
- # updating manifold
- updated_config = json.dumps(account_config)
- user_params = { 'config': keypair, 'auth_type':'managed'}
- manifold_update_account(request, user_id, user_params)
- messages.success(request, 'Sucess: New Keypair Generated! Delegation of your credentials will be automatic.')
- else:
- raise Exception,"Keys are not matching"
- except Exception, e:
- messages.error(request, 'Error: An error occured during the update of your public key at the Registry, or your public key is not matching the one stored.')
- print "Exception in accountview ", e
- return HttpResponseRedirect("/portal/account/")
- else:
+ try:
+ private = RSA.generate(1024)
+ private_key = json.dumps(private.exportKey())
+ public = private.publickey()
+ public_key = json.dumps(public.exportKey(format='OpenSSH'))
+ # updating manifold local:account table
+ account_config = json.loads(account_detail['config'])
+ # preserving user_hrn
+ user_hrn = account_config.get('user_hrn','N/A')
+ keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}'
+ #updated_config = json.dumps(account_config)
+ # updating manifold
+ #user_params = { 'config': keypair, 'auth_type':'managed'}
+ #manifold_update_account(request, user_id, user_params)
+ # updating sfa
+ public_key = public_key.replace('"', '');
+ user_pub_key = {'keys': public_key}
+
+ sfa_update_user(request, user_hrn, user_pub_key)
+ result_sfa_user = sfa_get_user(request, user_hrn, public_key)
+ try:
+ if 'keys' in result_sfa_user and result_sfa_user['keys'][0] == public_key:
+ # updating manifold
+ updated_config = json.dumps(account_config)
+ user_params = { 'config': keypair, 'auth_type':'managed'}
+ manifold_update_account(request, user_id, user_params)
+ messages.success(request, 'Sucess: New Keypair Generated! Delegation of your credentials will be automatic.')
+ else:
+ raise Exception,"Keys are not matching"
+ except Exception as e:
+ messages.error(request, 'Error: An error occured during the update of your public key at the Registry, or your public key is not matching the one stored.')
+ logger.error("Exception in accountview {}".format(e))
+ return HttpResponseRedirect("/portal/account/")
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
elif 'upload_key' in request.POST:
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- up_file = request.FILES['pubkey']
- file_content = up_file.read()
- file_name = up_file.name
- file_extension = os.path.splitext(file_name)[1]
- allowed_extension = ['.pub','.txt']
- if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
- account_config = json.loads(account_detail['config'])
- # preserving user_hrn
- user_hrn = account_config.get('user_hrn','N/A')
- file_content = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}'
- #file_content = re.sub("\r", "", file_content)
- #file_content = re.sub("\n", "\\n",file_content)
- file_content = ''.join(file_content.split())
- #update manifold local:account table
- user_params = { 'config': file_content, 'auth_type':'user'}
- manifold_update_account(request, user_id, user_params)
- # updating sfa
- user_pub_key = {'keys': file_content}
- sfa_update_user(request, user_hrn, user_pub_key)
- messages.success(request, 'Publickey uploaded! Please delegate your credentials using SFA: http://trac.myslice.info/wiki/DelegatingCredentials')
- return HttpResponseRedirect("/portal/account/")
- else:
- messages.error(request, 'RSA key error: Please upload a valid RSA public key [.txt or .pub].')
- return HttpResponseRedirect("/portal/account/")
- else:
+ try:
+ up_file = request.FILES['pubkey']
+ file_content = up_file.read()
+ file_name = up_file.name
+ file_extension = os.path.splitext(file_name)[1]
+ allowed_extension = ['.pub','.txt']
+ if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
+ account_config = json.loads(account_detail['config'])
+ # preserving user_hrn
+ user_hrn = account_config.get('user_hrn','N/A')
+ file_content = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}'
+ #file_content = re.sub("\r", "", file_content)
+ #file_content = re.sub("\n", "\\n",file_content)
+ file_content = ''.join(file_content.split())
+ #update manifold local:account table
+ user_params = { 'config': file_content, 'auth_type':'user'}
+ manifold_update_account(request, user_id, user_params)
+ # updating sfa
+ user_pub_key = {'keys': file_content}
+ sfa_update_user(request, user_hrn, user_pub_key)
+ messages.success(request, 'Publickey uploaded! Please delegate your credentials using SFA: http://trac.myslice.info/wiki/DelegatingCredentials')
+ return HttpResponseRedirect("/portal/account/")
+ else:
+ messages.error(request, 'RSA key error: Please upload a valid RSA public key [.txt or .pub].')
+ return HttpResponseRedirect("/portal/account/")
+
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
elif 'dl_pubkey' in request.POST or request.POST['button_value'] == 'dl_pubkey':
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- account_config = json.loads(account_detail['config'])
- public_key = account_config['user_public_key']
- response = HttpResponse(public_key, content_type='text/plain')
- response['Content-Disposition'] = 'attachment; filename="pubkey.txt"'
- return response
- break
- else:
+ try:
+ account_config = json.loads(account_detail['config'])
+ public_key = account_config['user_public_key']
+ response = HttpResponse(public_key, content_type='text/plain')
+ response['Content-Disposition'] = 'attachment; filename="pubkey.txt"'
+ return response
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
elif 'dl_pkey' in request.POST or request.POST['button_value'] == 'dl_pkey':
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- account_config = json.loads(account_detail['config'])
- if 'user_private_key' in account_config:
- private_key = account_config['user_private_key']
- response = HttpResponse(private_key, content_type='text/plain')
- response['Content-Disposition'] = 'attachment; filename="privkey.txt"'
- return response
- else:
- messages.error(request, 'Download error: Private key is not stored in the server')
- return HttpResponseRedirect("/portal/account/")
+ try:
+ account_config = json.loads(account_detail['config'])
+ if 'user_private_key' in account_config:
+ private_key = account_config['user_private_key']
+ response = HttpResponse(private_key, content_type='text/plain')
+ response['Content-Disposition'] = 'attachment; filename="privkey.txt"'
+ return response
+ else:
+ messages.error(request, 'Download error: Private key is not stored in the server')
+ return HttpResponseRedirect("/portal/account/")
- else:
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
elif 'delete' in request.POST or request.POST['button_value'] == 'delete':
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- account_config = json.loads(account_detail['config'])
- if 'user_private_key' in account_config:
- for key in account_config.keys():
- if key == 'user_private_key':
- del account_config[key]
-
- updated_config = json.dumps(account_config)
- user_params = { 'config': updated_config, 'auth_type':'user'}
- manifold_update_account(request, user_id, user_params)
- messages.success(request, 'Private Key deleted. You need to delegate credentials manually once it expires.')
- messages.success(request, 'Once your credentials expire, Please delegate manually using SFA: http://trac.myslice.info/wiki/DelegatingCredentials')
- return HttpResponseRedirect("/portal/account/")
- else:
- messages.error(request, 'Delete error: Private key is not stored in the server')
- return HttpResponseRedirect("/portal/account/")
-
- else:
+ try:
+ account_config = json.loads(account_detail['config'])
+ if 'user_private_key' in account_config:
+ for key in account_config.keys():
+ if key == 'user_private_key':
+ del account_config[key]
+
+ updated_config = json.dumps(account_config)
+ user_params = { 'config': updated_config, 'auth_type':'user'}
+ manifold_update_account(request, user_id, user_params)
+ messages.success(request, 'Private Key deleted. You need to delegate credentials manually once it expires.')
+ messages.success(request, 'Once your credentials expire, Please delegate manually using SFA: http://trac.myslice.info/wiki/DelegatingCredentials')
+ return HttpResponseRedirect("/portal/account/")
+ else:
+ messages.error(request, 'Delete error: Private key is not stored in the server')
+ return HttpResponseRedirect("/portal/account/")
+
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
# download identity for jfed
elif 'dl_identity' in request.POST or request.POST['button_value'] == 'dl_identity':
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'myslice' in platform_detail['platform']:
- account_config = json.loads(account_detail['config'])
- if 'user_private_key' in account_config:
- private_key = account_config['user_private_key']
- user_hrn = account_config.get('user_hrn','N/A')
- registry = 'http://sfa-fed4fire.pl.sophia.inria.fr:12345/'
- jfed_identity = user_hrn + '\n' + registry + '\n' + private_key
- response = HttpResponse(jfed_identity, content_type='text/plain')
- response['Content-Disposition'] = 'attachment; filename="jfed_identity.txt"'
- return response
- else:
- messages.error(request, 'Download error: Private key is not stored in the server')
- return HttpResponseRedirect("/portal/account/")
+ try:
+ jfed_identity = get_jfed_identity(request)
+ if jfed_identity is not None:
+ response = HttpResponse(jfed_identity, content_type='text/plain')
+ response['Content-Disposition'] = 'attachment; filename="jfed_identity.txt"'
+ return response
+ else:
+ messages.error(request, 'Download error: Private key is not stored in the server')
+ return HttpResponseRedirect("/portal/account/")
- else:
+ except Exception as e:
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
user_hrn = account_config.get('user_hrn','N/A')
t_user_hrn = user_hrn.split('.')
authority_hrn = t_user_hrn[0] + '.' + t_user_hrn[1]
+ registry = get_registry_url(request)
import socket
hostname = socket.gethostbyaddr(socket.gethostname())[0]
- registry = platform_config.get('registry','N/A')
admin_user = platform_config.get('user','N/A')
- if 'localhost' in registry:
- port = registry.split(':')[-1:][0]
- registry = "http://" + hostname +':'+ port
manifold_host = ConfigEngine().manifold_url()
if 'localhost' in manifold_host:
manifold_host = manifold_host.replace('localhost',hostname)
messages.success(request, 'All Credentials cleared')
else:
messages.error(request, 'Delete error: Credentials are not stored in the server')
- except Exception,e:
- print "Exception in accountview.py in clear_user_creds %s" % e
+ except Exception as e:
+ logger.error("Exception in accountview.py in clear_user_creds {}".format(e))
messages.error(request, 'Account error: You need an account in myslice platform to perform this action')
return HttpResponseRedirect("/portal/account/")
from myslice.theme import ThemeView
from myslice.configengine import ConfigEngine
-
+from myslice.settings import logger
theme = ThemeView()
# XXX tmp sfa dependency, should be moved to SFA gateway
#from sfa.util.xrn import Xrn
+def get_myslice_platform(request):
+ platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled','config').filter_by('platform','==','myslice')
+ platform_details = execute_query(request, platform_query)
+ if isinstance(platform_details,list):
+ for platform_detail in platform_details:
+ return platform_detail
+ else:
+ return None
+
+def get_myslice_account(request):
+ try:
+ platform_myslice = get_myslice_platform(request)
+ account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config').filter_by('platform_id','==',platform_myslice['platform_id'])
+ account_details = execute_query(request, account_query)
+ for account_detail in account_details:
+ return account_detail
+ except Exception as e:
+ print e
+ return None
+
+def get_registry_url(request):
+ try:
+ platform_detail = get_myslice_platform(request)
+ platform_config = json.loads(platform_detail['config'])
+ import socket
+ hostname = socket.gethostbyaddr(socket.gethostname())[0]
+ registry = platform_config.get('registry','N/A')
+ if 'localhost' in registry:
+ port = registry.split(':')[-1:][0]
+ registry = "http://" + hostname +':'+ port
+ return registry
+ except Exception as e:
+ print e
+ return None
+
+def get_jfed_identity(request):
+ try:
+ account_detail = get_myslice_account(request)
+ account_config = json.loads(account_detail['config'])
+ if 'user_private_key' in account_config:
+ private_key = account_config['user_private_key']
+ user_hrn = account_config.get('user_hrn','N/A')
+ platform_detail = get_myslice_platform(request)
+ registry = get_registry_url(request)
+ #registry = 'http://sfa-fed4fire.pl.sophia.inria.fr:12345/'
+ jfed_identity = user_hrn + '\n' + registry + '\n' + private_key
+ return jfed_identity
+ else:
+ return None
+ except Exception as e:
+ print e
+ return None
# Get the list of pis in a given authority
def authority_get_pis(request, authority_hrn):
pi_status = True
return pi_status
- except Exception,e:
- print "Exception in actions.py in authority_check_pis %s" % e
+ except Exception as e:
+ logger.error("Exception in actions.py in authority_check_pis {}".format(e))
return None
-def authority_add_pis(request, authority_hrn,user_hrn):
+def authority_add_pis(request, authority_hrn, user_hrn):
try:
+ pi_list = []
# getting pis of the authority of the user
pis = authority_get_pis (request, authority_hrn)
for pi in pis:
query = Query.update('myslice:authority').filter_by('authority_hrn', '==', authority_hrn).set({'pi_users':pi_list})
results = execute_query(request,query)
newpis = authority_get_pis (request, authority_hrn)
- return newpis
- except Exception,e:
- print "Exception in actions.py in authority_add_pis %s" % e
- return None
+
+ # Add the user to the slices of the project he/she joined
+ if len(authority_hrn.split('.')) > 2:
+ # this authority_hrn is a project
+ query_slices = Query.get('myslice:slice').filter_by('parent_authority', '==', authority_hrn).select('slice_hrn')
+ results_slices = execute_query(request,query_slices)
+ for s in results_slices:
+ sfa_add_user_to_slice(request, user_hrn, s['slice_hrn'])
+ # Clear Credentials of the user
+ user_email = get_user_email(request, user_hrn)
+ clear_user_creds(request, user_email)
+ return newpis
+ except Exception as e:
+ logger.error("Exception in actions.py in authority_add_pis {}".format(e))
+ raise Exception, "Exception in actions.py in authority_add_pis {}".format(e)
-def authority_remove_pis(request, authority_hrn,user_hrn):
+def authority_remove_pis(request, authority_hrn, user_hrn):
try:
+ pi_list = []
# getting pis of the authority of the user
pis = authority_get_pis (request, authority_hrn)
for pi in pis:
pi_list = pi['pi_users']
updated_pi_list = pi_list.remove(user_hrn)
- query = Query.update('authority').filter_by('authority_hrn', '==', authority_hrn).set({'pi_users':pi_list})
+ query = Query.update('myslice:authority').filter_by('authority_hrn', '==', authority_hrn).set({'pi_users':pi_list})
results = execute_query(request,query)
newpis = authority_get_pis (request, authority_hrn)
+
+ # Remove the user from the slices of the project he/she left
+ if len(authority_hrn.split('.')) > 2:
+ # this authority_hrn is a project
+ query_slices = Query.get('myslice:slice').filter_by('parent_authority', '==', authority_hrn).select('slice_hrn')
+ results_slices = execute_query(request,query_slices)
+ for s in results_slices:
+ print 'remove from slice %s' % s
+ sfa_remove_user_from_slice(request, user_hrn, s['slice_hrn'])
+
+ # Clear Credentials of the user
+ user_email = get_user_email(request, user_hrn)
+ clear_user_creds(request, user_email)
+
return newpis
- except Exception,e:
- print "Exception in actions.py in authority_remove_pis %s" % e
- return None
+ except Exception as e:
+ logger.error("Exception in actions.py in authority_remove_pis {}".format(e))
+ raise Exception, "Exception in actions.py in authority_remove_pis {}".format(e)
def authority_get_pi_emails(request, authority_hrn):
pi_users = authority_get_pis(request,authority_hrn)
- print "pi_users = %s" % pi_users
+ logger.info("pi_users = %s" % pi_users)
if any(pi['pi_users'] == None or not pi['pi_users'] for pi in pi_users):
#theme.template_name = 'email_default_recipients.txt'
results = execute_admin_query(request, query)
return [result['user_email'] for result in results]
+def get_user_email(request, user_hrn):
+ query = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn).select('user_email')
+ results = execute_admin_query(request, query)
+ return results[0]['user_email']
+
#clear user credentials
def clear_user_creds(request, user_email):
try:
else:
return None
- except Exception,e:
- print "Exception in actions.py in clear_user_creds %s" % e
+ except Exception as e:
+ logger.error("Exception in actions.py in clear_user_creds {}".format(e))
return None
def is_pi(wsgi_request, user_hrn, authority_hrn):
# authorities from user where user_hrn == "ple.upmc.jordan_auge"
- print "#### actions.py is_pi authority_hrn = ", authority_hrn
+ logger.debug("#### actions.py is_pi authority_hrn = {}".format(authority_hrn))
try:
# CACHE PB with fields
page = Page(wsgi_request)
query = Query().get('myslice:user').select(user_fields).filter_by('user_hrn','==',user_hrn)
#query = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities')
results = execute_query(wsgi_request, query)
- #print "is_pi results = ", results
for user_detail in results:
if authority_hrn in user_detail['pi_authorities']:
return True
- except Exception,e:
- print "Exception in actions.py in is_pi %s" % e
+ except Exception as e:
+ logger.error("Exception in actions.py in is_pi {}".format(e))
return False
# SFA get record
# REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
query = Query.create('myslice:authority').set(authority_params).select('authority_hrn')
results = execute_query(request, query)
- print "sfa_add_auth results=",results
+ logger.info("sfa_add_auth results={}".format(results))
if not results:
raise Exception, "Could not create %s. Already exists ?" % authority_params['hrn']
return results
-def sfa_add_user_to_slice(request, user_hrn, slice_params):
-# UPDATE myslice:slice SET researcher=['ple.upmc.jordan_auge','ple.inria.thierry_parmentelat','ple.upmc.loic_baron','ple.upmc.ciro_scognamiglio','ple.upmc.mohammed-yasin_rahman','ple.upmc.azerty'] where slice_hrn=='ple.upmc.myslicedemo'
+def sfa_add_user_to_slice(request, user_hrn, slice_hrn):
+# UPDATE myslice:slice SET users = ['fed4fire.upmc.loic_baron', 'fed4fire.upmc.mohammed-yasin_rahman', 'fed4fire.upmc.demo'] WHERE slice_hrn == 'fed4fire.upmc.project_y.test_under' SELECT slice_hrn, slice_urn
+ # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+ query_current_users = Query.get('myslice:slice').select('users').filter_by('slice_hrn','==',slice_hrn)
+ results_current_users = execute_query(request, query_current_users)
+ current_users = list()
+ for r in results_current_users:
+ current_users.extend(r['users'])
+ users = list(set([user_hrn]) | set(current_users))
+
+ # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+ query = Query.update('myslice:slice').filter_by('slice_hrn', '==', slice_hrn).set({'users':users}).select('slice_hrn')
+ results = execute_query(request, query)
+# Also possible but not supported yet
+# UPDATE myslice:user SET slice=['ple.upmc.agent','ple.upmc.myslicedemo','ple.upmc.tophat'] where user_hrn=='ple.upmc.azerty'
+ if not results:
+ raise Exception, "Could not add user %s to slice %s" % (user_hrn, slice_hrn)
+ return results
+def sfa_remove_user_from_slice(request, user_hrn, slice_hrn):
+# UPDATE myslice:slice SET users = ['fed4fire.upmc.loic_baron', 'fed4fire.upmc.demo'] WHERE slice_hrn == 'fed4fire.upmc.project_y.test_under' SELECT slice_hrn, slice_urn
# REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
- query_current_users = Query.get('myslice:slice').select('user').filter_by('slice_hrn','==',slice_params['hrn'])
+ query_current_users = Query.get('myslice:slice').select('users').filter_by('slice_hrn','==',slice_hrn)
results_current_users = execute_query(request, query_current_users)
- slice_params['researcher'] = slice_params['researcher'] | results_current_users
+ current_users = list()
+ for r in results_current_users:
+ current_users.extend(r['users'])
+ if user_hrn in current_users:
+ current_users.remove(user_hrn)
# REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
- query = Query.update('myslice:slice').filter_by('user_hrn', '==', user_hrn).set(slice_params).select('slice_hrn')
+ query = Query.update('myslice:slice').filter_by('slice_hrn', '==', slice_hrn).set({'users':current_users}).select('slice_hrn')
results = execute_query(request, query)
# Also possible but not supported yet
# UPDATE myslice:user SET slice=['ple.upmc.agent','ple.upmc.myslicedemo','ple.upmc.tophat'] where user_hrn=='ple.upmc.azerty'
if not results:
- raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
+ raise Exception, "Could not remove user %s to slice %s" % (user_hrn, slice_hrn)
return results
# Propose hrn
return request
def make_requests(pending_users, pending_slices, pending_authorities, pending_projects, pending_joins):
- print "$$$$$$$$$$$$$$$ make_request"
+ logger.info("$$$$$$$$$$$$$$$ make_request")
requests = []
for user in pending_users:
requests.append(make_request_user(user))
return requests
def get_request_by_id(ids):
- print "$$$$$$$$$$$$$$$$ get_request_by_id"
+ logger.info("$$$$$$$$$$$$$$$$ get_request_by_id")
sorted_ids = { 'user': [], 'slice': [], 'authority': [], 'project': [], 'join': [] }
for type__id in ids:
type, id = type__id.split('__')
return make_requests(pending_users, pending_slices, pending_authorities, pending_projects, pending_joins)
def get_requests(authority_hrns=None):
- print "$$$$$$$$$$$$$ get_request_by_authority auth_hrns = ", authority_hrns
+ logger.info("$$$$$$$$$$$$$ get_request_by_authority auth_hrns = {}".format(authority_hrns))
if not authority_hrns:
## get those pending users who have confirmed their emails
pending_users = PendingUser.objects.filter(status__iexact = 'True')
# slice : number of nodes, type of nodes, purpose
request_status = {}
-
- if request['type'] == 'user':
-
- try:
+ try:
+ if request['type'] == 'user':
create_user(wsgi_request, request)
request_status['SFA user'] = {'status': True }
+ u = PendingUser.objects.get(id=request['id'])
+ ctx = {
+ 'first_name' : u.first_name,
+ 'last_name' : u.last_name,
+ 'email' : u.email,
+ }
+ user_email = u.email
+
PendingUser.objects.get(id=request['id']).delete()
- except Exception, e:
- request_status['SFA user'] = {'status': False, 'description': str(e)}
-
-# user_params = {'status':2}
-# manifold_update_user(request, request['email'], user_params)
-
- # MANIFOLD user should be added beforehand, during registration
- #try:
- # manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
- # # XXX # manifold_add_user(manifold_user_params)
- # request_status['MySlice user'] = {'status': True }
- #except Exception, e:
- # request_status['MySlice user'] = {'status': False, 'description': str(e)}
-
- # XXX
- #manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS }
- #manifold_add_account(manifold_account_params)
- #request_status['MySlice testbed accounts'] = {'status': False }
-
- elif request['type'] == 'slice':
- try:
+
+ elif request['type'] == 'slice':
create_slice(wsgi_request, request)
request_status['SFA slice'] = {'status': True }
+ s = PendingSlice.objects.get(id=request['id'])
+ ctx = {
+ 'slice_name' : s.slice_name,
+ 'url' : s.url,
+ 'purpose' : s.purpose,
+ 'email' : s.email,
+ }
+ user_email = s.email
+
PendingSlice.objects.get(id=request['id']).delete()
# Clear user's Credentials
sfa_user = sfa_get_user(wsgi_request, request['user_hrn'])
clear_user_creds(wsgi_request,sfa_user['user_email'])
- except Exception, e:
- request_status['SFA slice'] = {'status': False, 'description': str(e)}
-
- elif request['type'] == 'authority':
- try:
+ elif request['type'] == 'authority':
#hrn = "%s.%s" % (request['authority_hrn'], request['site_authority'])
hrn = request['site_authority']
# XXX tmp sfa dependency
#'pi' : None,
#'enabled' : True
}
- print "ADD Authority"
+ logger.info("ADD Authority")
sfa_add_authority(wsgi_request, sfa_authority_params)
request_status['SFA authority'] = {'status': True }
- PendingAuthority.objects.get(id=request['id']).delete()
+ a = PendingAuthority.objects.get(id=request['id'])
+ ctx = {
+ 'site_name' : a.site_name,
+ 'short_name' : a.short_name,
+ 'url' : a.url,
+ 'city' : a.city,
+ 'country' : a.country,
+ 'portal_url' : a.current_site,
+ }
+ user_email = a.email
- except Exception, e:
- request_status['SFA authority'] = {'status': False, 'description': str(e)}
+ PendingAuthority.objects.get(id=request['id']).delete()
+
+ # Clear Admin Cache as it is used to display the list of authorities in Registration page
+ query = Query.update('myslice:authority').filter_by('authority_hrn', '==', sfa_authority_params['authority_hrn']).set({'authority_hrn':sfa_authority_params['authority_hrn']}).select('authority_hrn')
+ res = execute_admin_query(request, query)
- elif request['type'] == 'project':
- try:
+ elif request['type'] == 'project':
hrn = request['authority_hrn'] + '.' + request['project_name']
# Only hrn is required for Manifold Query
'authority_hrn' : hrn
}
sfa_add_authority(wsgi_request, sfa_authority_params)
- request_status['SFA project'] = {'status': True }
- PendingProject.objects.get(id=request['id']).delete()
# Add user as a PI of the project
+ # Clear user's Credentials
authority_add_pis(wsgi_request, hrn , request['user_hrn'])
- # Clear user's Credentials
- #sfa_user = sfa_get_user(wsgi_request, request['user_hrn'])
- clear_user_creds(wsgi_request,request['email'])
+ request_status['SFA project'] = {'status': True }
+ p = PendingProject.objects.get(id=request['id'])
+ ctx = {
+ 'project_name' : p.project_name,
+ 'authority_hrn' : p.authority_hrn,
+ 'email' : p.email,
+ 'purpose' : p.purpose,
+ }
+ user_email = p.email
+
+ PendingProject.objects.get(id=request['id']).delete()
+
+ # Clear Admin Cache as it is used to display the list of projects in Slice request page
+ query = Query.update('myslice:authority').filter_by('authority_hrn', '==', sfa_authority_params['authority_hrn']).set({'authority_hrn':sfa_authority_params['authority_hrn']}).select('authority_hrn')
+ res = execute_admin_query(request, query)
- except Exception, e:
- request_status['SFA project'] = {'status': False, 'description': str(e)}
- elif request['type'] == 'join':
- try:
+ elif request['type'] == 'join':
# Add user as a PI of the project
+ # Clear user's Credentials
authority_add_pis(wsgi_request, request['authority_hrn'] , request['user_hrn'])
request_status['SFA join'] = {'status': True }
- PendingJoin.objects.get(id=request['id']).delete()
+ j = PendingJoin.objects.get(id=request['id'])
+ ctx = {
+ 'project_name' : j.project_name,
+ 'authority_hrn' : j.authority_hrn,
+ 'email' : j.email,
+ 'user_hrn' : j.user_hrn,
+ }
+ user_email = j.email
- # Clear user's Credentials
- clear_user_creds(wsgi_request,request['email'])
+ PendingJoin.objects.get(id=request['id']).delete()
+ else:
+ raise Exception, 'unknown type of request %s' % request['type']
+ # XXX Remove from Pendings in database
- except Exception, e:
- request_status['SFA join'] = {'status': False, 'description': str(e)+' - '+str(request)}
- else:
- request_status['other'] = {'status': False, 'description': 'unknown type of request'}
- # XXX Remove from Pendings in database
+ send_status_email(ctx, user_email, request['type'], 'validated')
+ except Exception, e:
+ request_status['SFA '+request['type']] = {'status': False, 'description': str(e)}
status['%s__%s' % (request['type'], request['id'])] = request_status
ids = filter(None, kwargs['id'].split('/'))
status = portal_validate_request(request, ids)
json_answer = json.dumps(status)
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
def reject_action(request, **kwargs):
ids = filter(None, kwargs['id'].split('/'))
status = portal_reject_request(request, ids)
json_answer = json.dumps(status)
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
def portal_reject_request(wsgi_request, request_ids):
request_status = {}
- if request['type'] == 'user':
- try:
+ try:
+ if request['type'] == 'user':
request_status['SFA user'] = {'status': True }
# getting user email based on id
## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
ctx = {
'first_name' : first_name,
'last_name' : last_name,
+ 'email' : user_email,
'portal_url' : current_site,
}
- try:
- theme.template_name = 'user_request_denied.txt'
- text_content = render_to_string(theme.template, ctx)
- theme.template_name = 'user_request_denied.html'
- html_content = render_to_string(theme.template, ctx)
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, ctx)
- sender = sender.replace('\n', '')
-
- subject = 'User request denied.'
-
- msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
# removing from Django portal_pendinguser
PendingUser.objects.get(id=request['id']).delete()
-
+
delete_local_user(wsgi_request, user_email)
- except Exception, e:
- request_status['SFA authority'] = {'status': False, 'description': str(e)}
-
- elif request['type'] == 'slice':
- request_status['SFA slice'] = {'status': True }
-
- # getting user email based on id
- ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
- for user in PendingSlice.objects.raw('SELECT * FROM portal_pendingslice WHERE id = %s', [request['id']]):
- user_email= user.type_of_nodes # XXX type_of_nodes field contains the email [shd be renamed in DB]
- slice_name = user.slice_name
- purpose = user.purpose
- url = user.number_of_nodes
-
- ctx = {
- 'slice_name': slice_name,
- 'purpose': purpose,
- 'url': url,
- 'portal_url': current_site,
- }
- try:
- theme.template_name = 'slice_request_denied.txt'
- text_content = render_to_string(theme.template, ctx)
- theme.template_name = 'slice_request_denied.html'
- html_content = render_to_string(theme.template, ctx)
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, ctx)
- sender = sender.replace('\n', '')
-
- subject = 'Slice request denied.'
-
- msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
-
- PendingSlice.objects.get(id=request['id']).delete()
-
- elif request['type'] == 'authority':
- request_status['SFA authority'] = {'status': True }
-
- # getting user email based on id
- ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
- for user in PendingAuthority.objects.raw('SELECT * FROM portal_pendingauthority WHERE id = %s', [request['id']]):
- user_email= user.address_line1 # XXX address_line1 field contains the email [shd be renamed in DB]
- site_name = user.site_name
- city = user.address_city
- country = user.address_country
- short_name = user.site_abbreviated_name
- url = user.site_url
-
- ctx = {
- 'site_name': site_name,
- 'short_name': short_name,
- 'url': url,
- 'city': city,
- 'country': country,
- 'portal_url' : current_site,
- }
+
+ elif request['type'] == 'slice':
+ request_status['SFA slice'] = {'status': True }
+
+ # getting user email based on id
+ ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
+ for user in PendingSlice.objects.raw('SELECT * FROM portal_pendingslice WHERE id = %s', [request['id']]):
+ user_email= user.type_of_nodes # XXX type_of_nodes field contains the email [shd be renamed in DB]
+ slice_name = user.slice_name
+ purpose = user.purpose
+ url = user.number_of_nodes
+
+ ctx = {
+ 'slice_name': slice_name,
+ 'purpose': purpose,
+ 'url': url,
+ 'portal_url': current_site,
+ }
+
+ PendingSlice.objects.get(id=request['id']).delete()
+
+ elif request['type'] == 'authority':
+ request_status['SFA authority'] = {'status': True }
- try:
- theme.template_name = 'authority_request_denied.txt'
- text_content = render_to_string(theme.template, ctx)
- theme.template_name = 'authority_request_denied.html'
- html_content = render_to_string(theme.template, ctx)
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, ctx)
- sender = sender.replace('\n', '')
- subject = 'Authority request denied.'
- msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
-
- PendingAuthority.objects.get(id=request['id']).delete()
-
- # XXX TMP we should send an email to the user to inform him/her
- elif request['type'] == 'project':
- request_status['SFA project'] = {'status': True }
- PendingProject.objects.get(id=request['id']).delete()
-
- elif request['type'] == 'join':
- request_status['SFA join'] = {'status': True }
- PendingJoin.objects.get(id=request['id']).delete()
+ # getting user email based on id
+ ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
+ for user in PendingAuthority.objects.raw('SELECT * FROM portal_pendingauthority WHERE id = %s', [request['id']]):
+ user_email= user.address_line1 # XXX address_line1 field contains the email [shd be renamed in DB]
+ site_name = user.site_name
+ city = user.address_city
+ country = user.address_country
+ short_name = user.site_abbreviated_name
+ url = user.site_url
+
+ ctx = {
+ 'site_name': site_name,
+ 'short_name': short_name,
+ 'url': url,
+ 'city': city,
+ 'country': country,
+ 'portal_url' : current_site,
+ }
+
+ PendingAuthority.objects.get(id=request['id']).delete()
+
+ # XXX TMP we should send an email to the user to inform him/her
+ elif request['type'] == 'project':
+ request_status['SFA project'] = {'status': True }
+ p = PendingProject.objects.get(id=request['id'])
+ ctx = {
+ 'project_name' : p.project_name,
+ 'authority_hrn' : p.authority_hrn,
+ 'email' : p.email,
+ 'purpose' : p.purpose,
+ }
+ user_email = p.email
+ PendingProject.objects.get(id=request['id']).delete()
+
+ elif request['type'] == 'join':
+ request_status['SFA join'] = {'status': True }
+ j = PendingJoin.objects.get(id=request['id'])
+ ctx = {
+ 'project_name' : j.project_name,
+ 'authority_hrn' : j.authority_hrn,
+ 'email' : j.email,
+ 'user_hrn' : j.user_hrn,
+ }
+
+ user_email = j.email
+ PendingJoin.objects.get(id=request['id']).delete()
+ else:
+ raise Exception, 'unknown type of request %s' % request['type']
+
+ send_status_email(ctx, user_email, request['type'], 'denied')
+ except Exception, e:
+ request_status['SFA '+request['type']] = {'status': False, 'description': str(e)}
status['%s__%s' % (request['type'], request['id'])] = request_status
return status
+def send_status_email(ctx, user_email, obj_type, status):
+ try:
+ theme.template_name = obj_type + '_request_' + status + '.txt'
+ text_content = render_to_string(theme.template, ctx)
+ theme.template_name = obj_type + '_request_' + status + '.html'
+ html_content = render_to_string(theme.template, ctx)
+ theme.template_name = 'email_default_sender.txt'
+ sender = render_to_string(theme.template, ctx)
+ sender = sender.replace('\n', '')
+
+ subject = obj_type + ' request '+ status +'.'
+
+ msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
+ msg.attach_alternative(html_content, "text/html")
+ msg.send()
+ except Exception as e:
+ logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
+
+
# Django and ajax
# http://djangosnippets.org/snippets/942/
if not 'number_of_nodes' in request:
request['number_of_nodes']=""
+ # Slice is under a project
+ if len(request['authority_hrn'].split('.')) > 2:
+ pi_list = []
+ pis = authority_get_pis(wsgi_request, request['authority_hrn'])
+ for pi in pis:
+ pi_list = pi['pi_users']
+ user_hrns.extend(pi_list)
+
# XXX We should create a slice with Manifold terminology
slice_params = {
'slice_hrn' : hrn,
if not results:
raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
else:
- clear_user_creds(wsgi_request,user_email)
+ try:
+ for u_hrn in user_hrns:
+ u_email = get_user_email(wsgi_request, u_hrn)
+ clear_user_creds(wsgi_request, u_email)
+ except Exception as e:
+ logger.error("Failed clear credentials for all users")
+ clear_user_creds(wsgi_request,user_email)
# log user activity
activity.slice.validate(request, { "slice" : hrn })
- try:
- theme.template_name = 'slice_request_validated.txt'
- text_content = render_to_string(theme.template, request)
- theme.template_name = 'slice_request_validated.html'
- html_content = render_to_string(theme.template, request)
-
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, request)
- sender = sender.replace('\n', '')
-
- subject = 'Slice request validated'
-
- msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
return results
)
s.save()
- try:
- # Send an email: the recipients are the PI of the authority
- recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
-
- theme.template_name = 'slice_request_email.txt'
- text_content = render_to_string(theme.template, request)
-
- theme.template_name = 'slice_request_email.html'
- html_content = render_to_string(theme.template, request)
-
- theme.template_name = 'slice_request_email_subject.txt'
- subject = render_to_string(theme.template, request)
- subject = subject.replace('\n', '')
-
- sender = email
- msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
-
+ send_email_to_pis(wsgi_request, request, 'slice')
def create_pending_project(wsgi_request, request):
"""
)
s.save()
+ send_email_to_pis(wsgi_request, request, 'project')
+
def create_pending_join(wsgi_request, request):
"""
"""
)
s.save()
+ send_email_to_pis(wsgi_request, request, 'join')
+
+#-------------------------------------------------------------------------------
+# SEND EMAILS
+#-------------------------------------------------------------------------------
+
+def send_email_to_pis(wsgi_request, request, obj_type):
+ try:
+ # Send an email: the recipients are the PIs of the authority
+ recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
+
+ theme.template_name = obj_type + '_request_email.txt'
+ text_content = render_to_string(theme.template, request)
+
+ theme.template_name = obj_type + '_request_email.html'
+ html_content = render_to_string(theme.template, request)
-# try:
-# # Send an email: the recipients are the PI of the authority
-# recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
-#
-# theme.template_name = 'slice_request_email.txt'
-# text_content = render_to_string(theme.template, request)
-#
-# theme.template_name = 'slice_request_email.html'
-# html_content = render_to_string(theme.template, request)
-#
-# theme.template_name = 'slice_request_email_subject.txt'
-# subject = render_to_string(theme.template, request)
-# subject = subject.replace('\n', '')
-#
-# sender = email
-# msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
-# msg.attach_alternative(html_content, "text/html")
-# msg.send()
-# except Exception, e:
-# print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
+ theme.template_name = obj_type + '_request_email_subject.txt'
+ subject = render_to_string(theme.template, request)
+ subject = subject.replace('\n', '')
+
+ theme.template_name = 'email_default_sender.txt'
+ sender = render_to_string(theme.template, request)
+ sender = sender.replace('\n', '')
+
+ msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
+ msg.attach_alternative(html_content, "text/html")
+ msg.send()
+ except Exception, e:
+ print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
#-------------------------------------------------------------------------------
if not results:
raise Exception, "Could not create %s. Already exists ?" % sfa_user_params['user_hrn']
- else:
- try:
- theme.template_name = 'user_request_validated.txt'
- text_content = render_to_string(theme.template, request)
- theme.template_name = 'user_request_validated.html'
- html_content = render_to_string(theme.template, request)
-
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, request)
- sender = sender.replace('\n', '')
-
-
- subject = 'User validated'
-
- msg = EmailMultiAlternatives(subject, text_content, sender, [request['email']])
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
return results
iotlab_user_params1 = json.dumps(iotlab_user_params)
r=requests.post(url=URL_REST, data=iotlab_user_params1, headers=headers, auth=auth)
- print 'Create iotlab user : ', r.status_code, r.text
+ logger.info('Create iotlab user : {} {}'.format(r.status_code, r.text))
return r.text
def create_user(wsgi_request, request, namespace = None, as_admin = False):
'config' : json.dumps(account_config),
}
manifold_add_account(wsgi_request, account_params)
- except Exception, e:
- print "Failed creating manifold account on platform %s for user: %s" % ('myslice', request['email'])
- try:
- # Send an email: the recipients are the PI of the authority
- # If No PI is defined for this Authority, send to a default email (different for each theme)
- recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
-
- theme.template_name = 'user_request_email.html'
- html_content = render_to_string(theme.template, request)
-
- theme.template_name = 'user_request_email.txt'
- text_content = render_to_string(theme.template, request)
-
- theme.template_name = 'user_request_email_subject.txt'
- subject = render_to_string(theme.template, request)
- subject = subject.replace('\n', '')
-
- theme.template_name = 'email_default_sender.txt'
- sender = render_to_string(theme.template, request)
- sender = sender.replace('\n', '')
-
- msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
- msg.attach_alternative(html_content, "text/html")
- msg.send()
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
- import traceback
- traceback.print_exc()
+ # Email to PIs is sent when the user activates his email
+ # portal/emailactivationview.py
+
+ except Exception as e:
+ logger.error("Failed creating manifold account on platform {} for user: {}".format('myslice', request['email']))
+
username = None
# log user activity
activity.user.contact(self.request)
- return render(request,'contact_sent.html', { 'theme' : self.theme, 'username': username}) # Redirect after POST
+ return render(request,'contact_sent.html', { 'theme' : self.theme, 'username': username, 'request':request}) # Redirect after POST
else:
return self._display (request, form)
def _display (self, request, form):
if request.user.is_authenticated():
username = request.user.email
- ## check user is pi or not
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
- for platform_detail in platform_details:
- for account_detail in account_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- # assigning values
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
else :
username = None
pi = "is_not_pi"
'topmenu_items': topmenu_items('Contact', request),
'theme' : self.theme,
'username': username,
- 'pi': pi,
- 'section': "Contact"
+ 'section': "Contact",
+ 'request': request,
})
from ui.topmenu import topmenu_items_live, the_user
-from myslice.theme import ThemeView
+from myslice.theme import ThemeView
+from myslice.settings import logger
+
#This view requires login
class DashboardView (LoginRequiredAutoLogoutView, ThemeView):
#messages.info(self.request, 'You have logged in')
page = Page(self.request)
- print "Dashboard page"
+ logger.info("Dashboard page")
# Slow...
#slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
testbed_query = Query().get('network').select('network_hrn','platform','version')
# root_authority = sub_authority[0]
# slice_query = Query().get(root_authority+':user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
# else:
- print "SLICE QUERY"
- print "-" * 80
+ logger.debug("SLICE QUERY")
+ logger.debug("-" * 80)
slice_query = Query().get('myslice:user').filter_by('user_hrn', '==', '$user_hrn').select('slices.slice_hrn')
page.enqueue_query(slice_query)
page.enqueue_query(testbed_query)
-from unfold.loginrequired import FreeAccessView
-#
-from manifold.core.query import Query
-from manifoldapi.manifoldapi import execute_query, execute_admin_query
-from portal.actions import manifold_update_user, manifold_update_account, manifold_add_account, manifold_delete_account, sfa_update_user, authority_get_pi_emails, make_request_user, create_user
-#
-from unfold.page import Page
-from ui.topmenu import topmenu_items_live, the_user
-#
+import json
+import os
+import re
+import itertools
+
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
-from myslice.theme import ThemeView
-from portal.models import PendingUser, PendingAuthority
from django.core.mail import EmailMultiAlternatives, send_mail
from django.contrib.sites.models import Site
-#
-import json, os, re, itertools
+from manifold.core.query import Query
+from manifoldapi.manifoldapi import execute_query, execute_admin_query
+
+from unfold.loginrequired import FreeAccessView
+
+from portal.actions import (
+ manifold_update_user, manifold_update_account, manifold_add_account,
+ manifold_delete_account, sfa_update_user, authority_get_pi_emails,
+ make_request_user, create_user, send_email_to_pis)
+from portal.models import PendingUser, PendingAuthority
+
+from unfold.page import Page
+from ui.topmenu import topmenu_items_live, the_user
+
+from myslice.theme import ThemeView
+from myslice.settings import logger
+
def ValuesQuerySetToDict(vqs):
return [item for item in vqs]
# User is enabled in PLE
if 'enabled' in result and result['enabled']==True:
return True
- except Exception, e:
- print "Exception in myplc query = ",e
+ except Exception as e:
+ logger.error("Exception in myplc query = {}".format(e))
return False
#page.add_js_files ( [ "js/jquery.validate.js", "js/my_account.register.js", "js/my_account.edit_profile.js" ] )
#page.add_css_files ( [ "css/onelab.css", "css/account_view.css","css/plugin.css" ] )
+ # get the domain url
+ current_site = Site.objects.get_current()
+ current_site = current_site.domain
+
for key, value in kwargs.iteritems():
- #print "%s = %s" % (key, value)
if key == "hash_code":
hash_code=value
+
if PendingUser.objects.filter(email_hash__iexact = hash_code).filter(status__iexact = 'False'):
activation = 'success'
+ pending_users = PendingUser.objects.filter(email_hash__iexact = hash_code)
+ pending_user = pending_users[0]
# AUTO VALIDATION of PLE enabled users (only for OneLab Portal)
if self.theme == "onelab":
# as we currently need to do a Resolve on each user_hrn of the Registry in order to get its email
# TODO in SFA XXX We need a Resolve based on email
# TODO maybe we can use MyPLC API for PLE
- pending_users = PendingUser.objects.filter(email_hash__iexact = hash_code)
# by default user is not in PLE
ple_user_enabled = False
- if pending_users:
- pending_user = pending_users[0]
-
+ if pending_user:
# Auto Validation
if self.is_ple_enabled(pending_user):
pending_user_request = make_request_user(pending_user)
# template user auto validated
activation = 'validated'
-
- # sending email after activation success
- #try:
- # # Send an email: the recipient is the user
- # recipients = pending_user_eamil
- # theme.template_name = 'user_request_email.html'
- # html_content = render_to_string(theme.template, request)
- # theme.template_name = 'user_request_email.txt'
- # text_content = render_to_string(theme.template, request)
- # theme.template_name = 'user_request_email_subject.txt'
- # subject = render_to_string(theme.template, request)
- # subject = subject.replace('\n', '')
- # theme.template_name = 'email_default_sender.txt'
- # sender = render_to_string(theme.template, request)
- # sender = sender.replace('\n', '')
- # msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
- # msg.attach_alternative(html_content, "text/html")
- # msg.send()
- #except Exception, e:
- # print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
- # import traceback
- # traceback.print_exc()
PendingUser.objects.filter(email_hash__iexact = hash_code).update(status='True')
+ u = {}
+ u['first_name'] = pending_user.first_name
+ u['last_name'] = pending_user.last_name
+ u['authority_hrn'] = pending_user.authority_hrn
+ u['email'] = pending_user.email
+ u['user_hrn'] = pending_user.user_hrn
+ u['pi'] = pending_user.pi
+ u['public_key'] = pending_user.public_key
+ u['current_site'] = current_site
+
+ send_email_to_pis(self.request, u, 'user')
else:
activation = 'failed'
- # get the domain url
- current_site = Site.objects.get_current()
- current_site = current_site.domain
-
context = super(ActivateEmailView, self).get_context_data(**kwargs)
context['activation_status'] = activation
#context['first_name'] = first_name
#context['last_name'] = last_name
#context['authority_hrn'] = authority_hrn
- #context['public_key'] = public_key
#context['email'] = email
#context['user_hrn'] = user_hrn
- #context['current_site'] = current_site
context['theme'] = self.theme
# context ['firstname'] = config['firstname']
prelude_env = page.prelude_env()
# this program; see the file COPYING. If not, write to the Free Software
# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# TODO: Remove these automated forms and use html templates and views like any other page !
+
from django import forms
-from portal.models import PendingUser, PendingSlice
#from crispy_forms.helper import FormHelper
#from crispy_forms.layout import Submit
from django.utils.translation import ugettext_lazy as _
from django.utils.http import int_to_base36
from django.template import loader
-# TODO: Remove these automated forms and use html templates and views like any other page !
from django.contrib.auth.hashers import identify_hasher
+
+from portal.models import PendingUser, PendingSlice
+
+from myslice.settings import logger
+
# adapted from https://sourcegraph.com/github.com/fusionbox/django-authtools/symbols/python/authtools/forms
def is_password_unusable(pw):
subject = ''.join(subject.splitlines())
email = loader.render_to_string(email_template_name, c)
send_mail(subject, email, from_email, [user.email])
- except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
+ except Exception as e:
+ logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
class SetPasswordForm(forms.Form):
+import time
+import json
+
# this somehow is not used anymore - should it not be ?
from django.core.context_processors import csrf
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.shortcuts import render
-
from unfold.loginrequired import FreeAccessView
+from ui.topmenu import topmenu_items, the_user
from manifold.core.query import Query
from manifoldapi.manifoldapi import execute_query
-
from manifoldapi.manifoldresult import ManifoldResult
-from ui.topmenu import topmenu_items, the_user
-from myslice.configengine import ConfigEngine
+from myslice.configengine import ConfigEngine
from myslice.theme import ThemeView
+
from portal.account import Account, get_expiration
from portal.models import PendingSlice
-from portal.actions import authority_check_pis
+from portal.actions import authority_check_pis, get_jfed_identity, get_myslice_account
-import json, time
import activity.user
class HomeView (FreeAccessView, ThemeView):
template_name = 'home-view.html'
-
+
# expose this so we can mention the backend URL on the welcome page
def default_env (self):
- return {
+ return {
'MANIFOLD_URL':ConfigEngine().manifold_url(),
}
env = self.default_env()
env['theme'] = self.theme
env['section'] = "Dashboard"
-
+
username = request.POST.get('username')
password = request.POST.get('password')
-
+
# pass request within the token, so manifold session key can be attached to the request session.
- token = {'username': username, 'password': password, 'request': request}
+ token = {'username': username, 'password': password, 'request': request}
# our authenticate function returns either
# . a ManifoldResult - when something has gone wrong, like e.g. backend is unreachable
manifoldresult = auth_result
# let's use ManifoldResult.__repr__
env['state']="%s"%manifoldresult
-
- return render_to_response(self.template,env, context_instance=RequestContext(request))
+
# user was authenticated at the backend
elif auth_result is not None:
user=auth_result
- if user.is_active:
- print "LOGGING IN"
+ if user is not None and user.is_active:
login(request, user)
-
- if request.user.is_authenticated():
- env['person'] = self.request.user
- env['username'] = self.request.user
-
- # log user activity
- activity.user.login(self.request)
-
- ## check user is pi or not
- platform_details = {}
- account_details = {}
- acc_auth_cred = {}
- acc_user_cred = {}
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
- if platform_details is not None and platform_details != {}:
- for platform_detail in platform_details:
- for account_detail in account_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- acc_user_cred = account_config.get('delegated_user_credential','N/A')
- # assigning values
- #if acc_auth_cred=={} or acc_auth_cred=='N/A':
- # pi = "is_not_pi"
- #else:
- # pi = "is_pi"
- user_email = str(self.request.user)
- pi = authority_check_pis(self.request, user_email)
-
- # check if the user has creds or not
- if acc_user_cred == {} or acc_user_cred == 'N/A':
- user_cred = 'no_creds'
- else:
- exp_date = get_expiration(acc_user_cred, 'timestamp')
- if exp_date < time.time():
- user_cred = 'creds_expired'
- else:
- user_cred = 'has_creds'
- # list the pending slices of this user
- pending_slices = []
- for slices in PendingSlice.objects.filter(type_of_nodes__iexact=self.request.user).all():
- pending_slices.append(slices.slice_name)
-
- env['pending_slices'] = pending_slices
- env['pi'] = pi
- env['user_cred'] = user_cred
- else:
+ if request.user.is_authenticated():
+ try:
+ env['person'] = self.request.user
+ env['username'] = self.request.user
+
+ # log user activity
+ activity.user.login(self.request)
+
+ ## check user is pi or not
+ acc_auth_cred = {}
+ acc_user_cred = {}
+
+ account_detail = get_myslice_account(self.request)
+ if 'config' in account_detail and account_detail['config'] is not '':
+ account_config = json.loads(account_detail['config'])
+ acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
+ acc_user_cred = account_config.get('delegated_user_credential','N/A')
+ # assigning values
+ #if acc_auth_cred=={} or acc_auth_cred=='N/A':
+ # pi = "is_not_pi"
+ #else:
+ # pi = "is_pi"
+ user_email = str(self.request.user)
+ #pi = authority_check_pis(self.request, user_email)
+
+ # check if the user has creds or not
+ if acc_user_cred == {} or acc_user_cred == 'N/A':
+ user_cred = 'no_creds'
+ else:
+ exp_date = get_expiration(acc_user_cred, 'timestamp')
+ if exp_date < time.time():
+ user_cred = 'creds_expired'
+ else:
+ user_cred = 'has_creds'
+
+ # list the pending slices of this user
+ pending_slices = []
+ for slices in PendingSlice.objects.filter(type_of_nodes__iexact=self.request.user).all():
+ pending_slices.append(slices.slice_name)
+
+ env['pending_slices'] = pending_slices
+ #env['pi'] = pi
+ env['user_cred'] = user_cred
+ except Exception as e:
+ print e
+ env['person'] = None
+ env['state'] = "Your session has expired"
+ else:
env['person'] = None
- return render_to_response(self.template,env, context_instance=RequestContext(request))
else:
# log user activity
activity.user.login(self.request, "notactive")
env['state'] = "Your account is not active, please contact the site admin."
env['layout_1_or_2']="layout-unfold2.html"
-
- return render_to_response(self.template,env, context_instance=RequestContext(request))
+
+ jfed_identity = get_jfed_identity(request)
+ if jfed_identity is not None:
+ import base64
+ encoded_jfed_identity = base64.b64encode(jfed_identity)
+ env['jfed_identity'] = encoded_jfed_identity
+ else:
+ env['jfed_identity'] = None
+
# otherwise
else:
# log user activity
activity.user.login(self.request, "error")
env['state'] = "Your username and/or password were incorrect."
-
- return render_to_response(self.template, env, context_instance=RequestContext(request))
+ env['request'] = request
+ return render_to_response(self.template,env, context_instance=RequestContext(request))
def get (self, request, state=None):
env = self.default_env()
acc_auth_cred={}
- if request.user.is_authenticated():
-
- ## check user is pi or not
- platform_details = {}
- account_details = {}
- acc_auth_cred = {}
- acc_user_cred = {}
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- # XXX Something like an invalid session seems to make the execute fail sometimes, and thus gives an error on the main page
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
- if platform_details is not None and platform_details != {}:
- for platform_detail in platform_details:
- for account_detail in account_details:
- if 'platform_id' in platform_detail:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- acc_user_cred = account_config.get('delegated_user_credential','N/A')
- # assigning values
- #if acc_auth_cred=={} or acc_auth_cred=='N/A':
- # pi = "is_not_pi"
- #else:
- # pi = "is_pi"
- user_email = str(self.request.user)
- pi = authority_check_pis(self.request, user_email)
- # check if the user has creds or not
- if acc_user_cred == {} or acc_user_cred == 'N/A':
- user_cred = 'no_creds'
- else:
- exp_date = get_expiration(acc_user_cred, 'timestamp')
- if exp_date < time.time():
- user_cred = 'creds_expired'
+
+ try:
+ if request.user.is_authenticated():
+ jfed_identity = get_jfed_identity(request)
+ if jfed_identity is not None:
+ import base64
+ encoded_jfed_identity = base64.b64encode(jfed_identity)
+ env['jfed_identity'] = encoded_jfed_identity
+ else:
+ env['jfed_identity'] = None
+
+ ## check user is pi or not
+ platform_details = {}
+ account_details = {}
+ acc_auth_cred = {}
+ acc_user_cred = {}
+ platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
+ account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
+ # XXX Something like an invalid session seems to make the execute fail sometimes, and thus gives an error on the main page
+
+ account_detail = get_myslice_account(self.request)
+ if 'config' in account_detail and account_detail['config'] is not '':
+ account_config = json.loads(account_detail['config'])
+ acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
+ acc_user_cred = account_config.get('delegated_user_credential','N/A')
+ # assigning values
+ #if acc_auth_cred=={} or acc_auth_cred=='N/A':
+ # pi = "is_not_pi"
+ #else:
+ # pi = "is_pi"
+ user_email = str(self.request.user)
+ #pi = authority_check_pis(self.request, user_email)
+ # check if the user has creds or not
+ if acc_user_cred == {} or acc_user_cred == 'N/A':
+ user_cred = 'no_creds'
else:
- user_cred = 'has_creds'
-
- # list the pending slices of this user
- pending_slices = []
- for slices in PendingSlice.objects.filter(type_of_nodes__iexact=self.request.user).all():
- pending_slices.append(slices.slice_name)
-
- env['pending_slices'] = pending_slices
- env['pi'] = pi
- env['user_cred'] = user_cred
- env['person'] = self.request.user
- else:
+ exp_date = get_expiration(acc_user_cred, 'timestamp')
+ if exp_date < time.time():
+ user_cred = 'creds_expired'
+ else:
+ user_cred = 'has_creds'
+
+ # list the pending slices of this user
+ pending_slices = []
+ for slices in PendingSlice.objects.filter(type_of_nodes__iexact=self.request.user).all():
+ pending_slices.append(slices.slice_name)
+
+ env['pending_slices'] = pending_slices
+ #env['pi'] = pi
+ env['user_cred'] = user_cred
+ env['person'] = self.request.user
+ else:
+ env['person'] = None
+ except Exception as e:
+ print e
env['person'] = None
+ env['state'] = "Your session has expired"
env['theme'] = self.theme
env['section'] = "Dashboard"
-
env['username']=the_user(request)
env['topmenu_items'] = topmenu_items(None, request)
+ env['request'] = request
if state: env['state'] = state
elif not env['username']: env['state'] = None
# use one or two columns for the layout - not logged in users will see the login prompt
-
-# account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
-# account_details = execute_query(self.request, account_query)
-# for account_detail in account_details:
-# account_config = json.loads(account_detail['config'])
-# platform_name = platform_detail['platform']
-# if 'myslice' in platform_detail['platform']:
-# acc_user_cred = account_config.get('delegated_user_credential','N/A')
-# acc_slice_cred = account_config.get('delegated_slice_credentials','N/A')
-# acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
-#
-# if 'N/A' not in acc_user_cred:
-# exp_date = re.search('<expires>(.*)</expires>', acc_user_cred)
-# if exp_date:
-# user_exp_date = exp_date.group(1)
-# user_cred_exp_list.append(user_exp_date)
-#
-# my_users = [{'cred_exp': t[0]}
-# for t in zip(user_cred_exp_list)]
-#
-#
-# if 'N/A' not in acc_slice_cred:
-# for key, value in acc_slice_cred.iteritems():
-# slice_list.append(key)
-# # get cred_exp date
-# exp_date = re.search('<expires>(.*)</expires>', value)
-# if exp_date:
-# exp_date = exp_date.group(1)
-# slice_cred_exp_list.append(exp_date)
-#
-# my_slices = [{'slice_name': t[0], 'cred_exp': t[1]}
-# for t in zip(slice_list, slice_cred_exp_list)]
-#
-# if 'N/A' not in acc_auth_cred:
-# for key, value in acc_auth_cred.iteritems():
-# auth_list.append(key)
-# #get cred_exp date
-# exp_date = re.search('<expires>(.*)</expires>', value)
-# if exp_date:
-# exp_date = exp_date.group(1)
-# auth_cred_exp_list.append(exp_date)
-
-
return render_to_response(self.template, env, context_instance=RequestContext(request))
+import json
+
from django.core.context_processors import csrf
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from portal.actions import is_pi, authority_check_pis
from myslice.theme import ThemeView
-import json
+from myslice.settings import logger
+
class InstitutionView (LoginRequiredAutoLogoutView, ThemeView):
template_name = 'institution.html'
def post (self,request):
env = self.default_env()
env['theme'] = self.theme
+ env['request'] = request
return render_to_response(self.template, env, context_instance=RequestContext(request))
def get (self, request, authority_hrn=None, state=None):
env['project'] = True
env['user_details'] = {'parent_authority': authority_hrn}
+ logger.debug("BEFORE ####------#### is_pi")
+ logger.debug("is_pi = {}".format(is_pi))
+ pi = is_pi(self.request, '$user_hrn', env['user_details']['parent_authority'])
else:
env['person'] = None
- print "BEFORE ####------#### is_pi"
- pi = is_pi(self.request, '$user_hrn', env['user_details']['parent_authority'])
- print "is_pi = ",is_pi
-
+ pi = False
env['theme'] = self.theme
env['section'] = "Institution"
env['pi'] = pi
# use one or two columns for the layout - not logged in users will see the login prompt
env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
-
+ env['request'] = request
return render_to_response(self.template, env, context_instance=RequestContext(request))
from portal.actions import authority_get_pi_emails, manifold_add_user,manifold_add_account, create_pending_user
from myslice.theme import ThemeView
+from myslice.settings import logger
import activity.institution
msg.send()
except Exception, e:
- print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
+ logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
import traceback
- traceback.print_exc()
+ logger.error(traceback.format_exc())
self.template_name = 'join_complete.html'
# log institution activity
+import json
# this somehow is not used anymore - should it not be ?
from django.core.context_processors import csrf
from django.http import HttpResponseRedirect
from manifold.core.query import Query
from manifoldapi.manifoldapi import execute_query
from manifoldapi.manifoldresult import ManifoldResult
-from myslice.configengine import ConfigEngine
+from myslice.configengine import ConfigEngine
from myslice.theme import ThemeView
-import json
+from myslice.settings import logger
class ManagementAboutView (FreeAccessView, ThemeView):
template_name = 'management-tab-about.html'
user_local_query = Query().get('local:user').select('config').filter_by('email','==',str(self.request.user))
user_local_details = execute_query(self.request, user_local_query)
user_authority = json.loads(user_local_details[0]['config']).get('authority')
- print "**************________ management about = ",user_authority
+ logger.info("**************________ management about = {}".format(user_authority))
# XXX Should be done using Metadata
# select column.name from local:object where table=='authority'
authority_query = Query().get('authority').select('authority_hrn', 'name', 'address', 'enabled','description',
+import json
+
from django.template import RequestContext
from django.shortcuts import render_to_response
from portal.actions import get_requests
from myslice.theme import ThemeView
-
-import json
+from myslice.settings import logger
class ManagementRequestsView (LoginRequiredView, ThemeView):
template_name = "management-tab-requests.html"
sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
sfa_platforms = execute_query(self.request, sfa_platforms_query)
for sfa_platform in sfa_platforms:
- print "SFA PLATFORM > ", sfa_platform['platform']
+ logger.info("SFA PLATFORM > {}".format(sfa_platform['platform']))
if not 'auth_type' in sfa_platform:
continue
auth = sfa_platform['auth_type']
all_authorities.append(auth)
platform_ids.append(sfa_platform['platform_id'])
- print "W: Hardcoding platform myslice"
+ logger.warning("W: Hardcoding platform myslice")
# There has been a tweak on how new platforms are referencing a
# so-called 'myslice' platform for storing authentication tokens.
# XXX This has to be removed in final versions.
try:
for pa in pi_authorities_tmp:
pi_authorities |= set(pa['pi_authorities'])
- except:
- print 'No pi_authorities'
+ except Exception as e:
+ logger.error('No pi_authorities')
pi_credential_authorities = pi_authorities & credential_authorities
pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
+import os
+import re
+import itertools
+import json
+
from unfold.loginrequired import LoginRequiredAutoLogoutView
-#
+
from manifold.core.query import Query
from manifoldapi.manifoldapi import execute_query, execute_admin_query
from portal.actions import manifold_update_user, manifold_update_account, manifold_add_account, manifold_delete_account
-from portal.actions import sfa_update_user, authority_get_pis, authority_add_pis, authority_remove_pis,authority_check_pis ,clear_user_creds
-#
+from portal.actions import (
+ sfa_update_user, authority_get_pis, authority_add_pis,
+ authority_remove_pis,authority_check_pis ,clear_user_creds )
+
from unfold.page import Page
from ui.topmenu import topmenu_items_live, the_user
-#
+
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from myslice.theme import ThemeView
-#
-import json, os, re, itertools
# requires login
class UserView(LoginRequiredAutoLogoutView, ThemeView):
page.add_css_files ( [ "css/onelab.css", "css/account_view.css","css/plugin.css","css/jquery-ui.css" ] )
for key, value in kwargs.iteritems():
- #print "%s = %s" % (key, value)
if key == "email":
selected_email=value
#from django.core.validators import validate_email
-try:
- from django.contrib.auth import get_user_model
- User = get_user_model()
-except ImportError:
- from django.contrib.auth.models import User
+#try:
+# from django.contrib.auth import get_user_model
+# User = get_user_model()
+#except ImportError:
+# from django.contrib.auth.models import User
try:
from django.utils.timezone import now as datetime_now
--- /dev/null
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Institution',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('name', models.TextField()),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='PendingAuthority',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('site_name', models.TextField()),
+ ('site_authority', models.TextField()),
+ ('site_abbreviated_name', models.TextField()),
+ ('site_url', models.TextField()),
+ ('site_latitude', models.TextField()),
+ ('site_longitude', models.TextField()),
+ ('address_line1', models.TextField()),
+ ('address_line2', models.TextField()),
+ ('address_line3', models.TextField()),
+ ('address_city', models.TextField()),
+ ('address_postalcode', models.TextField()),
+ ('address_state', models.TextField()),
+ ('address_country', models.TextField()),
+ ('authority_hrn', models.TextField()),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='PendingJoin',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('user_hrn', models.TextField()),
+ ('email', models.TextField()),
+ ('project_name', models.TextField(null=True)),
+ ('authority_hrn', models.TextField()),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='PendingProject',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('project_name', models.TextField()),
+ ('user_hrn', models.TextField()),
+ ('email', models.TextField()),
+ ('authority_hrn', models.TextField(null=True)),
+ ('purpose', models.TextField(default=b'NA')),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='PendingSlice',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('slice_name', models.TextField()),
+ ('user_hrn', models.TextField()),
+ ('authority_hrn', models.TextField(null=True)),
+ ('number_of_nodes', models.TextField(default=0)),
+ ('type_of_nodes', models.TextField(default=b'NA')),
+ ('purpose', models.TextField(default=b'NA')),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='PendingUser',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('first_name', models.TextField()),
+ ('last_name', models.TextField()),
+ ('email', models.EmailField(max_length=75)),
+ ('password', models.TextField()),
+ ('user_hrn', models.TextField()),
+ ('public_key', models.TextField()),
+ ('private_key', models.TextField()),
+ ('authority_hrn', models.TextField()),
+ ('login', models.TextField()),
+ ('pi', models.TextField()),
+ ('email_hash', models.TextField()),
+ ('status', models.TextField()),
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ ]
from myslice.configengine import ConfigEngine
from myslice.theme import ThemeView
+from myslice.settings import logger
# View for 1 platform and its details
class PlatformView(FreeAccessView, ThemeView):
page.add_js_files ( [ "js/common.functions.js" ] )
for key, value in kwargs.iteritems():
- print "%s = %s" % (key, value)
+ logger.debug("{} = {}".format(key, value))
if key == "platformname":
platformname=value
+import json
+import time
+import re
+
from django.shortcuts import render
from django.contrib.sites.models import Site
from portal.models import PendingProject, PendingJoin
from myslice.theme import ThemeView
-
-import json, time, re
+from myslice.settings import logger
class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
template_name = 'projectrequest_view.html'
def getAuthorities(self, request):
- authorities_query = Query.get('authority').select('name', 'authority_hrn')
+ if self.theme == 'fed4fire':
+ authorities_query = Query.get('myslice:authority').select('authority_hrn')
+ else:
+ authorities_query = Query.get('authority').select('name', 'authority_hrn')
authorities = execute_admin_query(request, authorities_query)
if authorities is not None:
- authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
- authorities = sorted(authorities, key=lambda k: k['name'])
+ # Remove the root authority from the list
+ matching = [s for s in authorities if "." in s['authority_hrn']]
+ authorities = sorted(matching, key=lambda k: k['authority_hrn'])
+ if self.theme != 'fed4fire':
+ authorities = sorted(matching, key=lambda k: k['name'])
return authorities
def getUserAuthority(self, request):
user_authority = self.getUserAuthority(wsgi_request)
# getting the org from authority
- for authority in authorities:
- if authority['authority_hrn'] == user_authority:
- authority_name = authority['name']
+ #for authority in authorities:
+ # if authority['authority_hrn'] == user_authority:
+ # authority_name = authority['name']
if method == 'POST' :
-
+
+ project_name = wsgi_request.POST.get('project_name', '')
+ if not project_name or len(project_name) == 0 :
+ errors.append('Project name can\'t be empty')
+
+ # accept only lowercase names
+ project_name = project_name.lower()
+
if 'join' in wsgi_request.POST:
post = {
'user_hrn' : user_hrn,
'email' : user_email,
- 'project_name' : wsgi_request.POST.get('project_name', ''),
- 'authority_hrn' : wsgi_request.POST.get('project_name', ''),
+ 'project_name' : project_name,
+ 'authority_hrn' : project_name,
}
else:
'user_hrn' : user_hrn,
'email' : user_email,
'authority_hrn' : wsgi_request.POST.get('authority_name', ''),
- 'project_name' : wsgi_request.POST.get('project_name', ''),
+ 'project_name' : project_name,
'purpose' : wsgi_request.POST.get('purpose', ''),
}
- if (post['authority_hrn'] is None or post['authority_hrn'] == ''):
- errors.append('Organization is mandatory')
+ # for new projects max project_name length is 10
+ if (len(post['project_name']) >10):
+ errors.append('Project name can be maximum 10 characters long')
+
+ #if (post['authority_hrn'] is None or post['authority_hrn'] == ''):
+ # errors.append('Organization is mandatory')
- if (post['purpose'] is None or post['purpose'] == ''):
+ if post['purpose'] is None or post['purpose'] == '':
errors.append('Project purpose is mandatory')
- if (re.search(r'^[A-Za-z0-9_]*$', post['project_name']) == None):
+ if re.search(r'^[A-Za-z0-9_]*$', post['project_name']) is None:
errors.append('Project name may contain only letters, numbers, and underscore.')
# What kind of project name is valid?
- if (post['project_name'] is None or post['project_name'] == ''):
- errors.append('Project name is mandatory')
+ if post['project_name'] is None or post['project_name'] == '':
+ errors.append('Project name is mandatory')
if not errors:
- print "is_pi on auth_hrn = ", user_authority
+ logger.info("is_pi on auth_hrn = {}".format(user_authority))
if is_pi(wsgi_request, user_hrn, user_authority):
# PIs can directly create/join project in their own authority...
if 'join' in wsgi_request.POST:
+ # join existing project
authority_add_pis(wsgi_request, post['project_name'], user_hrn)
else:
+ # Create project
hrn = post['authority_hrn'] + '.' + post['project_name']
sfa_add_authority(wsgi_request, {'authority_hrn':hrn})
authority_add_pis(wsgi_request, hrn, user_hrn)
'pending_join_projects': pending_join_projects,
}
return render(wsgi_request, self.template, env)
-
-
-
- """
- """
- errors = []
- slice_name =''
- purpose=''
- url=''
- authority_hrn = None
- authority_name = None
- # Retrieve the list of authorities
- authorities_query = Query.get('authority').select('name', 'authority_hrn')
- authorities = execute_admin_query(wsgi_request, authorities_query)
- if authorities is not None:
- authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
- authorities = sorted(authorities, key=lambda k: k['name'])
-
- # Get user_email (XXX Would deserve to be simplified)
- user_query = Query().get('local:user').select('email','config')
- user_details = execute_query(wsgi_request, user_query)
- user_email = user_details[0].get('email')
- # getting user_hrn
- for user_detail in user_details:
- user_config = json.loads(user_detail['config'])
- user_authority = user_config.get('authority','N/A')
- # getting the org from authority
- for authority in authorities:
- if authority['authority_hrn'] == user_authority:
- authority_name = authority['name']
-
- # Handle the case when we use only hrn and not name
- if authority_name is None:
- authority_name = user_authority
- #
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- account_details = execute_query(wsgi_request, account_query)
- #
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- platform_details = execute_query(wsgi_request, platform_query)
-
- user_hrn = None
- # getting user_hrn from local:account
- for account_detail in account_details:
- for platform_detail in platform_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- # taking user_hrn only from myslice account
- # NOTE: we should later handle accounts filter_by auth_type= managed OR user
- if 'myslice' in platform_detail['platform']:
- account_config = json.loads(account_detail['config'])
- user_hrn = account_config.get('user_hrn','N/A')
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
-
-
- # checking if pi or not
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
-
-
- # Page rendering
-# page = Page(wsgi_request)
-# page.add_js_files ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
-# page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
-# page.expose_js_metadata()
-
- if method == 'POST':
- # The form has been submitted
-
- # get the domain url
-# current_site = Site.objects.get_current()
-# current_site = current_site.domain
-
- # getting the authority_hrn from the selected organization
- for authority in authorities:
- if authority['name'] == wsgi_request.POST.get('org_name', ''):
- authority_hrn = authority['authority_hrn']
-
- # Handle the case when we use only hrn and not name
- if authority_hrn is None:
- authority_hrn = wsgi_request.POST.get('org_name', '')
-
- slice_request = {
- 'type' : 'slice',
- 'id' : None,
- 'user_hrn' : user_hrn,
- 'email' : user_email,
- 'timestamp' : time.time(),
- 'authority_hrn' : authority_hrn,
- 'organization' : wsgi_request.POST.get('org_name', ''),
- 'slice_name' : wsgi_request.POST.get('slice_name', ''),
- 'url' : wsgi_request.POST.get('url', ''),
- 'purpose' : wsgi_request.POST.get('purpose', ''),
- 'current_site' : current_site
- }
-
- # create slice_hrn based on authority_hrn and slice_name
-# slice_name = slice_request['slice_name']
- req_slice_hrn = authority_hrn + '.' + slice_name
- # comparing requested slice_hrn with the existing slice_hrn
- slice_query = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
- slice_details_sfa = execute_admin_query(wsgi_request, slice_query)
- for _slice in slice_details_sfa:
- if _slice['slice_hrn'] == req_slice_hrn:
- errors.append('Slice already exists. Please use a different slice name.')
-
-
- # What kind of slice name is valid?
- if (slice_name is None or slice_name == ''):
- errors.append('Slice name is mandatory')
-
- if (re.search(r'^[A-Za-z0-9_]*$', slice_name) == None):
- errors.append('Slice name may contain only letters, numbers, and underscore.')
-
- organization = slice_request['organization']
- if (organization is None or organization == ''):
- errors.append('Organization is mandatory')
-
-
-
- purpose = slice_request['purpose']
- if (purpose is None or purpose == ''):
- errors.append('Experiment purpose is mandatory')
-
- url = slice_request['url']
-
- if not errors:
- if is_pi(wsgi_request, user_hrn, authority_hrn):
- # PIs can directly create slices in their own authority...
- create_slice(wsgi_request, slice_request)
- clear_user_creds(wsgi_request, user_email)
- self.template_name = 'slice-request-done-view.html'
- else:
- # Otherwise a wsgi_request is sent to the PI
- create_pending_slice(wsgi_request, slice_request, user_email)
- self.template_name = 'slice-request-ack-view.html'
-
- # log user activity
- activity.user.slice(wsgi_request)
-
- return render(wsgi_request, self.template, {'theme': self.theme}) # Redirect after POST
- else:
- slice_request = {}
-
- template_env = {
- 'username': wsgi_request.user.email,
- 'errors': errors,
- 'slice_name': slice_name,
- 'purpose': purpose,
- 'email': user_email,
- 'user_hrn': user_hrn,
- 'url': url,
- 'pi': pi,
- 'authority_name': authority_name,
- 'authority_hrn': user_authority,
- 'cc_myself': True,
- 'authorities': authorities,
- 'theme': self.theme,
- 'section': "Slice request"
- }
- template_env.update(slice_request)
- template_env.update(page.prelude_env())
- return render(wsgi_request, self.template, template_env)
-import os.path, re
+import os.path
+import re
import json
from random import randint
from hashlib import md5
from portal.actions import create_pending_user
from myslice.theme import ThemeView
+from myslice.settings import logger
import activity.user
# REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
authorities_query = Query.get('authority').select('name', 'authority_hrn')
authorities = execute_admin_query(wsgi_request, authorities_query)
- print "RegistrationView authorities = ", authorities
+ logger.info("RegistrationView authorities = {}".format(authorities))
if authorities is not None:
# Remove the root authority from the list
matching = [s for s in authorities if "." in s['authority_hrn']]
authorities = sorted(matching, key=lambda k: k['authority_hrn'])
authorities = sorted(matching, key=lambda k: k['name'])
- print "############ BREAKPOINT 1 #################"
+ logger.debug("############ BREAKPOINT 1 #################")
# Page rendering
page = Page(wsgi_request)
page.add_css_files ( [ "css/onelab.css", "css/registration.css", "css/jquery.qtip.min.css", "css/jquery.ui.combobox.css" ] )
page.expose_js_metadata()
- print "############ BREAKPOINT 2 #################"
+ logger.debug("############ BREAKPOINT 2 #################")
if method == 'POST':
reg_form = {}
# The form has been submitted
current_site = Site.objects.get_current()
current_site = current_site.domain
- print "############ BREAKPOINT 3 #################"
+ logger.debug("############ BREAKPOINT 3 #################")
post_email = wsgi_request.POST.get('email','').lower()
salt = randint(1,100000)
email_hash = md5(str(salt)+post_email).hexdigest()
'validation_link': current_site + '/portal/email_activation/'+ email_hash
}
- print "############ BREAKPOINT 4 #################"
+ logger.debug("############ BREAKPOINT 4 #################")
auth = wsgi_request.POST.get('org_name', None)
if auth is None or auth == "":
errors.append('Organization required: please select one or request its addition')
else:
- print "############ BREAKPOINT 5 #################"
+ logger.debug("############ BREAKPOINT 5 #################")
# Construct user_hrn from email (XXX Should use common code)
split_email = user_request['email'].split("@")[0]
return render(wsgi_request, self.template, {'theme': self.theme})
else:
- print "############ BREAKPOINT A #################"
+ logger.debug("############ BREAKPOINT A #################")
user_request = {}
## this is coming from onelab website onelab.eu
reg_form = {
}
# log user activity
activity.user.signup(self.request)
- print "############ BREAKPOINT B #################"
+ logger.debug("############ BREAKPOINT B #################")
template_env = {
#'topmenu_items': topmenu_items_live('Register', page),
template_env.update(user_request)
template_env.update(reg_form)
template_env.update(page.prelude_env ())
- print "############ BREAKPOINT C #################"
+ logger.debug("############ BREAKPOINT C #################")
return render(wsgi_request, self.template,template_env)
-from django.contrib.auth import authenticate, login, logout\r
-from django.template import RequestContext\r
-from django.shortcuts import render, render_to_response\r
-\r
-from manifoldapi.manifoldresult import ManifoldResult\r
-from ui.topmenu import topmenu_items, the_user\r
-from myslice.configengine import ConfigEngine\r
-from manifold.core.query import Query\r
-from unfold.page import Page\r
-from manifoldapi.manifoldapi import execute_admin_query, execute_query\r
-from unfold.loginrequired import LoginRequiredAutoLogoutView\r
-\r
-from myslice.theme import ThemeView\r
-import json\r
-import hashlib\r
-import datetime\r
-import urllib2\r
-import ast\r
-import time\r
-\r
-from django.views.decorators.csrf import csrf_exempt\r
-from django.http import *\r
-\r
-\r
-def response_mimetype(request):\r
- \r
- if "application/json" in request.META['HTTP_ACCEPT']:\r
- return "application/json"\r
- else:\r
- return "text/plain"\r
- \r
-\r
-def json_to_rest(url, data ):\r
- \r
- req = urllib2.Request(url)\r
- req.add_header('Content-Type', 'application/json')\r
- response = urllib2.urlopen(req, json.dumps(data))\r
- \r
- if data == "a":\r
- mylist = ast.literal_eval(response.read())\r
- else:\r
- mylist = response.read().translate(None, '"[]').split(",")\r
- \r
- return (mylist)\r
-\r
-\r
-def unix_to_timestamp(timest):\r
- try:\r
- return datetime.datetime.fromtimestamp(int(timest)).strftime('%Y-%m-%d %H:%M:%S')\r
- except:\r
- return timest\r
-\r
-def timestamp_to_unix(timest):\r
- try:\r
- pass\r
- except:\r
- pass\r
- \r
- \r
-def slice_to_exp(slices_users):\r
- experiments = {}\r
- testbeds = {}\r
- wildcard_testbeds = {}\r
- \r
- \r
- for slice in slices_users: \r
- nodes={}\r
- leases = slice['lease']\r
- \r
- if leases is not None and leases:\r
- for lease in leases:\r
- resource = lease['resource']\r
- start_t = lease['start_time']\r
- end_t = lease['end_time']\r
- \r
- testbed_start = resource.index('IDN+')+4\r
- testbed_end = resource.index('+node+')\r
- \r
- testbed = resource[testbed_start:testbed_end]\r
- node = resource[testbed_end+6:]\r
- if 'omf:nitos' in testbed:\r
- testbed = 'omf:nitos'\r
- if testbed in testbeds:\r
- if node not in testbeds[testbed]:\r
- testbeds[testbed].append(node)\r
- else:\r
- testbeds[testbed] = [node]\r
- \r
- #group nodes in consecutive timeslots\r
- if not node in nodes: \r
- nodes[node]={str(start_t):{'start_t':start_t, 'nodes':node, 'end_t':end_t}}\r
- else:\r
- if not str(start_t) in nodes[node]:\r
- f=0\r
- for n in nodes[node]:\r
- if n[str(end_t)] == start_t:\r
- n[str(end_t)] == end_t\r
- f=1\r
- if f==0:\r
- nodes[node][str(start_t)]={'start_t':start_t, 'nodes':node, 'end_t':end_t}\r
-\r
- ######### FOR PLE LIKE start ##################\r
- for resource in slice['resource']:\r
- testbed_start = resource.index('IDN+')+4\r
- testbed_end = resource.index('+node+')\r
- tb = resource[testbed_start:testbed_end]\r
- node = resource[testbed_end+6:]\r
- if 'ple:' in tb:\r
- tb = 'ple'\r
- if 'omf:nitos' in tb:\r
- tb = 'omf:nitos'\r
- if tb not in testbeds:\r
- try:\r
- if node not in wildcard_testbeds[slice['slice_hrn']][tb]:\r
- wildcard_testbeds[slice['slice_hrn']][tb].append([node])\r
- except:\r
- try:\r
- wildcard_testbeds[slice['slice_hrn']][tb] = [node]\r
- except:\r
- wildcard_testbeds[slice['slice_hrn']]={tb:[node]}\r
- \r
- \r
- else:\r
- s = slice['slice_last_updated']\r
- #s_time = int(time.mktime(datetime.datetime.strptime(s, "%Y%m%dT%H:%M:%Ss").timetuple()))\r
- s_time = time.mktime(s.timetuple()) \r
- \r
- if slice['resource'] is not None:\r
- \r
- for resource in slice['resource']:\r
- testbed_start = resource.index('IDN+')+4\r
- testbed_end = resource.index('+node+')\r
- tb = resource[testbed_start:testbed_end]\r
- if 'ple:' in tb:\r
- tb = 'ple'\r
- if 'omf:nitos' in tb:\r
- tb = 'omf:nitos'\r
- node = resource[testbed_end+6:]\r
- \r
- if testbed in testbeds:\r
- if node not in testbeds[testbed]:\r
- testbeds[testbed].append(node)\r
- else:\r
- testbeds[testbed] = [node] \r
- \r
- if not node in nodes: \r
- #nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':int(time.time())}} \r
- nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':s_time}} \r
- ######### FOR PLE LIKE end ##################\r
- \r
- \r
- #group grouped nodes in experiments\r
- for n in nodes:\r
- for exp in nodes[n]:\r
- key = str(exp) + str(nodes[n][exp]['end_t']) + slice['slice_hrn']\r
- \r
- if key not in experiments:\r
- experiments[key]={'slice_hrn':slice['slice_hrn'], \\r
- 'start':nodes[n][exp]['start_t'], 'end':nodes[n][exp]['end_t'], 'nodes':[nodes[n][exp]['nodes']]} \r
- \r
- \r
- ######### FOR PLE LIKE start ##################\r
- for item in wildcard_testbeds:\r
- if item == experiments[key]['slice_hrn']:\r
- for testbed in wildcard_testbeds[item]:\r
- \r
- if testbed not in testbeds:\r
- testbeds[testbed] = wildcard_testbeds[item][testbed] \r
- \r
- for n in wildcard_testbeds[item][testbed]:\r
- if n not in experiments[key]['nodes']:\r
- experiments[key]['nodes'].append(n) \r
- ######### FOR PLE LIKE end ##################\r
- \r
- elif nodes[n][exp]['end_t'] == experiments[key]['end']:\r
- experiments[key]['nodes'].append(nodes[n][exp]['nodes'])\r
- \r
- \r
- ######### FOR PLE LIKE start ##################\r
- for item in wildcard_testbeds:\r
- if item == experiments[key]['slice_hrn']:\r
- for testbed in wildcard_testbeds[item]:\r
- \r
- if testbed not in testbeds:\r
- testbeds[testbed] = wildcard_testbeds[item][testbed] \r
- \r
- for n in wildcard_testbeds[item][testbed]:\r
- if n not in experiments[key]['nodes']:\r
- experiments[key]['nodes'].append(n) \r
- ######### FOR PLE LIKE end ##################\r
- \r
- return (experiments,testbeds)\r
- \r
-class ReputationView (LoginRequiredAutoLogoutView, ThemeView):\r
- template_name = 'reputation.html'\r
- \r
- # expose this so we can mention the backend URL on the welcome page\r
- def default_env (self):\r
- return { \r
- 'MANIFOLD_URL':ConfigEngine().manifold_url(),\r
- }\r
-\r
- def post (self,request):\r
- env = self.default_env()\r
- env['theme'] = self.theme\r
- \r
- return render_to_response(self.template, env, context_instance=RequestContext(request)) \r
- \r
- def get (self, request, state=None):\r
- env = self.default_env()\r
- \r
- ##### *** Reputation Plugin-specific START *** ############\r
- #The following 'if' is a dirty way for bypassing the JS AJAX cross-domain prevention policy...not pretty\r
- if request.GET.has_key(u'slicedata[user_eval][overall]'):\r
- dict_to_send = {}\r
- dict_to_send['eid'] = str(request.GET[u'slicedata[id]'])\r
- dict_to_send['slice_hrn'] = str(request.GET[u'slicedata[slice_hrn]'])\r
- dict_to_send['user_hrn'] = str(request.GET[u'slicedata[user_hrn]'])\r
- dict_to_send['start_tunix'] = str(request.GET[u'slicedata[start_tunix]'])\r
- dict_to_send['end_tunix'] = str(request.GET[u'slicedata[end_tunix]'])\r
- dict_to_send['start_t'] = str(request.GET[u'slicedata[start_t]'])\r
- dict_to_send['end_t'] = str(request.GET[u'slicedata[end_t]'])\r
- dict_to_send['testbeds'] = ast.literal_eval(str(request.GET[u'testbeds']))\r
- dict_to_send['user_eval'] = {}\r
- dict_to_send['user_eval']['reuse'] = str(request.GET[u'slicedata[user_eval][reuse]'])\r
- dict_to_send['user_eval']['availability'] = str(request.GET[u'slicedata[user_eval][availability]'])\r
- dict_to_send['user_eval']['pay'] = str(request.GET[u'slicedata[user_eval][pay]'])\r
- dict_to_send['user_eval']['support'] = str(request.GET[u'slicedata[user_eval][support]'])\r
- dict_to_send['user_eval']['overall'] = str(request.GET[u'slicedata[user_eval][overall]'])\r
- dict_to_send['user_eval']['link_quality'] = str(request.GET[u'slicedata[user_eval][link_quality]'])\r
- dict_to_send['user_eval']['problems'] = str(request.GET[u'slicedata[user_eval][problems]'])\r
- dict_to_send['user_eval']['quality'] = str(request.GET[u'slicedata[user_eval][quality]'])\r
- \r
- slicedata_received = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/json', dict_to_send )\r
- \r
- return HttpResponse(json.dumps(slicedata_received), content_type = response_mimetype(self.request))\r
-\r
- \r
- slices_users = []\r
- \r
- #get slices\r
- userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease', 'slice_last_updated')\r
- slice_details = execute_query(self.request, userslice_query)\r
- \r
- #get local users\r
- local_user_query = Query().get('local:user').select('email','status','config')\r
- local_user_details = execute_admin_query(self.request, local_user_query)\r
- \r
- #get users - create dict[email]=hrn\r
- user_query = Query().get('user').select('user_hrn','user_urn','user_email')\r
- user_details = execute_admin_query(self.request, user_query)\r
- users_hrn = {}\r
- for item in user_details:\r
- users_hrn[item['user_email']] = item['user_hrn']\r
- \r
- #get currenct username (email)\r
- if request.user.is_authenticated():\r
- cur_username = request.user.username \r
- \r
- #get a list of all the slices for the logged in user\r
- testbeds = []\r
- #env['slices_users'] = json.dumps(slice_details, ensure_ascii=False)\r
- for slice in slice_details:\r
- \r
- if users_hrn[cur_username] in slice['users']:\r
- slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \\r
- , 'resource':slice['resource'], 'lease':slice['lease'], 'slice_last_updated':slice['slice_last_updated'] }) \r
- \r
- \r
- #env['slices_users'] = slices_users ### For logging\r
- #####create slicelist for template & JSON\r
- experiments,testbeds = slice_to_exp(slices_users)\r
- \r
- all_exp = []\r
- iddata = []\r
- \r
- for exp in experiments:\r
- experiment = {}\r
- experiment['slice_hrn'] = experiments[exp]['slice_hrn']\r
- experiment['user_hrn'] = users_hrn[cur_username]\r
- experiment['start_tunix'] = experiments[exp]['start']\r
- experiment['end_tunix'] = experiments[exp]['end']\r
- experiment['start_t'] = unix_to_timestamp(experiments[exp]['start'])\r
- experiment['end_t'] = unix_to_timestamp(experiments[exp]['end'])\r
- experiment['testbeds'] = {}\r
- for exp_node in experiments[exp]['nodes']:\r
- list_testbeds = [ key for key,val in testbeds.items()]\r
- for tkey in list_testbeds:\r
- if exp_node in testbeds[tkey]:\r
- if tkey in experiment['testbeds']:\r
- if exp_node not in experiment['testbeds'][tkey]:\r
- experiment['testbeds'][tkey].append(exp_node)\r
- else:\r
- experiment['testbeds'][tkey] = [exp_node]\r
- tempid = hashlib.sha1(str(experiment)).hexdigest() \r
- experiment['id'] = tempid\r
- \r
- iddata.append(tempid)\r
- all_exp.append(experiment)\r
- env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
- env['slices_users'] = json.dumps(all_exp, ensure_ascii=False)\r
- ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated\r
- \r
- unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata) \r
- \r
- for item in all_exp:\r
- if item['id'] in unrated_exp:\r
- pass\r
- else:\r
- all_exp.pop(all_exp.index(item))\r
-\r
- ###### Get Reputation values from Reputation DB\r
- reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a")\r
- #env['logging_test'] = reps \r
- \r
- #create a services list and a dict containing the services for each testbed\r
- serv_per_tb = {}\r
- services = []\r
- for item in reps:\r
- serv_per_tb[item['testbed']]=[]\r
- for serv in item['services']:\r
- if serv.keys()[0] not in services:\r
- services.append(serv.keys()[0])\r
- serv_per_tb[item['testbed']].append(serv.keys()[0]) \r
- \r
- #in json, sevices are in the form: 'services':[{'serv1':x}, {'serv2':y}], so we transform it to 'services':[x,y] based on\r
- # the services dict above. If for a specific service there is no applicable value, we put N/A \r
- for testbed in reps:\r
- d = list(testbed['services'])\r
- del testbed['services']\r
- testbed['services'] = []\r
- for s in services:\r
- set_v = 0\r
- for i in d:\r
- try:\r
- testbed['services'].append(i[s])\r
- set_v=1\r
- except:\r
- pass\r
- if set_v == 0 :\r
- testbed['services'].append('N/A')\r
- \r
- ###### Pass variables to template\r
- #env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
- env['serv_per_tb'] = json.dumps(serv_per_tb, ensure_ascii=False)\r
- env['reputation'] = reps\r
- env['rep_serv'] = services\r
- env['slicelist'] = all_exp\r
- env['json_data'] = json.dumps(all_exp, ensure_ascii=False)\r
- \r
- ###### *** Reputation Plugin-specific END *** ############\r
- \r
- \r
- if request.user.is_authenticated(): \r
- env['person'] = self.request.user\r
- else: \r
- env['person'] = None\r
- \r
- env['theme'] = self.theme\r
- #env['user_list']= user_list\r
-\r
- env['username']=the_user(request)\r
- env['topmenu_items'] = topmenu_items(None, request)\r
- if state: env['state'] = state\r
- elif not env['username']: env['state'] = None\r
- # use one or two columns for the layout - not logged in users will see the login prompt\r
- env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html" \r
- \r
- return render_to_response(self.template, env, context_instance=RequestContext(request))\r
- \r
-\r
-\r
- \r
-\r
- \r
- \r
- \r
- \r
-
\ No newline at end of file
+from django.contrib.auth import authenticate, login, logout
+from django.template import RequestContext
+from django.shortcuts import render, render_to_response
+
+from manifoldapi.manifoldresult import ManifoldResult
+from ui.topmenu import topmenu_items, the_user
+from myslice.configengine import ConfigEngine
+from manifold.core.query import Query
+from unfold.page import Page
+from manifoldapi.manifoldapi import execute_admin_query, execute_query
+from unfold.loginrequired import LoginRequiredAutoLogoutView
+
+from myslice.theme import ThemeView
+import json
+import hashlib
+import datetime
+import urllib2
+import ast
+import time
+
+from django.views.decorators.csrf import csrf_exempt
+from django.http import *
+
+
+def response_content_type(request):
+
+ if "application/json" in request.META['HTTP_ACCEPT']:
+ return "application/json"
+ else:
+ return "text/plain"
+
+
+def json_to_rest(url, data ):
+
+ req = urllib2.Request(url)
+ req.add_header('Content-Type', 'application/json')
+ response = urllib2.urlopen(req, json.dumps(data))
+
+ if data == "a":
+ mylist = ast.literal_eval(response.read())
+ else:
+ mylist = response.read().translate(None, '"[]').split(",")
+
+ return (mylist)
+
+
+def unix_to_timestamp(timest):
+ try:
+ return datetime.datetime.fromtimestamp(int(timest)).strftime('%Y-%m-%d %H:%M:%S')
+ except:
+ return timest
+
+def timestamp_to_unix(timest):
+ try:
+ pass
+ except:
+ pass
+
+
+def slice_to_exp(slices_users):
+ experiments = {}
+ testbeds = {}
+ wildcard_testbeds = {}
+
+
+ for slice in slices_users:
+ nodes={}
+ leases = slice['lease']
+
+ if leases is not None and leases:
+ for lease in leases:
+ resource = lease['resource']
+ start_t = lease['start_time']
+ end_t = lease['end_time']
+
+ testbed_start = resource.index('IDN+')+4
+ testbed_end = resource.index('+node+')
+
+ testbed = resource[testbed_start:testbed_end]
+ node = resource[testbed_end+6:]
+ if 'omf:nitos' in testbed:
+ testbed = 'omf:nitos'
+ if testbed in testbeds:
+ if node not in testbeds[testbed]:
+ testbeds[testbed].append(node)
+ else:
+ testbeds[testbed] = [node]
+
+ #group nodes in consecutive timeslots
+ if not node in nodes:
+ nodes[node]={str(start_t):{'start_t':start_t, 'nodes':node, 'end_t':end_t}}
+ else:
+ if not str(start_t) in nodes[node]:
+ f=0
+ for n in nodes[node]:
+ if n[str(end_t)] == start_t:
+ n[str(end_t)] == end_t
+ f=1
+ if f==0:
+ nodes[node][str(start_t)]={'start_t':start_t, 'nodes':node, 'end_t':end_t}
+
+ ######### FOR PLE LIKE start ##################
+ for resource in slice['resource']:
+ testbed_start = resource.index('IDN+')+4
+ testbed_end = resource.index('+node+')
+ tb = resource[testbed_start:testbed_end]
+ node = resource[testbed_end+6:]
+ if 'ple:' in tb:
+ tb = 'ple'
+ if 'omf:nitos' in tb:
+ tb = 'omf:nitos'
+ if tb not in testbeds:
+ try:
+ if node not in wildcard_testbeds[slice['slice_hrn']][tb]:
+ wildcard_testbeds[slice['slice_hrn']][tb].append([node])
+ except:
+ try:
+ wildcard_testbeds[slice['slice_hrn']][tb] = [node]
+ except:
+ wildcard_testbeds[slice['slice_hrn']]={tb:[node]}
+
+
+ else:
+ s = slice['slice_last_updated']
+ #s_time = int(time.mktime(datetime.datetime.strptime(s, "%Y%m%dT%H:%M:%Ss").timetuple()))
+ s_time = time.mktime(s.timetuple())
+
+ if slice['resource'] is not None:
+
+ for resource in slice['resource']:
+ testbed_start = resource.index('IDN+')+4
+ testbed_end = resource.index('+node+')
+ tb = resource[testbed_start:testbed_end]
+ if 'ple:' in tb:
+ tb = 'ple'
+ if 'omf:nitos' in tb:
+ tb = 'omf:nitos'
+ node = resource[testbed_end+6:]
+
+ if testbed in testbeds:
+ if node not in testbeds[testbed]:
+ testbeds[testbed].append(node)
+ else:
+ testbeds[testbed] = [node]
+
+ if not node in nodes:
+ #nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':int(time.time())}}
+ nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':s_time}}
+ ######### FOR PLE LIKE end ##################
+
+
+ #group grouped nodes in experiments
+ for n in nodes:
+ for exp in nodes[n]:
+ key = str(exp) + str(nodes[n][exp]['end_t']) + slice['slice_hrn']
+
+ if key not in experiments:
+ experiments[key]={'slice_hrn':slice['slice_hrn'], \
+ 'start':nodes[n][exp]['start_t'], 'end':nodes[n][exp]['end_t'], 'nodes':[nodes[n][exp]['nodes']]}
+
+
+ ######### FOR PLE LIKE start ##################
+ for item in wildcard_testbeds:
+ if item == experiments[key]['slice_hrn']:
+ for testbed in wildcard_testbeds[item]:
+
+ if testbed not in testbeds:
+ testbeds[testbed] = wildcard_testbeds[item][testbed]
+
+ for n in wildcard_testbeds[item][testbed]:
+ if n not in experiments[key]['nodes']:
+ experiments[key]['nodes'].append(n)
+ ######### FOR PLE LIKE end ##################
+
+ elif nodes[n][exp]['end_t'] == experiments[key]['end']:
+ experiments[key]['nodes'].append(nodes[n][exp]['nodes'])
+
+
+ ######### FOR PLE LIKE start ##################
+ for item in wildcard_testbeds:
+ if item == experiments[key]['slice_hrn']:
+ for testbed in wildcard_testbeds[item]:
+
+ if testbed not in testbeds:
+ testbeds[testbed] = wildcard_testbeds[item][testbed]
+
+ for n in wildcard_testbeds[item][testbed]:
+ if n not in experiments[key]['nodes']:
+ experiments[key]['nodes'].append(n)
+ ######### FOR PLE LIKE end ##################
+
+ return (experiments,testbeds)
+
+class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
+ template_name = 'reputation.html'
+
+ # expose this so we can mention the backend URL on the welcome page
+ def default_env (self):
+ return {
+ 'MANIFOLD_URL':ConfigEngine().manifold_url(),
+ }
+
+ def post (self,request):
+ env = self.default_env()
+ env['theme'] = self.theme
+
+ return render_to_response(self.template, env, context_instance=RequestContext(request))
+
+ def get (self, request, state=None):
+ env = self.default_env()
+
+ ##### *** Reputation Plugin-specific START *** ############
+ #The following 'if' is a dirty way for bypassing the JS AJAX cross-domain prevention policy...not pretty
+ if request.GET.has_key(u'slicedata[user_eval][overall]'):
+ dict_to_send = {}
+ dict_to_send['eid'] = str(request.GET[u'slicedata[id]'])
+ dict_to_send['slice_hrn'] = str(request.GET[u'slicedata[slice_hrn]'])
+ dict_to_send['user_hrn'] = str(request.GET[u'slicedata[user_hrn]'])
+ dict_to_send['start_tunix'] = str(request.GET[u'slicedata[start_tunix]'])
+ dict_to_send['end_tunix'] = str(request.GET[u'slicedata[end_tunix]'])
+ dict_to_send['start_t'] = str(request.GET[u'slicedata[start_t]'])
+ dict_to_send['end_t'] = str(request.GET[u'slicedata[end_t]'])
+ dict_to_send['testbeds'] = ast.literal_eval(str(request.GET[u'testbeds']))
+ dict_to_send['user_eval'] = {}
+ dict_to_send['user_eval']['reuse'] = str(request.GET[u'slicedata[user_eval][reuse]'])
+ dict_to_send['user_eval']['availability'] = str(request.GET[u'slicedata[user_eval][availability]'])
+ dict_to_send['user_eval']['pay'] = str(request.GET[u'slicedata[user_eval][pay]'])
+ dict_to_send['user_eval']['support'] = str(request.GET[u'slicedata[user_eval][support]'])
+ dict_to_send['user_eval']['overall'] = str(request.GET[u'slicedata[user_eval][overall]'])
+ dict_to_send['user_eval']['link_quality'] = str(request.GET[u'slicedata[user_eval][link_quality]'])
+ dict_to_send['user_eval']['problems'] = str(request.GET[u'slicedata[user_eval][problems]'])
+ dict_to_send['user_eval']['quality'] = str(request.GET[u'slicedata[user_eval][quality]'])
+
+ slicedata_received = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/json', dict_to_send )
+
+ return HttpResponse(json.dumps(slicedata_received), content_type = response_content_type(self.request))
+
+
+ slices_users = []
+
+ #get slices
+ userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease', 'slice_last_updated')
+ slice_details = execute_query(self.request, userslice_query)
+
+ #get local users
+ local_user_query = Query().get('local:user').select('email','status','config')
+ local_user_details = execute_admin_query(self.request, local_user_query)
+
+ #get users - create dict[email]=hrn
+ user_query = Query().get('user').select('user_hrn','user_urn','user_email')
+ user_details = execute_admin_query(self.request, user_query)
+ users_hrn = {}
+ for item in user_details:
+ users_hrn[item['user_email']] = item['user_hrn']
+
+ #get currenct username (email)
+ if request.user.is_authenticated():
+ cur_username = request.user.username
+
+ #get a list of all the slices for the logged in user
+ testbeds = []
+ #env['slices_users'] = json.dumps(slice_details, ensure_ascii=False)
+ for slice in slice_details:
+
+ if users_hrn[cur_username] in slice['users']:
+ slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \
+ , 'resource':slice['resource'], 'lease':slice['lease'], 'slice_last_updated':slice['slice_last_updated'] })
+
+
+ #env['slices_users'] = slices_users ### For logging
+ #####create slicelist for template & JSON
+ experiments,testbeds = slice_to_exp(slices_users)
+
+ all_exp = []
+ iddata = []
+
+ for exp in experiments:
+ experiment = {}
+ experiment['slice_hrn'] = experiments[exp]['slice_hrn']
+ experiment['user_hrn'] = users_hrn[cur_username]
+ experiment['start_tunix'] = experiments[exp]['start']
+ experiment['end_tunix'] = experiments[exp]['end']
+ experiment['start_t'] = unix_to_timestamp(experiments[exp]['start'])
+ experiment['end_t'] = unix_to_timestamp(experiments[exp]['end'])
+ experiment['testbeds'] = {}
+ for exp_node in experiments[exp]['nodes']:
+ list_testbeds = [ key for key,val in testbeds.items()]
+ for tkey in list_testbeds:
+ if exp_node in testbeds[tkey]:
+ if tkey in experiment['testbeds']:
+ if exp_node not in experiment['testbeds'][tkey]:
+ experiment['testbeds'][tkey].append(exp_node)
+ else:
+ experiment['testbeds'][tkey] = [exp_node]
+ tempid = hashlib.sha1(str(experiment)).hexdigest()
+ experiment['id'] = tempid
+
+ iddata.append(tempid)
+ all_exp.append(experiment)
+ env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)
+ env['slices_users'] = json.dumps(all_exp, ensure_ascii=False)
+ ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated
+
+ unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata)
+
+ for item in all_exp:
+ if item['id'] in unrated_exp:
+ pass
+ else:
+ all_exp.pop(all_exp.index(item))
+
+ ###### Get Reputation values from Reputation DB
+ reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a")
+ #env['logging_test'] = reps
+
+ #create a services list and a dict containing the services for each testbed
+ serv_per_tb = {}
+ services = []
+ for item in reps:
+ serv_per_tb[item['testbed']]=[]
+ for serv in item['services']:
+ if serv.keys()[0] not in services:
+ services.append(serv.keys()[0])
+ serv_per_tb[item['testbed']].append(serv.keys()[0])
+
+ #in json, sevices are in the form: 'services':[{'serv1':x}, {'serv2':y}], so we transform it to 'services':[x,y] based on
+ # the services dict above. If for a specific service there is no applicable value, we put N/A
+ for testbed in reps:
+ d = list(testbed['services'])
+ del testbed['services']
+ testbed['services'] = []
+ for s in services:
+ set_v = 0
+ for i in d:
+ try:
+ testbed['services'].append(i[s])
+ set_v=1
+ except:
+ pass
+ if set_v == 0 :
+ testbed['services'].append('N/A')
+
+ ###### Pass variables to template
+ #env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)
+ env['serv_per_tb'] = json.dumps(serv_per_tb, ensure_ascii=False)
+ env['reputation'] = reps
+ env['rep_serv'] = services
+ env['slicelist'] = all_exp
+ env['json_data'] = json.dumps(all_exp, ensure_ascii=False)
+
+ ###### *** Reputation Plugin-specific END *** ############
+
+
+ if request.user.is_authenticated():
+ env['person'] = self.request.user
+ else:
+ env['person'] = None
+
+ env['theme'] = self.theme
+ #env['user_list']= user_list
+
+ env['username']=the_user(request)
+ env['topmenu_items'] = topmenu_items(None, request)
+ if state: env['state'] = state
+ elif not env['username']: env['state'] = None
+ # use one or two columns for the layout - not logged in users will see the login prompt
+ env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
+
+ return render_to_response(self.template, env, context_instance=RequestContext(request))
+
+
+
+
+
+
+
+
+
+
page.add_js_files ( [ "js/common.functions.js" ] )
for key, value in kwargs.iteritems():
- print "%s = %s" % (key, value)
if key == "urn":
resource_urn=value
+import json
+import time
+import re
+
from django.shortcuts import render
+from django.shortcuts import render_to_response
+from django.template import RequestContext
from django.contrib.sites.models import Site
-
from unfold.page import Page
from manifold.core.query import Query
from ui.topmenu import topmenu_items_live, the_user
from myslice.theme import ThemeView
-
-import json, time, re
+from myslice.settings import logger
import activity.user
+theme = ThemeView()
class SliceRequestView (LoginRequiredAutoLogoutView, ThemeView):
template_name = 'slicerequest_view.html'
def get (self, request):
return self.get_or_post (request, 'GET')
- def get_or_post (self, wsgi_request, method):
+ def get_or_post (self, request, method):
"""
"""
+
errors = []
slice_name =''
purpose=''
authority_hrn = None
authority_name = None
# Retrieve the list of authorities
- authorities_query = Query.get('authority').select('name', 'authority_hrn')
- authorities = execute_admin_query(wsgi_request, authorities_query)
+ if self.theme == 'fed4fire':
+ authorities_query = Query.get('myslice:authority').select('authority_hrn')
+ else:
+ authorities_query = Query.get('authority').select('name', 'authority_hrn')
+ authorities = execute_admin_query(request, authorities_query)
if authorities is not None:
authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
- authorities = sorted(authorities, key=lambda k: k['name'])
+ if self.theme != 'fed4fire':
+ authorities = sorted(authorities, key=lambda k: k['name'])
# Get user_email (XXX Would deserve to be simplified)
user_query = Query().get('local:user').select('email','config')
- user_details = execute_query(wsgi_request, user_query)
+ user_details = execute_query(request, user_query)
user_email = user_details[0].get('email')
# getting user_hrn
for user_detail in user_details:
user_authority = user_config.get('authority','N/A')
# getting the org from authority
for authority in authorities:
- if authority['authority_hrn'] == user_authority:
+ if 'name' in authority and authority['authority_hrn'] == user_authority:
authority_name = authority['name']
# Handle the case when we use only hrn and not name
authority_name = user_authority
account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- account_details = execute_query(wsgi_request, account_query)
+ account_details = execute_query(request, account_query)
platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- platform_details = execute_query(wsgi_request, platform_query)
+ platform_details = execute_query(request, platform_query)
user_hrn = None
#getting user_hrn from local:account
for account_detail in account_details:
#else:
# pi = "is_pi"
- pi = authority_check_pis (wsgi_request, user_email)
- print "SLICEREQUESTVIEW.PY ----- pi=",pi
+ pi = authority_check_pis (request, user_email)
+ logger.debug("SLICEREQUESTVIEW.PY ----- pi= {}".format(pi))
# Page rendering
- page = Page(wsgi_request)
+ page = Page(request)
page.add_js_files ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
page.add_css_files ( [ "css/jquery-ui.css" ] )
page.expose_js_metadata()
# get the domain url
current_site = Site.objects.get_current()
current_site = current_site.domain
-
- # getting the authority_hrn from the selected organization
- for authority in authorities:
- if authority['name'] == wsgi_request.POST.get('org_name', ''):
- authority_hrn = authority['authority_hrn']
+
+ if theme.theme != 'fed4fire':
+ # getting the authority_hrn from the selected organization
+ for authority in authorities:
+ if authority['name'] == request.POST.get('org_name', ''):
+ authority_hrn = authority['authority_hrn']
# Handle the case when we use only hrn and not name
if authority_hrn is None:
- authority_hrn = wsgi_request.POST.get('org_name', '')
+ authority_hrn = request.POST.get('org_name', '')
# Handle project if used
- project = wsgi_request.POST.get('project', None)
+ project = request.POST.get('project', None)
if project is not None and project != '':
authority_hrn = project
+ slice_name = request.POST.get('slice_name', '')
+ if not slice_name or len(slice_name) == 0 :
+ errors.append('Slice name can\'t be empty')
+
+ # accept only lowercase names
+ slice_name = slice_name.lower()
+
slice_request = {
'type' : 'slice',
'id' : None,
'email' : user_email,
'timestamp' : time.time(),
'authority_hrn' : authority_hrn,
- 'organization' : wsgi_request.POST.get('org_name', ''),
- 'slice_name' : wsgi_request.POST.get('slice_name', ''),
- 'url' : wsgi_request.POST.get('url', ''),
- 'purpose' : wsgi_request.POST.get('purpose', ''),
+ 'organization' : request.POST.get('org_name', ''),
+ 'slice_name' : slice_name,
+ 'url' : request.POST.get('url', ''),
+ 'purpose' : request.POST.get('purpose', ''),
'current_site' : current_site
}
-
- # create slice_hrn based on authority_hrn and slice_name
- slice_name = slice_request['slice_name']
- req_slice_hrn = authority_hrn + '.' + slice_name
- # comparing requested slice_hrn with the existing slice_hrn
- slice_query = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
- slice_details_sfa = execute_admin_query(wsgi_request, slice_query)
+
+ # slice name is unique among all authorities
+ slice_query = Query().get('myslice:slice').select('slice_hrn')
+ slice_details_sfa = execute_admin_query(request, slice_query)
for _slice in slice_details_sfa:
- if _slice['slice_hrn'] == req_slice_hrn:
+ split_list = _slice['slice_hrn'].split('.')
+ sfa_slice_name = split_list[-1]
+ if sfa_slice_name == slice_name:
errors.append('Slice already exists. Please use a different slice name.')
# What kind of slice name is valid?
- if (slice_name is None or slice_name == ''):
+ if slice_name is None or slice_name == '':
errors.append('Slice name is mandatory')
- if (re.search(r'^[A-Za-z0-9_]*$', slice_name) == None):
+ if re.search(r'^[A-Za-z0-9_]*$', slice_name) is None:
errors.append('Slice name may contain only letters, numbers, and underscore.')
- organization = slice_request['organization']
- if (organization is None or organization == ''):
- errors.append('Organization is mandatory')
+ organization = slice_request['organization']
+ if theme.theme == 'fed4fire':
+ if organization is None or organization == '':
+ errors.append('Selecting project is mandatory')
+ else:
+ if organization is None or organization == '':
+ errors.append('Organization is mandatory')
+
+ slice_length= len(slice_request['slice_name'])
+ if slice_length >19:
+ errors.append('Slice name can be maximum 19 characters long')
purpose = slice_request['purpose']
- if (purpose is None or purpose == ''):
+ if purpose is None or purpose == '':
errors.append('Experiment purpose is mandatory')
url = slice_request['url']
if not errors:
- if is_pi(wsgi_request, user_hrn, authority_hrn):
+ if is_pi(request, user_hrn, authority_hrn):
# PIs can directly create slices in their own authority...
- create_slice(wsgi_request, slice_request)
- clear_user_creds(wsgi_request, user_email)
+ create_slice(request, slice_request)
+ clear_user_creds(request, user_email)
self.template_name = 'slice-request-done-view.html'
else:
- # Otherwise a wsgi_request is sent to the PI
- create_pending_slice(wsgi_request, slice_request, user_email)
+ # Otherwise a request is sent to the PI
+ create_pending_slice(request, slice_request, user_email)
self.template_name = 'slice-request-ack-view.html'
# log user activity
- activity.user.slice(wsgi_request)
-
- return render(wsgi_request, self.template, {'theme': self.theme}) # Redirect after POST
+ activity.user.slice(request)
+ return render_to_response(self.template, {'theme': self.theme, 'request':request}, context_instance=RequestContext(request))
+ #return render(request, self.template, {'theme': self.theme}) # Redirect after POST
else:
slice_request = {}
template_env = {
- 'username': wsgi_request.user.email,
+ 'username': request.user.email,
'topmenu_items': topmenu_items_live('Request a slice', page),
'errors': errors,
'slice_name': slice_name,
'cc_myself': True,
'authorities': authorities,
'theme': self.theme,
- 'section': "Slice request"
+ 'section': "Slice request",
+ 'request': request,
}
template_env.update(slice_request)
template_env.update(page.prelude_env())
- return render(wsgi_request, self.template, template_env)
+
+ return render_to_response(self.template,template_env, context_instance=RequestContext(request))
+ #return render(request, self.template, template_env)
+import json
+
from django.template import RequestContext
from django.shortcuts import render_to_response
+from django.views.generic.base import TemplateView
+from django.http import HttpResponse
+from django.shortcuts import render
from manifold.core.query import Query, AnalyzedQuery
from manifoldapi.manifoldapi import execute_query
-import json
-from django.views.generic.base import TemplateView
from unfold.loginrequired import LoginRequiredView
-from django.http import HttpResponse
-from django.shortcuts import render
-
from unfold.page import Page
from myslice.configengine import ConfigEngine
from plugins.univbrisfvf import UnivbrisFvf
from plugins.univbrisfvfo import UnivbrisFvfo
from plugins.univbristopo import UnivbrisTopo
-from plugins.univbrisvtam import UnivbrisVtam as UnivbrisVtamPlugin
+from plugins.univbrisvtam import UnivbrisVtam as UnivbrisVtamPlugin
from plugins.univbrisvtamform import UnivbrisVtamForm
from plugins.columns_editor import ColumnsEditor
from plugins.lists.simplelist import SimpleList
from myslice.theme import ThemeView
+from myslice.settings import logger
class SliceResourceView (LoginRequiredView, ThemeView):
template_name = "slice-resource-view.html"
slice_md = metadata.details_by_object('slice')
slice_fields = [column['name'] for column in slice_md['column']]
- print "SLICE RES VIEW fields = %s" % slice_fields
+ logger.debug("SLICE RES VIEW fields = {}".format(slice_fields))
# TODO The query to run is embedded in the URL
# Example: select slice_hrn, resource.urn, lease.resource, lease.start_time, lease.end_time from slice where slice_hrn == "ple.upmc.myslicedemo"
main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
page = page,
domid = "filter-status",
query = sq_resource,
+ query_lease = sq_lease,
)
apply = ApplyPlugin(
page = page,
# },
# )
- # # --------------------------------------------------------------------------
- # # SLA View and accept dialog
- #
- # sla_dialog = SlaDialog(
- # page = page,
- # title = 'sla dialog',
- # query = main_query,
- # togglable = False,
- # # start turned off, it will open up itself when stuff comes in
- # toggled = True,
- # domid = 'sla_dialog',
- # outline_complete = True,
- # username = request.user,
- # )
- #
- ## check user is pi or not
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
-
- # XXX When session has expired, this is None and thus not iterable
- for platform_detail in platform_details:
- for account_detail in account_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- # assigning values
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
+ # --------------------------------------------------------------------------
+ # SLA View and accept dialog
+
+ sla_dialog = SlaDialog(
+ page = page,
+ title = 'sla dialog',
+ query = main_query,
+ #togglable = False,
+ # start turned off, it will open up itself when stuff comes in
+ #toggled = True,
+ domid = 'sla_dialog',
+ #outline_complete = True,
+ username = request.user,
+ )
template_env = {}
+
+ template_env['request'] = self.request
+
template_env['list_resources'] = list_resources.render(self.request)
template_env['list_reserved_resources'] = list_reserved_resources.render(self.request)
template_env['list_reserved_leases'] = list_reserved_leases.render(self.request)
# template_env['vms_list'] = univbrisvtamplugin.render(self.request)
# template_env['vm_form'] = univbrisvtamform.render(self.request)
-# template_env['pending_resources'] = pending_resources.render(self.request)
- # template_env['sla_dialog'] = '' # sla_dialog.render(self.request)
+ # template_env['pending_resources'] = pending_resources.render(self.request)
+ template_env['sla_dialog'] = sla_dialog.render(self.request)
template_env["theme"] = self.theme
template_env["username"] = request.user
- template_env["pi"] = pi
template_env["slice"] = slicename
template_env["section"] = "resources"
template_env["msg"] = msg
from myslice.theme import ThemeView
from myslice.configengine import ConfigEngine
+from myslice.settings import logger
from sfa.planetlab.plxrn import hash_loginbase
import urllib2,json
class ExperimentView (FreeAccessView, ThemeView):
+ # parent View is portal/sliceview.py
+
template_name = 'slice-tab-experiment.html'
def get (self, request, slicename, state=None):
try:
for resources in current_resources:
list_res = resources['resource']
- #print "list_b4"
- #print list_res
for res in list_res:
split_list = res.split('+') # split the resource urn
- #print "list_after"
- #print split_list
if [s for s in split_list if 'ple' in s]: # find ple resources
res_hrn = split_list[-1] # last element is resource hrn
ple_resource_list.append(res_hrn)
nitos_resource_list.append(res_hrn)
- except Exception,e:
- print "Exception in slicetabexperiment.py in OneLab resource search %s" % e
+ except Exception as e:
+ logger.error("Exception in slicetabexperiment.py in OneLab resource search {}".format(e))
- #print "list of ple res hrns"
- #print ple_resource_list
- #print "list of nit_paris res hrns"
- #print nitos_paris_resource_list
- #print "list of iotLab res hrns"
- #print iotlab_resource_list
- #print "list of nitos res hrns"
- #print nitos_resource_list
+ #logger.debug("list of ple res hrns")
+ #logger.debug(ple_resource_list)
+ #logger.debug("list of nit_paris res hrns")
+ #logger.debug(nitos_paris_resource_list)
+ #logger.debug("list of iotLab res hrns")
+ #logger.debug(iotlab_resource_list)
+ #logger.debug("list of nitos res hrns")
+ #logger.debug(nitos_resource_list)
all_users = list()
#get all iotlab users
res = urllib2.urlopen(req)
all_users = json.load(res)
except urllib2.URLError as e:
- print "There is a problem in getting iotlab users %s" % e.reason
+ logger.error("There is a problem in getting iotlab users {}".format(e.reason))
#getting the login from email
for user in all_users:
if user['email'] == username:
iot_login = user['login']
-
- return render_to_response(self.template, { 'theme' : self.theme,'slicename':slicename, 'ple_slicename':ple_slicename, 'username':username, 'ple_resources':ple_resource_list, 'nitos_resources': nitos_resource_list, 'nitos_paris_resources':nitos_paris_resource_list, 'iotlab_resources':iotlab_resource_list, 'iot_login':iot_login }, context_instance=RequestContext(request))
+ env = { 'theme' : self.theme,
+ 'slicename':slicename,
+ 'ple_slicename':ple_slicename,
+ 'username':username,
+ 'ple_resources':ple_resource_list,
+ 'nitos_resources': nitos_resource_list,
+ 'nitos_paris_resources':nitos_paris_resource_list,
+ 'iotlab_resources':iotlab_resource_list,
+ 'iot_login':iot_login,
+ 'request':self.request,
+ }
+ return render_to_response(self.template, env, context_instance=RequestContext(request))
from myslice.theme import ThemeView
class SliceTabMeasurements (LoginRequiredView, ThemeView):
- template_name = "slice-tab-measurement.html"
+ template_name = "slice-tab-measurements.html"
def get(self, request, slicename):
- return render_to_response(self.template, {"theme": self.theme, "username": request.user, "slice" : slicename, "section":"measurements"}, context_instance=RequestContext(request))
+ return render_to_response(self.template, {"theme": self.theme, "username": request.user, "slicename" : slicename, "section":"measurements"}, context_instance=RequestContext(request))
template_name = "slice-view.html"
def get(self, request, slicename):
- ## check user is pi or not
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
- for platform_detail in platform_details:
- for account_detail in account_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- # assigning values
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
- return render_to_response(self.template, {"slice": slicename, "theme": self.theme, "username": request.user,"pi":pi, "section": "Slice %s" % slicename }, context_instance=RequestContext(request))
+
+ return render_to_response(self.template,
+ {"slice" : slicename,
+ "theme" : self.theme,
+ "username" : request.user,
+ "section" : "Slice {}".format(slicename),'request':request },
+ context_instance=RequestContext(request))
color:#333333;
}
h3 {
- font-size:13pt;
+ font-size:12pt;
+ letter-spacing:0.6pt;
+ color:#201E62;
+}
+h4 {
+ font-size:12pt;
+ letter-spacing:0.6pt;
+ color:#201E62;
+}
+label {
+ font-weight:normal;
+ font-size:13px;
color:#201E62;
}
input[type=checkbox] {
div.secondary .account a {
color:black;
}
-div.dashboard div {
- margin:25px 0;
+
+div.home {
+ padding-top:50px;
+}
+div.home h1 {
+ font-size:22pt;
+ border:0;
+}
+div.home h3, div.home h4 {
+ color:#424242;
+ line-height:1.4em;
+}
+
+div.home h3 a {
+ color:#FD6D2C;
}
div.dashboard {
- text-align:center;
+}
+div.dashboard a {
+ color:#206090;
+}
+
+div.dashboard a:hover {
+ text-decoration:underline;
+}
+div.dashboard div.projects-tree {
+ margin-left:49px;
}
div.dashboard ul {
+ list-style-type:disc;
+ list-style-position:inside;
text-align:left;
- margin-left:24px;
+ margin:0 0 15px 0;
+ padding:0;
+
+}
+div.dashboard ul ul {
+ margin:5px 0 15px 25px;
list-style:none;
}
+div.dashboard li {
+ margin:0 0 5px 0;
+ padding:0;
+}
+div.dashboard ul ul li {
+ margin:0;
+}
+div.dashboard ul ul a {
+}
+div.dashboard h3 {
+ border-bottom:1px solid #E0E0E0;
+ margin-right:15px;
+ margin-bottom:25px;
+}
+div.dashboard h3 a {
+ color:#201E62;
+}
+div.dashboard h3 img {
+ margin:15px 15px 15px 0;
+}
+div.dashboard span.glyphicon {
+ text-align:center;
+ width:45px;
+ height:25px;
+}
+div.dashboard-create-slice {
+ display:none;
+}
+div.experiment-tools {
+}
+div.experiment-tools h4 {
+ border-bottom:1px solid #E0E0E0;
+ margin:25px 15px 25px 0;
+ padding-bottom:5px;
+}
+div.experiment-tools .jfed {
+ text-align:center;
+ margin-right:25px;
+}
+div.experiment-tools button {
+ margin:0;
+ padding:7px 10px 4px 0;
+ color:white;
+ vertical-align:middle;
+}
+
+div.experiment-tools button span {
+ margin:0;
+ padding:0;
+}
+
div.dataTables_filter label{
float:left;
width:400px;
color:gray;
font-size:10pt;
}
+
+.sublabel {
+ color:gray;
+ font-style:italic;
+ font-weight:normal;
+}
+.tab-pane {
+ padding-top:25px;
+}
/* Service Directory */
div#appservices div.row {
font-size:12pt;
color:#333333;
}
+ul {
+ margin:0 0 0 15px;
+ padding:0;
+}
+li {
+}
span.subtitle {
color:#454545;
font-size:9pt;
text-decoration:underline;
}
.tab-pane {
- padding-top:15px;
}
/* buttons */
button.btn, input.btn {
div.sl-filter-facilities h4 {
margin-bottom:15px;
+}
+.sl-menu {
+ padding:0;
+}
+.sl-menu h4 {
+ margin:0 0 15px 0;
+ padding:0;
+}
+.sl-menu ul {
+ list-style:none;
+ margin:0;
+ padding:0;
+}
+.sl-menu li {
+ color:gray;
+ cursor:pointer;
+ padding:4px 8px;
+}
+.sl-menu li img {
+ vertical-align:top;
+}
+.sl-menu li.active {
+ color:black;
+}
+.sl-menu-item {
}
img.sl-image {
margin:0 5px 5px 0;
if ( typeof String.prototype.startsWith != 'function' ) {
String.prototype.startsWith = function( str ) {
return this.substring( 0, str.length ) === str;
- }
+ };
};
if ( typeof String.prototype.endsWith != 'function' ) {
String.prototype.endsWith = function( str ) {
return this.substring( this.length - str.length, this.length ) === str;
- }
+ };
};
// http://stackoverflow.com/questions/646628/javascript-startswith
// FROM Triptych : http://stackoverflow.com/users/43089/triptych
// http://stackoverflow.com/questions/979256/how-to-sort-an-array-of-javascript-objects
// data.sort(sort_by('city', false, function(a){return a.toUpperCase()}));
-var sort_by = function(field, reverse, primer){
+var sort_by = function(field, reverse, primer) {
- var key = function (x) {return primer ? primer(x[field]) : x[field]};
+ var key = function(x) { return primer ? primer(x[field]) : x[field]; };
//var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
- return function (a,b) {
+ return function(a,b) {
var A = key(a), B = key(b);
return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse];
//return ((A < B) ? -1 :
// (A > B) ? +1 : 0)) * [-1,1][+!!reverse];
- }
+ };
+};
+
+function escapeRegExp(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
+function unspin_all(){
+ $('input:checkbox').each(function (index) {
+ if(this.checked){
+ this.nextElementSibling.style.display = "none";
+ }
+ });
+}
+function spin_all(){
+ $('input:checkbox').each(function (index) {
+ if(this.checked){
+ this.nextElementSibling.style.display = "inline";
+ }
+ });
+}
$(document).ready(function() {
loadedTabs = [];
});
$('button#deleteusers').click(function() {
+ spin_all();
$('input:checkbox.user').each(function (index) {
if(this.checked){
var record_id = this.id;
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
}
});
/* TODO: factorize into functions */
$('button#deleteslices').click(function() {
+ spin_all();
var flag = false;
$('input:checkbox.slice').each(function (index) {
if(this.checked){
var record_id = this.id;
+ $('#'+record_id+'-loading').spin();
$.post("/delete/slice/",{'filters':{'slice_hrn':this.id}}, function(data) {
if(data.success){
localStorage.clear();
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
}
});
});
$('button#renewslices').click(function() {
+ spin_all();
var now = new Date();
/* In Javascript getMonth() gives month[0] = january, month[1] = february, and so on... */
var month = now.getMonth()+2;
$('input:checkbox.slice').each(function (index) {
if(this.checked){
var record_id = this.id;
+ $('#'+record_id+'-loading').spin();
$.post("/update/slice/",{'filters':{'slice_hrn':this.id},'params':{'expires':one_month_later}}, function(data) {
if(data.success){
// TODO: highlight row after success
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
}
//window.location="/portal/institution#slices";
});
$('button#deleteprojects').click(function() {
+ spin_all();
var flag = false;
$('input:checkbox.project').each(function (index) {
if(this.checked){
var record_id = this.id;
+ $('#'+record_id+'-loading').spin();
console.log(record_id);
$.post("/delete/myslice:authority/",{'filters':{'authority_hrn':this.id}}, function(data) {
if(data.success){
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
}
});
jQuery("#upload_file").click(function(){
jQuery("#span_upload").show();
- jQuery("#dl_file").hide();
+ jQuery("#dl_pubkey").hide();
jQuery("#upload_file").hide();
jQuery("#keyval").hide();
// enforcing when one edit is clicked the rest will not work at same time
jQuery("#span_upload").hide();
jQuery("#keyval").show();
- jQuery("#dl_file").show();
+ jQuery("#dl_pubkey").show();
jQuery("#upload_file").show();
});
});
var myslice = {
user: {},
- user: function() {
+ get_user: function() {
if ($.isEmptyObject(this.user)) {
//this.login(function() { return this.user; });
if(localStorage.getItem('user')!='undefined'){
},
projects: {},
- projects: function() {
+ get_projects: function() {
if ($.isEmptyObject(this.projects)) {
//this.login(function() { return this.user; });
if(localStorage.getItem('projects')!='undefined'){
// What are the projects under this authority?
$.post("/rest/myslice:authority/",{'fields':['authority_hrn'],'filters':{'authority_hrn':'CONTAINS'+auth}}, function( data ) {
$.each(data, function(idx, project) {
- console.log(project.authority_hrn);
if($.inArray(project.authority_hrn,projects) == -1){
projects.push(project.authority_hrn);
}
if(isFunction(fn)){
fn();
}
+ }else{
+ $('#credentials_msg').css('display','block');
}
});
}else{
+ $('#credentials_msg').css('display','block');
if(isFunction(fn)){
fn();
}
}
-
},
--- /dev/null
+function unspin_all_status(){
+ $('.portal__validate__checkbox').each(function (index) {
+ if(this.checked){
+ t_id = this.id.split('__');
+ status_id = t_id[t_id.length-2]+'__'+t_id[t_id.length-1]+'-status-loading';
+ $('#'+status_id).css('display','none');
+ }
+ });
+}
+function spin_all_status(){
+ $('.portal__validate__checkbox').each(function (index) {
+ if(this.checked){
+ t_id = this.id.split('__');
+ status_id = t_id[t_id.length-2]+'__'+t_id[t_id.length-1]+'-status-loading';
+ $('#'+status_id).css('display','inline');
+ }
+ });
+}
+ $(document).ready(function() {
+ $("li#nav-request").addClass("active");
+ $('table.requests').dataTable({
+ "sDom": "frtiS",
+ "bScrollCollapse": true,
+ "bStateSave": true,
+ "bPaginate": false,
+ "bLengthChange": false,
+ "bFilter": false,
+ "bSort": true,
+ "bInfo": false,
+ "bAutoWidth": true,
+ "bAutoHeight": false,
+ });
+ });
+ function on_click_event() {
+ var ids = [];
+ $('.portal__validate__checkbox').each(function(i, el) {
+ if ($(el).prop('checked')) {
+ // portal__validate__checkbox__slice__2
+ var id_array = $(el).attr('id').split('__');
+ // push(slice__2)
+ ids.push(id_array[3] + '__' + id_array[4]);
+ }
+ });
+ if (ids.length > 0) {
+ spin_all_status();
+ var id_str = ids.join('/');
+
+ // XXX spinner
+ $.getJSON('/portal/validate_action/' + id_str, function(status) {
+ $.each(status, function(request_type__id, request_status) {
+ // request_status: NAME -> dict (status, description)
+ var status_str = '';
+ $.each(request_status, function(name, result) {
+ if (status_str != '')
+ status_str += ' -- ';
+
+ if (result.status) {
+ status_str += '<font color="green">OK</font>';
+ $('#portal__validate__checkbox__' + request_type__id).hide();
+ } else {
+ status_str += '<font color="red">ERROR: ' + result.description + '</font>';
+ }
+ });
+ $('#portal__status__' + request_type__id).html(status_str);
+ });
+ unspin_all_status();
+ });
+ }
+ }
+ function on_click_reject() {
+ var ids = [];
+ $('.portal__validate__checkbox').each(function(i, el) {
+ if ($(el).prop('checked')) {
+ // portal__validate__checkbox__slice__2
+ var id_array = $(el).attr('id').split('__');
+ // push(slice__2)
+ ids.push(id_array[3] + '__' + id_array[4]);
+ }
+ });
+ if (ids.length > 0) {
+ spin_all_status();
+ var id_str = ids.join('/');
+
+ // XXX spinner
+ $.getJSON('/portal/reject_action/' + id_str, function(status) {
+ $.each(status, function(request_type__id, request_status) {
+ // request_status: NAME -> dict (status, description)
+ var status_str = '';
+ $.each(request_status, function(name, result) {
+ if (status_str != '')
+ status_str += ' -- ';
+
+ if (result.status) {
+ status_str += '<font color="green">Rejected</font>';
+ $('#portal__validate__checkbox__' + request_type__id).hide();
+ } else {
+ status_str += '<font color="red">ERROR: ' + result.description + '</font>';
+ }
+ });
+ $('#portal__status__' + request_type__id).html(status_str);
+ });
+ unspin_all_status();
+ });
+ }
+ }
if request.user.is_authenticated():
env['person'] = self.request.user
- ## check user is pi or not
- platform_query = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
- account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
- platform_details = execute_query(self.request, platform_query)
- account_details = execute_query(self.request, account_query)
- for platform_detail in platform_details:
- for account_detail in account_details:
- if platform_detail['platform_id'] == account_detail['platform_id']:
- if 'config' in account_detail and account_detail['config'] is not '':
- account_config = json.loads(account_detail['config'])
- if 'myslice' in platform_detail['platform']:
- acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
- # assigning values
- if acc_auth_cred == {} or acc_auth_cred == 'N/A':
- pi = "is_not_pi"
- else:
- pi = "is_pi"
- env['pi'] = pi
else:
env['person'] = None
if state: env['state'] = state
elif not env['username']: env['state'] = None
# use one or two columns for the layout - not logged in users will see the login prompt
-
+ env['request'] = request
return render_to_response(self.template, env, context_instance=RequestContext(request))
$(document).ready(function() {
$.get('/monitor/services', function(result) {
for (var r in result) {
- html = '<div class="col-xs-6 col-sm-4 col-md-3 s-monitor"><div class="row">';
- html += '<div class="col-md-2"><img src="{{ STATIC_URL }}icons/'+result[r].status+'.png"></div>';
- html += '<div class="col-md-8">';
- html += '<h4>'+result[r].name+'<h4>';
- html += '<span class="subtitle">'+result[r].type+'</span>';
- if (typeof(result[r].version) != 'undefined')
- html += ' <span class="version">version '+result[r].version+'</span>';
- html += '</div></div></div>';
+ if(r == 'error'){
+ html = '<div style="padding-left:20px;">no monitoring available</div>'
+ }else{
+ html = '<div class="col-xs-6 col-sm-4 col-md-3 s-monitor"><div class="row">';
+ html += '<div class="col-md-2"><img src="{{ STATIC_URL }}icons/'+result[r].status+'.png"></div>';
+ html += '<div class="col-md-8">';
+ html += '<h4>'+result[r].name+'<h4>';
+ html += '<span class="subtitle">'+result[r].type+'</span>';
+ if (typeof(result[r].version) != 'undefined')
+ html += ' <span class="version">version '+result[r].version+'</span>';
+ html += '</div></div></div>';
+ }
$('div#monitor-services').append(html);
}
});
</ul>
</div>
</li>
- {%if 'is_pi' in pi %}
+ {% if request.session.user.pi %}
<li id="nav-institution" class=""><a href="/institution">MANAGEMENT</a></li>
- {%endif%}
+ {%endif%}
<li><a href="/support/">SUPPORT</a></li>
</ul>
</div>
{% load portal_filters %}
{# This is required by insert_above #}{% insert_handler %}<!DOCTYPE html>
-<html lang="en"><head>
+<html lang="en">
+<head>
<title>{{theme}} portal - {{ section }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="{{ STATIC_URL }}js/jquery.dataTables.min.js"></script>
<script src="{{ STATIC_URL }}js/jquery.qtip.min.js"></script>
<script src="{{ STATIC_URL }}js/bootstrap.datatables.js"></script>
-<!-- <script src="{{ STATIC_URL }}js/stash.min.js"></script> -->
+<script src="{{ STATIC_URL }}js/common.functions.js"></script>
<script src="{{ STATIC_URL }}js/myslice.js"></script>
<script src="{{ STATIC_URL }}js/myslice-ui.js"></script>
+
+<script type="text/javascript" src="{{STATIC_URL}}/js/spin-presets.js"></script>
+<script type="text/javascript" src="{{STATIC_URL}}/js/spin.min.js"></script>
+<script type="text/javascript" src="{{STATIC_URL}}/js/jquery.spin.js"></script>
+
<style type="text/css">{# In case we need to add raw css code #}{% container prelude_css %}</style>
{{ header_prelude }}
{% block head %} {% endblock head %}
$(document).ready(function() {
{% if username %}
myslice.login(function(){
- user = myslice.user();
+ user = myslice.get_user();
var slices = [];
if($.isEmptyObject(user)){
slices.push("no slice");
}else{
slices = user.slices;
+ {% if theme != "fed4fire" %}
drawSlices(slices);
+ {% endif %}
}
{% if theme == "fed4fire" %}
- p = myslice.projects();
+ p = myslice.get_projects();
if(p != null){
- drawProjects(p);
+ //drawProjects(p);
+ drawProjectsTree(p,slices);
}
{% endif %}
});
$("div#home-project-list").html($( "<ul/>", { html: items.join( "" ) }));
$("ul#dropdown-project-list").append(items.join( "" ));
}
+ function drawProjectsTree(projects,slices) {
+ var items = [];
+ var items_sl = [];
+ $.each( projects, function(i, p) {
+ $.each( slices, function(y, s) {
+ if (s.match('^' + escapeRegExp(p))) {
+ items_sl.push( "<li><a href=\"/resources/" + s + "\">" + s.replace(p + '.','') + "</a></li>" );
+ }
+ });
+ el = "<li><a href=\"/portal/project/" + p + "\">" + p + "</a>";
+ if (items_sl.length > 0) {
+ el += "<ul>" + items_sl.join( "" ) + "</ul>";
+ }
+ el += "</li>";
+ items.push(el);
+ items_sl = [];
+ });
+ $("div#home-project-tree").html($( "<ul/>", { html: items.join( "" ) }));
+ if (projects.length > 0) {
+ $('.dashboard-create-slice').show();
+ }
+ }
+
+ window.setTimeout(function() {
+ $('.projects-loading').hide();
+ },20000);
{% endif %}
{% endif %}
jQuery('[title!=""]').qtip();
<ul class="nav nav-tabs nav-section">
<li class="active"><a href="#profile">User Profile</a></li>
<li><a href="#account">Account</a></li>
- <li><a href="#access">Testbed Access</a></li>
</ul>
</div>
</div>
{%endif%}
</div>
</div>
-
-
- <div class="tab-pane row" id="access">
- <div class="col-md-12">
-
- <h3>Testbed Access <small>Reference Accounts in the following testbeds</small></h3>
- <table class="mytable table table-bordered table-hover">
- <tr class="odd">
- <th>Platform</th>
- <th>Account Type</th>
- <th>Reference to</th>
- <th>Remove Account</th>
- </tr>
- {% for row in ref_acc %}
- <tr class="border_bottom">
- <td class="odd"> {{ row.platform_name }} </td>
- <td class="odd"> {{ row.account_type }} </td>
- <td class="odd"> {{ row.account_reference }} </td>
- <td class="odd">
- <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform" onclick="javascript:document.getElementById('button_value').value='delete_{{row.platform_name}}';">
- <span class="glyphicon glyphicon-minus"></span>
- </button>
- </td>
- </tr>
- {%endfor%}
- </table>
-
-
- <h3>Add reference account to the following testbeds</h3>
- <table class="mytable table table-bordered table-hover">
- <tr class="odd">
- <th>Platforms</th>
- <th>Add Account</th>
- </tr>
- {% for platform in platform_list %}
- <tr class="border_bottom">
- <td class="odd"> {{ platform.platform_no_access }} </td>
- <td class="odd">
- <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform" onclick="javascript:document.getElementById('button_value').value='add_{{platform.platform_no_access}}';">
- <span class="glyphicon glyphicon-plus"></span>
- </button>
- </td>
- </tr>
- {%endfor%}
- </table>
- </div>
{%endif%}
</div>
-</div>
</form>
<script>
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<p>We have received a user signup request for your email address at {{current_site}}</p>
<p>You have the following user details:</p>
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<b>Email :</b> {{email}}
{% widget '_widget-news.html' %}
</div> -->
{% if username %}
+
+{% block head %}
+<script type="text/javascript" src="https://java.com/js/dtjava.js"></script>
+{% endblock head %}
+
{% widget "_widget-no_credentials.html" %}
<div class="container dashboard">
<div class="row">
+ <div class="col-md-12" id="credentials_msg" style="display:none;">
{%if 'no_creds' in user_cred %}
<p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
{%endif%}
{%if 'creds_expired' in user_cred %}
<p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">EXPIRED CREDENTIALS</a> Please delegate again your credentials to the portal!</p>
{%endif%}
- <div class="col-md-3">
- <h3>
- EXPERIMENT
- </h3>
- <div>
- <a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a>
- </div>
- <div>
- <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create Slice</button>
- </div>
- <div>
- <p><strong>Your slices </strong>
- <span title="A slice is a set of testbed resources on which you can conduct an experiment.
- Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'.
- However, on the Fed4FIRE portal, you will only see slices that you have created through Fed4FIRE. If you have created slices elsewhere,
- those slices will not appear here."
- class="glyphicon glyphicon-info-sign">
- </span>
-
- </p>
- </div>
- <div>
- <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
- </div>
- <h3 title="Some tools do their own slice creation and management.">Experiment now</h3>
- <a class="btn btn-primary" style="width: 150px;"
- href='http://jfed.iminds.be/releases/5.4-dev/r2289/webstart/experimenter/jfed-experimenter.jnlp'
- title="Click here to start your experiment with jFed"
- onclick="return launchApplication('http://jfed.iminds.be/releases/5.4-dev/r2289/webstart/experimenter/jfed-experimenter.jnlp');">
- <span class="glyphicon glyphicon-cloud"></span> jFed</a>
- </div>
- <div class="col-md-3">
- <h3>MANAGEMENT</h3>
- <div>
- <a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color.png" alt="" /></a>
- </div>
- <div>
- <button id="projectrequestbtn" type="button" class="btn btn-default" style="width:165px;"><span class="glyphicon glyphicon-plus"></span> Join Project</button>
- </div>
- <div>
- <button id="validaterequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Validate Requests</button>
- </div>
- <div>
- <p><strong>Your projects </strong>
- <span title="A project is a sub-authority under the responsability of your institution gathering users, who will be able to create slices for their experiments."
- class="glyphicon glyphicon-info-sign">
- </span>
- </p>
- </div>
- <div>
- <div id="home-project-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading projects" /></div>
- </div>
-
- </div>
- <div class="col-md-3">
- <h3>
- SUPPORT
- </h3>
- <div>
- <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a>
- </div>
- <div>
- <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
- </div>
- <p></p>
- <div>
- <button id="statbtn" type="button" style="width: 170px;" class="btn btn-default"><span class="glyphicon glyphicon-stats" style="margin-right: 10px;"></span>Testbeds' status</button>
- </div>
- <div>
- <button id="repbtn" type="button" style="width: 170px;" class="btn btn-default"><span class="glyphicon glyphicon-stats"></span>Testbeds' reputation</button>
- </div>
- </div>
-
- <div class="col-md-3">
- <h3>
- ACCOUNT
- </h3>
- <div>
- <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a>
- </div>
- <div>
- <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
- </div>
- <div>
- {% if person.last_name %}
- {{person.first_name}} {{person.last_name}}<br />
- {% endif %}
- <span class="label">Username:</span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
- </div>
- </div>
- </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-4">
+ <h3>
+ <img src="{{ STATIC_URL }}img/icon_slices_small.png" alt="" />EXPERIMENT
+ </h3>
+ <div>
+ <span class="glyphicon glyphicon-cog"></span> <a href="/portal/project_request/">Create/Join project</a>
+ </div>
+ <div class="dashboard-create-slice">
+ <span class="glyphicon glyphicon-plus"></span> <a href="/portal/slice_request/">Create slice</a>
+ </div>
+ <div class="projects-tree">
+ Your projects and slices
+ <span title="A <b>slice</b> is a set of testbed resources on which you can conduct an experiment.
+ Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'.
+ However, on the Fed4FIRE portal, you will only see slices that you have created through Fed4FIRE. If you have created slices elsewhere,
+ those slices will not appear here. <br /><br /> A <b>project</b> is a sub-authority under the responsability of your institution gathering users,
+ who will be able to create slices for their experiments." class="glyphicon glyphicon-info-sign"> </span>
+
+ <div id="home-project-tree"><img class="projects-loading" src="{{ STATIC_URL }}img/loading.gif" alt="Loading projects" /></div>
+ </div>
+
+ <div class="experiment-tools">
+ <h4 title="Some tools do their own slice creation and management.">Experiment now</h4>
+
+ <p class="jfed">
+ <button id="start" class="btn btn-primary" type="button" onclick="launchjFed()"><span class="glyphicon glyphicon-cloud"></span> Start jFed</button>
+ </p>
+ <div id='java7Dialog' title="Old Java version detected" >
+ <p>The latest version of jFed is only compatible with Java 8 or higher. We detected that you are using an older version.</p>
+ <p>Please upgrade to Java 8 to get access to the newest version of jFed. Otherwise, you can use jFed 5.3.2, which is Java 7-compatible.</p>
+ </div>
+
+ <div id='noJavaDialog' title="No Java detected" >
+ <p>jFed requires Java to run. We however couldn't detect a Java installation in your browser.</p>
+ <p>Please install the latest version of Java to continue.</p>
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-4">
+ <div class="row">
+ <div class="col-sm-12">
+ <h3>
+ <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_small.png" alt="" /></a><a href="/portal/account/">ACCOUNT</a>
+ </h3>
+ {% if person.last_name %}
+ <p>
+ {{person.first_name}} {{person.last_name}}
+ </p>
+ {% endif %}
+ <p>
+ <span class="glyphicon glyphicon-user"></span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+ </p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-12">
+ <h3>
+ <a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color_small.png" alt="" /></a><a href="/portal/institution">MANAGEMENT</a>
+ </h3>
+
+ <div>
+ <span class="glyphicon glyphicon-ok"></span> <a href="/portal/institution#requests">Validate Requests</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-4">
+ <div class="row">
+ <div class="col-sm-12">
+ <h3>
+ <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support_small.png" alt="" /></a><a href="/portal/support">SUPPORT</a>
+ </h3>
+ <p>
+ <span class="glyphicon glyphicon-envelope"></span> <a href="/portal/contact/">Contact</a>
+ </p>
+ <p>
+ <span class="glyphicon glyphicon-stats"></span> <a target="_blank" href="https://flsmonitor.fed4fire.eu">Testbeds' status</a>
+ </br />
+ <span class="glyphicon glyphicon-stats"></span> <a href="/portal/reputation">Testbeds' reputation</a>
+
+ </p>
+ <p>
+ <span class="glyphicon glyphicon-book"></span> <a target="_blank" href="http://doc.fed4fire.eu/">Documentation</a>
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
{% else %}
-<div class="container-fluid home">
+<div class="container home">
<div class="">
- <div class="col-sm-2"></div>
- <div class="col-sm-4 slogan">
- <h2>
+ <div class="col-sm-4 col-sm-offset-1 slogan">
+ <h1>
Fed4FIRE Portal
- </h2>
+ </h1>
<h3>
- Your easy access to Future Internet Research and Experimentation testbeds belonging to the Fed4FIRE federation.
+ Your easy access to Future Internet Research and Experimentation testbeds belonging to the
+ <a target="_blank" href="http://www.fed4fire.eu/">Fed4FIRE</a> federation.
</h3>
- <h3>
+ <br />
+ <h4>
<a href='http://doc.fed4fire.eu'>Want to learn more?</a>
- </h3>
+ </h4>
</div>
<div class="col-sm-4 col-sm-offset-1" style="width:400px; top:16px; float:left;">
<div class="row">
{% widget '_widget-login-user.html' %}
</div>
</div>
- <div class="col-sm-1"></div>
</div>
</div>
+
+<script type="text/javascript">
+ $(document).ready(function() {
+ localStorage.clear();
+ });
+</script>
+
{% endif %}
<script type="text/javascript">
+ var config = {
+ java8_jnlp: 'http://jfed.iminds.be/jfed-f4f-java8.jnlp',
+ java7_jnlp: 'http://jfed.iminds.be/jfed-f4f-java7.jnlp'
+ };
+
+ var certkey = "{{jfed_identity}}";
+
$(document).ready(function() {
{%if 'no_creds' in user_cred or 'creds_expired' in user_cred %}
localStorage.clear();
+ /*
$.post("/cache/clear/", function( data ) {
});
+ */
{% endif %}
$('a.home-tab').click(function() {
$('ul.nav-tabs li').removeClass('active');
$('div.home-panel').hide();
$('div#'+$(this).data('panel')).show();
});
- $('button#validaterequestbtn').click(function() {
- window.location="/portal/institution#requests";
- });
- $('button#ticketbtn').click(function() {
- window.location="/portal/contact/";
- });
- $('button#statbtn').click(function() {
- window.location="https://flsmonitor.fed4fire.eu";
- });
- $('button#repbtn').click(function() {
- window.location="/portal/reputation";
- });
- $('button#signupbtn').click(function() {
- window.location="/portal/register/";
- });
- $('button#slicerequestbtn').click(function() {
- window.location="/portal/slice_request/";
- });
- $('button#projectrequestbtn').click(function() {
- window.location="/portal/project_request/";
- });
-
- myslice.loadSlices();
-});
-</script>
-
-<!--for jfed tool-->
-<script type="text/javascript" src="{{STATIC_URL}}js/fed4fire_dtjava_orig.js"></script>
-<script>
- function launchApplication(jnlpfile) {
- dtjava.launch(
- { url : jnlpfile },
- {
- javafx : '2.2+',
- toolkit: 'swing'
- },
- {}
- );
- return false;
- }
+
+ });
</script>
-{# widget "_widget-monitor.html" #}
-{# widget "_widget-stats-top-slices.html" #}
-
+<script src='https://authority.ilabt.iminds.be/js/jquery/jquery-ui.min.js'></script>
+<script src="//java.com/js/dtjava.js"></script>
+<script src='https://authority.ilabt.iminds.be/js/jfed_webstart_f4fportal.js'></script>
+<link rel='stylesheet' href='https://authority.ilabt.iminds.be/js/jquery/jquery-ui.css' />
{% endblock %}
{% block head %}
<script type="text/javascript" src="{{STATIC_URL}}/js/institution.js"></script>
+<script type="text/javascript" src="{{STATIC_URL}}js/requests.js"></script>
{% endblock head %}
{% block content %}
<li><a href="#users">Users</a></li>
{% if not project %}
<li><a href="#projects">Projects</a></li>
- {% endif %}
+ {% else %}
<li><a href="#slices">Slices</a></li>
+ {% endif %}
<li><a href="#requests">Requests</a></li>
</ul>
</div>
<div class="tab-pane row" id="users" data-authority="{{user_details.parent_authority}}">
<div class="col-md-12 el">
- <div id="user-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+ <div id="user-tab-loading" style="padding-bottom:10px;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
<div id="user-tab-loaded" style="display:none;">
<table id="user-tab" class="table">
<tr>
{% if not project %}
<div class="tab-pane row" id="projects" data-authority="{{user_details.parent_authority}}">
<div class="col-md-12 el">
- <div id="project-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Projects" /></div>
+ <div id="project-tab-loading" style="padding-bottom:10px;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Projects" /></div>
<div id="project-tab-loaded" style="display:none;">
<table id="project-tab" class="table">
<tr>
{% endif %}
<div class="tab-pane row" id="slices">
<div class="col-md-12 el">
- <div id="slice-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+ <div id="slice-tab-loading" style="padding-bottom:10px;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
<div id="slice-tab-loaded" style="display:none;">
<table id="slice-tab" class="table">
<tr>
</div>
</div>
<div class="tab-pane row" id="requests">
+ <div id="spinner" style="padding-top:40px; padding-left:40px;"></div>
</div>
</div>
<script>
$(document).ready(function() {
{% if person %}
{% if user_details.parent_authority %}
-
+ $('#spinner').spin();
+
$.post("/rest/myslice:slice/",{'fields':['slice_hrn','users','url','slice_date_created'],'filters':{'parent_authority':'{{user_details.parent_authority}}'}}, function( data ) {
var list_slices = [];
var table_slices = [];
}else{
nodes_length=val.nodes.length;
}
- //console.log(val);
if(val.users=="undefined" || val.users==null){
users_length=0;
}else{
}
slice_row = "<tr id='"+val.slice_hrn+"'>";
- slice_row += "<td><input type='checkbox' class='slice' id='"+val.slice_hrn+"'></td>";
+ slice_row += "<td><input type='checkbox' class='slice' id='"+val.slice_hrn+"'><div id='"+val.slice_hrn+"-loading' style='display:none;padding-left:3px;'><img src='{{ STATIC_URL }}img/loading.gif'></div></td>";
// filter links to slices, only those that the user has credentials for
s = myslice.user.slices;
var table_users = [];
$.each( data[0].pi_users, function( key, val ) {
- //console.log(val);
user_row = "<tr id='"+val+"'>";
- user_row += "<td><input type='checkbox' class='user' id='"+val+"'></td>";
+ user_row += "<td><input type='checkbox' class='user' id='"+val+"'><div id='"+val+"-loading' style='display:none;padding-left:3px;'><img src='{{ STATIC_URL }}img/loading.gif'></div></td>";
user_row += "<td>"+val+"</td>";
user_row += "</tr>";
table_users.push(user_row);
$.each( data, function( key, val ) {
list_users.push( "<li><a href=\"portal/user/"+val.user_email+"\">" + val.user_email + "</a></li>" );
user_row = "<tr id='"+val.user_hrn+"'>";
- user_row += "<td><input type='checkbox' class='user' id='"+val.user_hrn+"' data-email='"+val.user_email+"'></td>";
+ user_row += "<td><input type='checkbox' class='user' id='"+val.user_hrn+"' data-email='"+val.user_email+"'><div id='"+val.user_hrn+"-loading' style='display:none;padding-left:3px;'><img src='{{ STATIC_URL }}img/loading.gif'></div></td>";
user_row += "<td>"+val.user_email+"</td>";
user_row += "<td>"+val.user_hrn+"</td>";
/*
var table_projects = [];
$.each( data, function( key, val ) {
- console.log(val);
project_row = "<tr id='"+val.authority_hrn+"'>";
- project_row += "<td><input type='checkbox' class='project' id='"+val.authority_hrn+"'></td>";
+ project_row += "<td><input type='checkbox' class='project' id='"+val.authority_hrn+"'><div id='"+val.authority_hrn+"-loading' style='display:none;padding-left:3px;'><img src='{{ STATIC_URL }}img/loading.gif'></div></td>";
// filter links to projects, only those that the user has credentials for
p = myslice.projects;
} else {
$('.nav-tabs a[href=#about]').click();
}
-});
-//upgrade users to PI
-$(document).ready(function() {
+ //upgrade users to PI
$('button#makepi').click(function() {
+ spin_all();
var flag = false;
var pi_users = [];
$.post("/rest/myslice:authority/",{'filters':{'authority_hrn': '{{user_details.parent_authority}}'}}, function( data ) {
if(this.checked){
var record_id = this.id;
pi_users.push(record_id)
+ $.post("/credentials/clear/",{'emails':[this.dataset['email']]}, function(data) {
+ }); // post credentials clear
flag = true;
}
});
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
}
});
});
-});
//downgrade to user [in projects:remove from project]
-$(document).ready(function() {
$('button#removepi').click(function() {
+ spin_all();
var flag = false;
var pi_users = [];
$.post("/rest/myslice:authority/",{'filters':{'authority_hrn': '{{user_details.parent_authority}}'}}, function( data ) {
for (var i=pi_users.length-1; i>=0; i--) {
if (pi_users[i] === record_id) {
pi_users.splice(i, 1);
+ $.post("/credentials/clear/",{'emails':[this.dataset['email']]}, function(data) {
+ }); // post credentials clear
+ flag = true;
}
}
- flag = true;
}
});
if(flag == true){
mysliceAlert('Rest Error for: '+data.error,'warning', true);
//alert("Rest Error for "+record_id+": "+data.error);
}
+ unspin_all();
});
+ }else{
+ mysliceAlert('No action: User had no rights on: {{user_details.parent_authority}}','success', true);
+ unspin_all();
}
});
});
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<p>Dear Fed4FIRE user,</p>
+<p></p>
+<p>You have recently requested to join a project in the Fed4FIRE portal.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<p></p>
+<br>
+<p>We regret to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information.
+For any other queries, please contact us by replying to this email.</p>
+<br>
+<p>We wish you a fruitful user experience on Fed4FIRE.</p>
+<br>
+<p>Yours sincerely,</p>
+<p>The Fed4FIRE team</p>
--- /dev/null
+Dear Fed4FIRE user,
+
+You have recently requested to join a project in the Fed4FIRE portal.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+
+We regret to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information. For any other queries, please contact us by replying to this email.
+
+We wish you a fruitful user experience on Fed4FIRE.
+
+Yours sincerely,
+The Fed4FIRE team
+
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<h1>JOIN PROJECT REQUEST</h1>
+<br>
+<p>You are receiving this request because we have you listed as a manager of a project that uses Fed4FIRE.</p>
+<p>A user has requested to join your project, which will allow him or her to reserve testbed resources to conduct an experiment.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<p></p>
+<p>You can accept or reject this request <a href="{{current_site}}/portal/project/{{authority_hrn}}.{{project_name}}#requests">in the portal.</a><p>
+<p>Please be sure that you know the user who is requesting to join your project.</p>
+<p>Fed4FIRE and its affiliated testbeds exist purely to support useful and interesting work. To ensure the future of these environments, we need to know what work is actually being done.</p>
+<p></p>
+<p>If you believe that you have received this message in error, or if you have any questions, kindly contact contact@fed4fire.eu</p>
+
+
--- /dev/null
+JOIN PROJECT REQUEST
+
+You are receiving this request because we have you listed as a manager a project that uses Fed4FIRE.
+A user has requested to join your project, which will allow him or her to reserve testbed resources to conduct an experiment.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+
+You can accept or reject thisrequest in:
+{{current_site}}/portal/project/{{authority_hrn}}.{{project_name}}#requests
+
+
+Please be sure that you know the user who is requesting to join your project.
+
+Fed4FIRE and its affiliated testbeds exist purely to support useful and interesting work. To ensure the future of these environments, we need to know what work is actually being done.
+
+If you believe that you have received this message in error, or if you have any questions, kindly contact contact@fed4fire.eu
+
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<p>Dear Fed4FIRE user,</p>
+<p></p>
+<p>You have recently requested to join a project in the Fed4FIRE portal.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<p></p>
+<p>
+ We are pleased to inform you that a project manager has validated your request on the Fed4FIRE portal.
+ You can now create slices in this project and start experimenting.
+</p>
+<p></p>
+<p>We wish you a fruitful user experience with the Fed4FIRE portal.</p>
+<p></p>
+<p>Yours sincerely,</p>
+<p>The Fed4FIRE team</p>
+
+
--- /dev/null
+Dear Fed4FIRE user,
+
+You have recently requested to join a project in the Fed4FIRE portal.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+
+We are pleased to inform you that a project manager has validated your request on the Fed4FIRE portal.
+You can now create slices in this project and start experimenting.
+
+We wish you a fruitful user experience with the Fed4FIRE portal.
+
+Yours sincerely,
+The Fed4FIRE team
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<p>Dear Fed4FIRE user,</p>
+<p></p>
+<p>You have recently requested a project in the Fed4FIRE portal.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<b>Purpose :</b> {{purpose}}</br>
+<p></p>
+<br>
+<p>We regret to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information.
+For any other queries, please contact us by replying to this email.</p>
+<br>
+<p>We wish you a fruitful user experience on Fed4FIRE.</p>
+<br>
+<p>Yours sincerely,</p>
+<p>The Fed4FIRE team</p>
--- /dev/null
+Dear Fed4FIRE user,
+
+You have recently requested a project in the Fed4FIRE portal.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+Purpose : {{purpose}}
+
+We regret to inform you that, a manager of your institution has rejected your request. Please contact the manager of your institution for further information. For any other queries, please contact us by replying to this email.
+
+We wish you a fruitful user experience on Fed4FIRE.
+
+Yours sincerely,
+The Fed4FIRE team
+
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<h1>NEW PROJECT REQUEST</h1>
+<br>
+<p>You are receiving this request because we have you listed as a manager at an organization that uses Fed4FIRE.</p>
+<p>A user from your organization has requested the creation of a new project.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<b>Purpose :</b> {{purpose}}</br>
+<b>Portal url :</b> {{current_site}}</br>
+<p></p>
+<p>You can see this new project request <a href="{{current_site}}/portal/institution#requests">in the portal.</a><p>
+<p>Please be sure that you know the user who is requesting this project, as you are responsible for his or her actions.</p>
+<p>And kindly ensure that the stated experiment purpose is clear.</p>
+<p>Fed4FIRE and its affiliated testbeds exist purely to support useful and interesting work. To ensure the future of these environments, we need to know what work is actually being done.</p>
+<p></p>
+<p>If you believe that you have received this message in error, or if you have any questions, kindly contact contact@fed4fire.eu</p>
+
+
--- /dev/null
+NEW SLICE REQUEST
+
+You are receiving this request because we have you listed as a manager at an organization that uses Fed4FIRE.
+A user from your organization has requested the creation of a new slice, which will allow him or her to reserve testbed resources to conduct an experiment.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+Purpose : {{purpose}}
+Portal url : {{current_site}}
+
+You can see this new project request in: {{current_site}}/portal/institution#requests
+
+Please be sure that you know the user who is requesting this project, as you are responsible for his or her actions.
+
+And kindly ensure that the stated experiment purpose is clear.
+Fed4FIRE and its affiliated testbeds exist purely to support useful and interesting work. To ensure the future of these environments, we need to know what work is actually being done.
+
+If you believe that you have received this message in error, or if you have any questions, kindly contact contact@fed4fire.eu
+
--- /dev/null
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
+<br>
+<p>Dear Fed4FIRE user,</p>
+<p></p>
+<p>You have recently requested a project in the Fed4FIRE portal.</p>
+<br>
+<b>Project name :</b> {{project_name}}</br>
+<b>Authority :</b> {{authority_hrn}}</br>
+<b>Email :</b> {{email}}</br>
+<b>Purpose :</b> {{purpose}}</br>
+<p></p>
+<p>
+ We are pleased to inform you that a manager from your institution has validated your project request on the Fed4FIRE portal.
+ You can now create slices and start experimenting.
+</p>
+<p></p>
+<p>We wish you a fruitful user experience with the Fed4FIRE portal.</p>
+<p></p>
+<p>Yours sincerely,</p>
+<p>The Fed4FIRE team</p>
+
+
--- /dev/null
+Dear Fed4FIRE user,
+
+You have recently requested a project in the Fed4FIRE portal.
+
+Project name : {{project_name}}
+Authority : {{authority_hrn}}
+Email : {{email}}
+Purpose : {{purpose}}
+
+We are pleased to inform you that a manager from your institution has validated your project request on the Fed4FIRE portal. You can now create slices and start experimenting.
+
+We wish you a fruitful user experience with the Fed4FIRE portal.
+
+Yours sincerely,
+The Fed4FIRE team
{% extends "layout.html" %}
{% load i18n %}
-
-{% block content %}
+{% block head %}
<script src="{{ STATIC_URL }}js/jquery-ui.js"></script>
<script src="{{ STATIC_URL }}js/jquery-ui-combobox.js"></script>
-<link rel='stylesheet' type='text/css' href="{{ STATIC_URL }}css/jquery-ui.css">
+<link rel='stylesheet' type='text/css' href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/jquery.ui.combobox.css">
-<br />
+{% endblock head %}
+{% block content %}
+<div class="row">
+ <div class="col-md-12">
+ <div class="breadcrumbs" style="line-height: 3;">
+ Experiment > Create or join a Project
+ </div>
+ </div>
+</div>
<div class="row">
<div class="col-md-12">
<ul class="nav nav-tabs nav-section">
- <li class="active"><a href="#existing">Join existing Project</a></li>
- <li><a href="#new">Create new Project</a></li>
+ <li class="active"><a href="#new">Create new Project</a></li>
+ <li><a href="#existing">Join existing Project</a></li>
</ul>
</div>
{% endif %}
<div class="container tab-content">
+
+ <div class="tab-pane active" id="new">
+
+ <div class="row">
+ <div class="col-sm-6 col-sm-offset-3">
+ <form role="form" method="post" action="/portal/project_request">
+ {% csrf_token %}
+ <label>
+ Please insert a name for your project under which you will be able to create slices <br />
+ <span class="sublabel">
+ The project name should only contain letters, numbers and the underscore "_" (10 max length)<br />
+ </span>
+ </label>
+ <div class="form-group">
+ <input type="text" name="project_name" value="" class="form-control" maxlength="10" style="width:100%;" title="The project name should not contain spaces but only letters, numbers and the underscore character" placeholder="Project name" required>
+ </div>
+
+ <label>
+ The authority under which your project will be managed <br />
+ <span class="sublabel">
+ Before you can access your project a manager of this authority should approve the request
+ </span>
+ </label>
+ <div class="form-group">
+ <select id="org_name" name="authority_name" class="form-control" style="width:100%" value="{{ organization }}" required>
+ {% if authorities %}
+ {% for authority in authorities %}
+ {% if authority.name %}
+ <option value="{{ authority.authority_hrn }}" {% if authority.authority_hrn == authority_hrn %}selected{% endif %}>{{authority.name}}</option>
+ {% else %}
+ <option value="{{ authority.authority_hrn }}" {% if authority.authority_hrn == authority_hrn %}selected{% endif %}>{{authority.authority_hrn}}</option>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </select>
+ </div>
+
+ <label>
+ Please provide a description of the purpose for your project
+ </label>
+ <div class="form-group">
+ <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Project description" style="width:100%" title="Purpose of your project (informative)" required="required"></textarea>
+ </div>
+ <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Send Request</button>
+ </form>
+
+ </div>
+ </div>
+ </div>
- <div class="tab-pane active" id="existing">
+ <div class="tab-pane" id="existing">
<div class="row">
<div class="col-md-6">
<h3>Join an existing Project</h3>
<form role="form" method="post" action="/portal/project_request">
{% csrf_token %}
<div id="project_loading" style="display:inline;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading projects" /></div>
- <select id="projects" name="project_name" style="display:none;"></select> <div style="display:none;" id="projects_button"><input type="submit" id="join" name="join" value="Join" class="btn"/></div>
+ <select id="projects" name="project_name" style="display:none;"></select>
+ <div style="display:none;" id="projects_button">
+ <input type="submit" id="join" name="join" value="Join" class="btn"/>
+ </div>
</form>
</div>
<div class="col-md-6">
</div>
</div>
</div>
-
- <div class="tab-pane" id="new">
- <div class="row">
- <div class="col-md-12">
- <h3>Create a new Project</h3>
- </div>
- </div>
-
-
- <div class="row">
- <div class="col-md-12">
- <form role="form" method="post" action="/portal/project_request">
- {% csrf_token %}
- <div class="form-group">
- <input type="text" name="project_name" value="" style="width:380px;" placeholder="Name" required>
- </div>
- <div class="form-group">
- <select id="org_name" name="authority_name" class="form-control" style="width:380px" value="{{ organization }}" required>
- {% if authorities %}
- {% for authority in authorities %}
- {% if authority.name %}
- <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
- {% else %}
- <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
- {% endif %}
- {% endfor %}
- {% endif %}
- </select>
- </div>
-
-
- <div class="form-group">
- <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Description" style="width:380px" title="Purpose of your project (informative)" required="required"></textarea>
- </div>
- <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Send Request</button>
- </form>
-
- </div>
- </div>
- </div>
-
</div>
<script>
$(document).ready(function() {
var myprojects = JSON.parse(localStorage.getItem('projects'));
- console.log(myprojects);
if (myprojects) {
$.each(myprojects, function (i, val){
- console.log(val);
$('.project-list').append('<tr><td>'+ val +'</td></tr>');
});
} else {
$("#project_loading").hide();
$("#projects").html(projects.join( "" ));
$("#projects").combobox();
+ var $s = jQuery("#projects").next().attr('id','listProjects');
+ jQuery('#listProjects').bind("click",function(){
+ // show all items click
+ this.childNodes[1].click();
+ });
+
});
/*
- $("#authority_hrn").load("/rest/user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
+ $("#authority_hrn").load("/rest/myslice:user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
var jsonData = JSON.parse(data);
$(this).attr("value", jsonData[0]['parent_authority']);
});
// auto-complete the form
jQuery("#org_name").combobox();
+ $('input[name=project_name]').keyup(function(){
+ this.value = this.value.toLowerCase();
+ });
});
</script>
{% endblock %}
</div>
<div class="modal-body">
<p align="left">
- The exact terms and conditions for Fed4FIRE are currently under development.
+<div style="text-align: left;" class="mk-text-block "><h4>Fed4FIRE Umbrella Terms and Conditions</h4>
+<h4><span style="color: #f97352;">Purpose of this document</span></h4>
+<p>These Terms and Conditions are provided to inform the user (hereinafter ‘You’) about what constitutes acceptable and permitted use of testbed resources and tools (hereinafter ‘the Platform’) in the Fed4FIRE federation (hereinafter ‘Fed4FIRE’).</p>
+<p>The regulations are not intended to constrain You unnecessarily, but to make You aware and protect You, along with all the participating institutions, from the consequences of any misuse or illegal activity as far as is reasonable.</p>
+<p>It is important to understand that when You use the Platform You are bound by these global Fed4FIRE terms and conditions (as provided online at <a href="http://www.fed4fire.eu/terms">http://www.fed4fire.eu/terms</a>), and also by the ICT regulations of Your own institution and the Acceptable Use Policy of the network providers connecting You to the testbed and interconnecting the resources You use. Thus You must have read and understood these before using Platform resources.</p>
+<p>This policy may be updated as necessary. The current version in force will be available at <a href="http://www.fed4fire.eu/terms">http://www.fed4fire.eu/terms</a>.</p>
+<h4><span style="color: #f97352;">Context</span></h4>
+<p>Fed4FIRE provides an experimental platform for testing new ideas and technologies in the area of computer networking (<a href="http://www.fed4fire.eu">http://www.fed4fire.eu</a>). The federated facility consists of individual testbeds and tools, with different owners. The Fed4FIRE consortium is coordinated by iMinds.</p>
+<p>Fed4FIRE provides You with basic access (through a single account, common tools, support and documentation) to the Platform, while each individual testbed provider determines the specifics of this access in terms of available resources, access policies, etc.</p>
+<h4><span style="color: #f97352;">Scope</span></h4>
+<p>These Terms and Conditions apply to every user of the Platform.</p>
+<p>The Terms and Conditions apply to the use of all equipment connected to the Platform. This includes servers, network(s), and Your workstations (whether owned by You, a company or an institution) and any other equipment or facilities connected to the Platform.</p>
+<p>These Terms and Conditions apply to all use of the Platform.</p>
+<p>These Terms and Conditions apply to third parties using the Platform through services You have made available through the Platform as part of an experiment. You will have to inform these third parties of the Terms and Conditions.</p>
+<h4><span style="color: #f97352;">Limitation of Liability</span></h4>
+<p>No liability is assumed by service providers involved on the Platform or any member of the Fed4FIRE consortium in regards to interruption, corruption, loss or disclosure of the services, tools, processes and data hosted<strong>, </strong>unless it is explicitly mentioned otherwise.</p>
+<h4><span style="color: #f97352;">Service Provision</span></h4>
+<p>You are granted Resources within the Fed4FIRE testbed so that You can use the Platform for the purposes described in the experiment projects You are taking part in. These resources can not be used for any other purposes.</p>
+<p>Platform resource providers aim to provide a stable, high-quality service. If there is evidence that the actions of users are adversely impacting this, resource providers are empowered to take reasonable measures to terminate or reprioritise usage in order to protect the overall operation of their services. Implicated users will be contacted by testbed providers as early as is reasonable.</p>
+<h4><span style="color: #f97352;">Acceptable Usage Policy</span></h4>
+<p>You are granted an account solely for Your own and personal use. You should take appropriate measure to protect Your credentials and prevent their use by third parties. The information You provide when requesting an account should be correct to the best of Your knowledge. You shall be responsible for all loss or damages to any part of the Platform as a result of any use of Your credentials to access the Platform, whether they are authorised or unauthorised by You.</p>
+<p>You shall be liable for actions performed on the Platform, by You, at your request or at the request of any other user invited or permitted by You to use services running on Fed4FIRE. In case of any loss or damage to the Platform originating from Your account, You are responsible for repairing or compensating for all damages to the Platform. In addition, You must respect the regulations of the various testbed resources You use in Your work, as described at <a href="http://www.fed4fire.eu/terms">http://www.fed4fire.eu/terms</a>. Your need to do this arises from co-operative agreements that have been made between all the organisations participating in the Platform.</p>
+<p>You may not interfere with others’ work or attempt to invade their privacy.</p>
+<p>You may not attempt to disrupt the working of the Platform.</p>
+<p>You must respect all Copyright for any software and data used on the Platform.</p>
+<p>The terms of software and data licences must be respected.</p>
+<p>You are not entitled to move proprietary data to, from, or via Platform systems without the prior agreement of its owner.</p>
+<p>Once You have registered to use the Platform, it is Your responsibility to remain aware of these regulations and of any changes made to them, and your continued use of the Platform means that you shall abide by the latest version of these terms and conditions.</p>
+<p>In order to keep the Platform operating correctly in both the technical and legal senses, it may become necessary to investigate network traffic (including, for example, e-mails) as well as examine information held on systems that are, or have been, connected to the Platform. You are deemed to have agreed to this.</p>
+<p>You must ensure that all known or obvious threats and vulnerabilities of the systems You run are adequately addressed.</p>
+<p>Should Your usage imply giving access to the Platform to third parties, You understand You will need to gather explicit consent from the operators of the individual testbed providers You will use, and You agree to enforce any restrictions imposed by an individual testbed provider and accept to fulfil Your legal obligations regarding data protection and retention laws.</p>
+<p>The following are explicitly forbidden on the Platform:</p>
+<ul>
+<li>Any military usage, including the development and production of weapons of mass destruction.</li>
+<li>Any activity resulting in compromising the security or integrity of any sites or networks connected to the Fed4FIRE facility</li>
+<li>Distribution of documents or materials containing insults or defamation, racial hatred or revisionism, terrorism, advertising, or distribution of material in a way that infringes the copyright of another person.</li>
+<li>Any illegal activity.</li>
+</ul>
+<p>You must comply to any additional national regulations from the government of the operators of the local testbeds.</p>
+<h4><span style="color: #f97352;">Enforcement</span></h4>
+<p>Whenever You use the Platform, You are bound by all the regulations in the current form of these terms and conditions and the legislation in force at the time.</p>
+<p>The regulations and legislation which applies to You will be enforced by iMinds, as leader of the Fed4FIRE consortium, or/and by the affected testbed providers, even if a breach of either has been evidenced from elsewhere.</p>
+<p>Note that for breaches of some legislation, the law enforcement can be involved.</p>
+<p>Ignorance of regulations or legislation is not a defence.</p>
+<p>Penalties, as defined in the individual testbed regulations at <a href="http://www.fed4fire.eu/terms">http://www.fed4fire.eu/terms</a>, will be levied for confirmed breaches of regulations.</p>
+<p>Disciplinary and investigative processes may also involve any Fed4FIRE partners, users and testbed providers involved in or affected by Your actions.</p>
+<p>Note that all testbed providers have agreed to co-operate in investigating disciplinary cases.</p>
+<p>You agree that the testbed and network providers in Fed4FIRE may monitor the systems and traffic for vulnerabilities and conformance to the acceptable uses, and You will collaborate with Fed4FIRE and any third party involved should any violations or breaches be noticed. The testbed providers involved may suspend or stop systems or suspend network connectivity without notice if such violations are found or suspected. To fulfil legal and contractual requirements, they may communicate to authorized third parties the owner and user of any resource provisioned and connected to the internet.</p>
+<h4><span style="color: #f97352;">Non-research use of Platform resources</span></h4>
+<p>The Fed4FIRE federation Platform has been constructed for experiment-driven research activities, where experiment-driven research is defined as any activity that furthers the user’s knowledge and/or understanding of algorithms, complex data structures or user behaviour.</p>
+<p>If You wish to use the Platform for any other purpose this must be authorized in advance by the Fed4FIRE testbed providers You will use. You will be expected to provide detailed information in support of Your request.</p>
+<p>Experiments must obtain prior agreement from the providers of all resources (e.g. computers, software, data, networks, and any other facilities) before these are used for any purposes other than experiment-driven research activities.</p>
+<p>The use of Fed4FIRE to host commercial services is explicitly disallowed.</p>
+<p>Experimenters that wish to use additional resources also have to agree with the policies of the testbed providers that offer the requested resources (when applicable). The individual testbed policies can be found here:</p>
+<p><a href="http://www.fed4fire.eu/terms/" target="_blank">fed4fire testbeds</a></p>
+<div class="clearboth"></div></div>
</p>
</div>
--- /dev/null
+{% extends "layout.html" %}
+
+{% block content %}
+
+ <h1>Success</h1>
+
+Your slice has been created. You can view all your slices in the <a href="/">dashboard.</a>
+<script>
+$(document).ready(function() {
+ localStorage.clear();
+});
+</script>
+{% endblock %}
+
<li class="active"><a href="#resourcelist" role="tab" data-toggle="tab">Table</a></li>
<li> <a href="#resourcemap" role="tab" data-toggle="tab">Map</a></li>
<li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li>
+ <li> <a href="#resourcesla" role="tab" data-toggle="tab">SLA offers</a></li>
</ul>
</div>
</div>
<div class="tab-pane" id="resourcemap">
{{map_resources}}
</div>
+ <div class="tab-pane" id="resourcesla">
+ {{sla_dialog}}
+ </div>
<div class="tab-pane" id="resourcescheduler">
{{scheduler}}
</div>
<!-- <div class="tab-pane row" id="statistics">...</div> -->
<!-- <div class="tab-pane row" id="measurements">...</div> -->
<div class="tab-pane row" id="experiment">...</div>
+ <div class="tab-pane row" id="sla">...</div>
</div>
{% endblock %}
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<p>Dear Fed4FIRE user,</p>
<p></p>
<b>Slice name :</b> {{slice_name}}<br>
<b>URL :</b> {{url}}<br>
<b>Purpose :</b> {{purpose}}<br>
-<br>c
+<br>
<p>We regret to inform you that, a manager of your institution has not confirmed your request. Please contact the manager of your institution for further information.
For any other queries, please contact us by replying to this email.</p>
<br>
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<h1>NEW SLICE REQUEST</h1>
<br>
<b>Email :</b> {{email}}</br>
<b>Portal url :</b> {{current_site}}</br>
<p></p>
-<p>You can see new slice request <a href="{{current_site}}/portal/validate">in the portal.</a><p>
+<p>You can see new slice request <a href="{{current_site}}/portal/institution#requests">in the portal.</a><p>
<p>Please be sure that you know the user who is requesting this slice, as you are responsible for his or her actions.</p>
<p>And kindly ensure that the stated experiment purpose is clear, and, if there is a website that explains the website, that a URL is provided.</p>
<p>Fed4FIRE and its affiliated testbeds exist purely to support useful and interesting work. To ensure the future of these environments, we need to know what work is actually being done.</p>
Organization : {{organization}}
Portal url : {{current_site}}
-You can see new slice request in: {{current_site}}/portal/validate
+You can see new slice request in: {{current_site}}/portal/institution#requests
Please be sure that you know the user who is requesting this slice, as you are responsible for his or her actions.
And kindly ensure that the stated experiment purpose is clear, and, if there is a website that explains the website, that a URL is provided.
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<p>Dear Fed4FIRE user,</p>
<p></p>
</div>
</div>
</div>
-
+
{% if errors %}
<div class="row">
<div class="col-md-12">
{% endif %}
<div class="row">
- <div class="col-md-8 el">
+ <div class="col-md-5 col-md-offset-3">
<form role="form" method="post">
{% csrf_token %}
- <div class="form-group" style="display:none">
- <input type="email" class="form-control" id="email" style="width:300px" value="{{ email }}" readonly="readonly">
- </div>
<div class="form-group">
- <input type="text" class="form-control" name="slice_name" id="slice_name" style="width:300px" placeholder="Slice name" value="{{slice_name}}"
- title="Please enter a name for your slice"required="required">
+ <input type="hidden" id="email" value="{{ email }}" readonly="readonly">
+ <label>
+ Please enter a name for your slice <br />
+ <span class="sublabel">
+ The slice name should only contain letters, numbers and the underscore "_" (19 max length) <br />
+ </span>
+ </label>
+ <input type="text" class="form-control" name="slice_name" id="slice_name" maxlength="19" style="width:100%" placeholder="Slice name" value="{{slice_name}}" required="required">
</div>
<div class="form-group">
- {% if pi %}
- <input type="text" class="form-control" id="authority_hrn" name="org_name" style="width:300px" placeholder="Organization"
- title="An authority responsible for vetting your slice" required="required">
- {% else %}
- <input type="hidden" class="form-control" id="authority_hrn" name="org_name" placeholder="Organization" style="width:300px;"
- title="An authority responsible for vetting your slice" required="required" readonly>
- <span style="float:left;">Authority: </span>
- <div id="authority_display">
- <img src="{{ STATIC_URL }}img/loading.gif" alt="Loading authority" />
- </div>
- {% endif %}
+ <label>
+ Select a project under which you want your slice to be created <br />
+ If your are not part of any projects you can <a href="/portal/project_request/">join or create one</a>
+ </label>
+ <input type="text" class="form-control" id="authority_hrn" name="org_name" style="width:100%" placeholder="Project"
+ title="Select a project under which you want to create your slice" required="required">
</div>
<div class="form-group">
- Project: <div id="project_loading" style="display:inline;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading projects" /></div>
- <select id="project" name="project" style="display:none;">
- </select>
- </div>
- <div class="form-group">
- <input type="text" class="form-control" name="url" id="url" style="width:300px" placeholder="Experiment URL (if one exists)"
- title="Please provide the url of your experiment if you have one." value="{{url}}">
+ <label>
+ Provide an URL for your experiment (not required)
+ </label>
+ <input type="text" class="form-control" name="url" id="url" style="width:100%" placeholder="Experiment URL (if one exists)"
+ title="Please provide the url of your experiment" value="{{url}}">
</div>
<div class="form-group">
- <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Experiment purpose" style="width:300px"
- title="Purpose of your experiment (informative)" required="required">{{ purpose }}</textarea>
+ <label>
+ Please provide a description of the purpose for your experiment
+ </label>
+ <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Experiment description" style="width:100%"
+ title="Description of your experiment" required="required">{{ purpose }}</textarea>
</div>
- {% if pi %}
<button type="submit" id=submit_pi class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Create slice</button>
- {% else %}
- <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Request slice</button>
- {% endif %}
</form>
</div>
<script>
jQuery(document).ready(function(){
-
- $("#authority_hrn").load("/rest/user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
- var jsonData = JSON.parse(data);
- $(this).attr("value", jsonData[0]['parent_authority']);
- {% if pi %}
- draw_projects(jsonData[0]['parent_authority']);
- {% else %}
- $('#authority_display').html(jsonData[0]['parent_authority']);
- draw_projects('');
- {% endif %}
- });
-
- {% if pi %}
- $("#authority_hrn").val("{{authority_name}}");
- var availableTags = [
- {% if authorities %}
- {% for authority in authorities %}
- {% if authority.name %}
- {value:"{{ authority.name }}",label:"{{authority.name}}"},
- // to show only full name
- {% else %}
- {value:"{{ authority.authority_hrn }}",label:"{{authority.authority_hrn}}"},
- {% endif %}
- {% endfor %}
- {% else %}
- {value:"",label:"No authority found !!!"}
- {% endif %}
- ];
- // sorting the list
- availableTags.sort(function(a,b){
- var nameA=a.value.toLowerCase(), nameB=b.value.toLowerCase();
- if (nameA < nameB) {
- return -1;
- }
- if (nameA > nameB) {
- return 1;
- }
- return 0;
- });
+ var myprojects = JSON.parse(localStorage.getItem('projects'));
$( "#authority_hrn" ).autocomplete({
- source: availableTags,
- minLength: 0,
- select: function( event, ui ) {
- $("#project").hide();
- $("#project_loading").css('display', 'inline-block');
- draw_projects(jQuery('.ui-state-focus').html());
- },
+ minLength: 0,
+ source: myprojects,
+ change: function (event, ui) {
+ if(!ui.item){
+ //http://api.jqueryui.com/autocomplete/#event-change -
+ // The item selected from the menu, if any. Otherwise the property is null
+ //so clear the item for force selection
+ $("#authority_hrn").val("");
+ }
+ }
+ }).bind('focus', function(){ $(this).autocomplete("search"); } );
+ $('input[name=slice_name]').keyup(function(){
+ this.value = this.value.toLowerCase();
});
- {% endif %}
});
-
-function draw_projects(authority_hrn){
-
- var projects = [];
- project_row = "<option value=''> - </option>";
- projects.push(project_row);
-
- if(authority_hrn.length > 0){
- // Not for root authority
- if(authority_hrn.split('.').length > 1){
- $.post("/rest/myslice:authority/",{'fields':['authority_hrn','pi_users'],'filters':{'authority_hrn':'CONTAINS'+authority_hrn}}, function( data ) {
-
- $.each( data, function( key, val ) {
- project_row = "<option value='"+val.authority_hrn+"'>"+val.authority_hrn+"</option>";
- projects.push(project_row);
- });
- $("#project").html(projects.join( "" ));
- });
- }else{
- $("#project").html(projects.join( "" ));
- }
- }else{
- my_projects = JSON.parse(localStorage.getItem('projects'));
- $.each( my_projects, function( i, val ) {
- project_row = "<option value='"+val+"'>"+val+"</option>";
- projects.push(project_row);
- });
- $("#project").html(projects.join( "" ));
- }
- $("#project").show();
- $("#project_loading").hide();
-}
</script>
{% endblock %}
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<p>Dear {{first_name}} {{last_name}},</p>
<p></p>
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<h1>NEW USER REQUEST</h1>
<br>
<b>User hrn :</b> {{user_hrn}}<br>
<b>Portal url :</b> {{ current_site }}<br>
<p></p>
-<p>You can validate the user <a href="{{current_site}}/portal/validate">here</a>.<p>
+<p>You can validate the user <a href="{{current_site}}/portal/institution#requests">here</a>.<p>
<br>
<p>Please note that the validation request will only become visible once the user has confirmed his/her email address.</p>
-<img src="http://doc.fed4fire.eu/_static/fed4fire-logo.jpg">
+<img src="https://portal.fed4fire.eu/static/img/f4f-logo.png" width="80px">
<br>
<p>Dear {{first_name}} {{last_name}},</p>
<p></p>
-<p>It is my pleasure to welcome you as a fully signed-up user of the Fed4FIRE portal. Fed4FIRE provides you with access to world class computer networking testbeds. Our aim at Fed4FIRE is to promote the use of these testbeds for research and development by industry, for scientific research, and for university level laboratory exercises.</p>
+<p>It is my pleasure to welcome you as a fully registered user of the Fed4FIRE portal. Fed4FIRE provides you with access to world-class computer networking testbeds. Our aim in Fed4FIRE is to promote the use of these testbeds for industrial research and development, scientific research, and university-level laboratory exercises.</p>
<p></p>
-</p>
-Your entry point for access to the testbeds is the Fed4FIRE portal, which provides a web-based interface for browsing and reserving resources on the various testbeds. To run an experiment using those resources, you may log in to the testbed and/or individual nodes on the testbed with your Fed4FIRE public/private key pair, or you may use an experiment control tool such as as NEPI or OMF. The Fed4FIRE operations team is standing by at contact@fed4fire.eu to provide you with help regarding the portal and to refer your testbed- and tool-specific queries to those best able to answer them.
-</p>
+<p>Your entry point for access to our testbeds is the Fed4FIRE portal, which provides a web-based interface for browsing and reserving resources on the various testbeds. To run an experiment using these resources, you may either log into the specific testbed and/or individual nodes on the testbed using your Fed4FIRE public/private key pair, or you may use an experiment control tool such as as NEPI or OMF. The Fed4FIRE operations team is standing by at contact@fed4fire.eu to provide you with any help regarding the portal, or to refer your testbed and tool-specific queries to those best able to answer them.</p>
<p></p>
</p>We wish you a fruitful user experience with the Fed4FIRE portal.</p>
<p></p>
--- /dev/null
+Fed4FIRE portal: Account validated
<!-- <li><a href="/slice/{{ slice }}#experiment">Statistics</a></li> -->
<!-- <li><a href="/slice/{{ slice }}#experiment">Measurements</a></li> -->
<li><a href="/slice/{{ slice }}#experiment">Tools</a></li>
+ <li><a href="/slice/{{ slice }}#sla">SLA status</a></li>
</ul>
{% else %}
<ul class="nav nav-tabs nav-section">
<!-- <li class="statistics"><a href="#experiment">Statistics</a></li> -->
<!-- <li class="measurements"><a href="#experiment">Measurements</a></li> -->
<li class="experiment"><a href="#experiment">Tools</a></li>
+ <li class="sla"><a href="#sla">SLA status</a></li>
</ul>
<script>
if ($(this).hasClass('link')) return;
e.preventDefault();
$(this).tab('show');
- var id = $(this).attr('href').substr(1);
+ var id = $(this).attr('href').substr(1);
$("#" + id).load('/' + id + '/{{ slice }}/');
});
<div id="secondary" class="col-sm-8 col-md-8 secondary">
<ul>
- <li><a href="/">Home</a></li>
<li><a href="/portal/about">About</a></li>
<li><a href="http://doc.fed4fire.eu/">Documentation</a></li>
<li><a target="_blank" href="http://www.fed4fire.eu">Project website</a></li>
{% if username %}
<div class="col-md-12 navigation">
<ul>
- <li id="nav-account"><a href="/portal/account/">{{ username }}</a></li>
+ <li><a href="/">DASHBOARD</a></li>
<li>|</li>
<!--<li id="nav-institution" class=""><a href="/portal/institution">AUTHORITY</a></li>-->
<li class="slices">
<li id="nav-service"><a href="/portal/servicedirectory">SERVICES</a></li>
<li id="nav-support"><a href="http://doc.fed4fire.eu/support.html">SUPPORT</a></li>
<li>|</li>
+ <li id="nav-account"><a href="/portal/account/">{{ username }}</a></li>
<li id="nav-logout"><span class="glyphicon glyphicon-off iconlogout"></span> <a id="logout" data-username="{{ username }}" href="#">LOGOUT</a></li>
</ul>
</div>
</div>
</div>
<div class="tab-pane row" id="requests">
+ <div id="spinner" style="padding-top:40px; padding-left:40px;"></div>
</div>
</div>
<script>
$(document).ready(function() {
{% if person %}
{% if user_details.parent_authority %}
+ $('#spinner').spin();
$.post("/rest/myslice:slice/",{'fields':['slice_hrn','users','url','slice_date_created'],'filters':{'parent_authority':'{{user_details.parent_authority}}'}}, function( data ) {
var list_slices = [];
-<script type="text/javascript">
- $(document).ready(function() {
- $("li#nav-request").addClass("active");
- $('table.requests').dataTable({
- "sDom": "frtiS",
- "bScrollCollapse": true,
- "bStateSave": true,
- "bPaginate": false,
- "bLengthChange": false,
- "bFilter": false,
- "bSort": true,
- "bInfo": false,
- "bAutoWidth": true,
- "bAutoHeight": false,
- });
- });
- function on_click_event() {
- var ids = [];
- $('.portal__validate__checkbox').each(function(i, el) {
- if ($(el).prop('checked')) {
- // portal__validate__checkbox__slice__2
- var id_array = $(el).attr('id').split('__');
- // push(slice__2)
- ids.push(id_array[3] + '__' + id_array[4]);
- }
- });
- if (ids.length > 0) {
- var id_str = ids.join('/');
-
- // XXX spinner
-
- $.getJSON('/portal/validate_action/' + id_str,
- function(status) {
- $.each(status, function(request_type__id, request_status) {
- // request_status: NAME -> dict (status, description)
- var status_str = '';
- $.each(request_status, function(name, result) {
- if (status_str != '')
- status_str += ' -- ';
-
- if (result.status) {
- status_str += '<font color="green">OK</font>';
- $('#portal__validate__checkbox__' + request_type__id).hide();
- } else {
- status_str += '<font color="red">ERROR: ' + result.description + '</font>';
- }
- });
- $('#portal__status__' + request_type__id).html(status_str);
-
-
- });
- }
- );
- }
- }
- function on_click_reject() {
- var ids = [];
- $('.portal__validate__checkbox').each(function(i, el) {
- if ($(el).prop('checked')) {
- // portal__validate__checkbox__slice__2
- var id_array = $(el).attr('id').split('__');
- // push(slice__2)
- ids.push(id_array[3] + '__' + id_array[4]);
- }
- });
- if (ids.length > 0) {
- var id_str = ids.join('/');
-
- // XXX spinner
-
- $.getJSON('/portal/reject_action/' + id_str,
- function(status) {
- $.each(status, function(request_type__id, request_status) {
- // request_status: NAME -> dict (status, description)
- var status_str = '';
- $.each(request_status, function(name, result) {
- if (status_str != '')
- status_str += ' -- ';
-
- if (result.status) {
- status_str += '<font color="green">Rejected</font>';
- $('#portal__validate__checkbox__' + request_type__id).hide();
- } else {
- status_str += '<font color="red">ERROR: ' + result.description + '</font>';
- }
- });
- $('#portal__status__' + request_type__id).html(status_str);
-
-
- });
- }
- );
- }
- }
-</script>
-
<div class="container-fluid">
<div class="col-md-12">
<h2>From your authorities</h2>
</td>
<td>{{ request.timestamp }}</td>
- <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
+ <td>
+ <span id='portal__status__{{request.type}}__{{request.id}}'></span>
+ <div id='{{request.type}}__{{request.id}}-status-loading' style="display:none;"><img src="{{ STATIC_URL }}img/loading.gif"></div>
+ </td>
<!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
</tr>
</div>
{% endif %}
</div>
-
-{% if sub_authorities %}
-<br />
-<div class="col-md-12">
- <h2>From your sub-authorities</h2>
-</div>
-
- {% for authority, requests in sub_authorities.items %}
- <div class="col-md-12">
- <h3>{{authority}}</h3>
- <table class="table">
- <th>
- <td>Type</td>
- <td>Id</td>
- <td>Details</td>
- <td>Timestamp</td>
- <td>Status</td>
- </th>
- {% for request in requests %}
- <tr>
- <td>
- {% if request.allowed == 'allowed' %}
- <input class='portal__validate__checkbox' id='portal__validate__checkbox__{{request.type}}__{{request.id}}' type='checkbox'/>
- {% else %}
- {% if request.allowed == 'expired' %}
- expired
- {% else %} {# denied #}
- denied
- {% endif %}
- {% endif %}
- </td>
- <td>{{ request.type }}</td>
- <td>{{ request.id }}</td>
- <td>
- {% if request.type == 'user' %}
- Login: {{request.login}} -- First name: {{request.first_name}} -- Last name: {{request.last_name}} -- Email: {{request.email}}
- {% else %}
- {% if request.type == 'slice' %}
- Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
- {% elif request.type == 'project' %}
- <b>{{request.project_name}}</b> -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
- {% elif request.type == 'join' %}
- <b>{{request.user_hrn}}</b> -- to join {{ request.authority_hrn }}
- {% else %} {# authority #}
- Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
- {% endif %}
- {% endif %}
- </td>
- <td>{{ request.timestamp }}</td>
-
- <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
-
- <!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
- </tr>
- {% endfor %}
- </table>
- </div>
- {% endfor %}
-{% endif %}
-{% if delegation_authorities %}
-<br />
-<div class="col-md-12">
- <h2>From your authorities with delegation</h2>
-</div>
-
- {% for authority, requests in delegation_authorities.items %}
- <div class="col-md-12">
- <h3>{{authority}}</h3>
- <table class="table">
- <th>
- <td>Type</td>
- <td>Id</td>
- <td>Details</td>
- <td>Timestamp</td>
- <td>Status</td>
- </th>
- {% for request in requests %}
- <tr>
- <td>
- {% if request.allowed == 'allowed' %}
- <input class='portal__validate__checkbox' id='portal__validate__checkbox__{{request.type}}__{{request.id}}' type='checkbox'/>
- {% else %}
- {% if request.allowed == 'expired' %}
- expired
- {% else %} {# denied #}
- denied
- {% endif %}
- {% endif %}
- </td>
- <td>{{ request.type }}</td>
- <td>{{ request.id }}</td>
- <td>
- {% if request.type == 'user' %}
- Login: {{request.login}} -- First name: {{request.first_name}} -- Last name: {{request.last_name}} -- Email: {{request.email}}
- {% else %}
- {% if request.type == 'slice' %}
- Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
- {% elif request.type == 'project' %}
- <b>{{request.project_name}}</b> -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
- {% else %} {# authority #}
- Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
- {% endif %}
- {% endif %}
- </td>
- <td>{{ request.timestamp }}</td>
-
- <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
-
- <!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
- </tr>
- {% endfor %}
- </table>
- </div>
- {% endfor %}
-{% endif %}
<br />
<div class="col-md-12">
<button class="btn btn-onelab" type="button" id="portal__validate" onclick="on_click_event();"><span class="glyphicon glyphicon-ok"></span> Validate</button>
<input type="file" name="pubkey" class="required" id="pubkey"/>
<input class="btn btn-default btn-xs" name="upload_key" id="upload_key" type="submit" title="Upload your public key" value="Upload"
onclick="return confirm('Are you sure? It will overwrite your current credentials and you have delegate it manually.');"/>
- </span>
+
<div style='display:none;'> <input type='hidden' name='dload' /> </div>
<button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_pubkey" onclick="javascript:document.getElementById('button_value').value='dl_pubkey';">
<span class="glyphicon glyphicon-download"></span> Download
<th>Slice Name</th>
<th>Expiration Date</th>
<th>Download</th>
+ <th>Delete</th>
</tr>
{% for row in my_slices %}
<tr class="border_bottom">
<span class="glyphicon glyphicon-download"></span> Download
</button>
</td>
+ <td class="odd">
+ <button class="btn btn-danger btn-xs" name= "del_{{row.slice_name}}" type="submit" title="Download Slice Credentials" onclick="return confirm('Are you sure? If you do so, the slice will be permanently deleted.'); javascript:document.getElementById('button_value').value='del_{{row.slice_name}}';">
+ <span class="glyphicon glyphicon-remove"></span> Delete
+ </button>
+ </td>
</tr>
{%endfor%}
</table>
{% block content %}
{% include theme|add:"_widget-slice-sections.html" %}
-
<div class="container-fluid tab-content container-slice">
- <div class="tab-pane active row" id="info">...</div>
- <div class="tab-pane row" id="testbeds">...</div>
- <div class="tab-pane row" id="resources">...</div>
- <div class="tab-pane row" id="users">...</div>
- <!-- <div class="tab-pane row" id="statistics">...</div> -->
- <!-- <div class="tab-pane row" id="measurements">...</div> -->
- <div class="tab-pane row" id="experiment">...</div>
- <!-- <div class="tab-pane row" id="studentslabs">...</div> -->
+ <div class="tab-pane active row" id="info"></div>
+ <div class="tab-pane row" id="testbeds"></div>
+ <div class="tab-pane row" id="resources"></div>
+ <div class="tab-pane row" id="users"></div>
+ <!-- <div class="tab-pane row" id="statistics"></div> -->
+ <div class="tab-pane row" id="measurements"></div>
+ <div class="tab-pane row" id="experiment"></div>
+ <!-- <div class="tab-pane row" id="studentslabs"></div> -->
</div>
{% endblock %}
title="Please enter a name for your slice"required="required">
</div>
<div class="form-group">
- {% if pi %}
- <input type="text" class="form-control" id="authority_hrn" name="org_name" style="width:300px" placeholder="Organization"
+ {% if request.session.user.pi %}
+ <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" style="width:300px" placeholder="Authority"
title="An authority responsible for vetting your slice" required="required">
- {% else %}
- <input type="text" class="form-control" id="authority_hrn" name="org_name" placeholder="Organization" style="width:300px;"
- title="An authority responsible for vetting your slice" required="required" readonly>
- {% endif %}
+ {% else %}
+ <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" placeholder="Authority" style="width:300px; display:none;"
+ title="An authority responsible for vetting your slice" required="required" readonly="readonly">
+ {% endif %}
</div>
<div class="form-group">
<input type="text" class="form-control" name="url" id="url" style="width:300px" placeholder="Experiment URL (if one exists)"
<b>User hrn :</b> {{user_hrn}}<br>
<b>Portal url :</b> {{ current_site }}<br>
<p></p>
-<p>You can see new user request <a href="{{current_site}}/portal/validate">in the portal.</a><p>
+<p>You can see new user request <a href="{{current_site}}/portal/institution#requests">in the portal.</a><p>
<p>Please note that the request will only become visible to you on the OneLab portal once the user has confirmed his/her email address.</p>
<p>Please only validate users who you know for whose actions you are prepared to take responsibility, as described in the
<a href="{{current_site}}/terms">OneLab terms and conditions.</a> If you find any anomalies in the request
User hrn : {{user_hrn}}
Portal url : {{ current_site }}
-You can see new user request in the portal: {{current_site}}/portal/validate
+You can see new user request in the portal: {{current_site}}/portal/institution#requests
Please note that the request will only become visible to you on the OneLab portal once the user has confirmed his/her email address.
<li><a href="/slice/{{ slice }}#users">Users</a></li>
<li><a href="/slice/{{ slice }}#info">Information</a></li>
<!-- <li><a href="/slice/{{ slice }}#experiment">Statistics</a></li> -->
- <!-- <li><a href="/slice/{{ slice }}#experiment">Measurements</a></li> -->
+ <li><a href="/slice/{{ slice }}#measurements">Measurements</a></li>
<li><a href="/slice/{{ slice }}#experiment">Tools</a></li>
<!-- <li><a href="/slice/{{ slice }}#studentslabs">Students Labs</a></li> -->
</ul>
<li class="users"><a href="#users">Users</a></li>
<li class="active"><a href="#info">Information</a></li>
<!-- <li class="statistics"><a href="#experiment">Statistics</a></li> -->
- <!-- <li class="measurements"><a href="#experiment">Measurements</a></li> -->
+ <li class="measurements"><a href="#measurements">Measurements</a></li>
<li class="experiment"><a href="#experiment">Tools</a></li>
<!-- <li class="studentslabs"><a href="#studentslabs">Students Labs</a></li> -->
</ul>
</ul>
</div>
</li>
- {%if 'is_pi' in pi %}
+ {% if request.session.user.pi %}
<li id="nav-institution" class=""><a href="/institution">MANAGEMENT</a></li>
- {%endif%}
+ {%endif%}
<li><a href="/support/">SUPPORT</a></li>
</ul>
</div>
{% block content %}
-<h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="Slice" />Request received</h1>
+<h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="Slice" />Project request sent</h1>
-We will process your request and get back to you as soon as possible.
+You will receive an email as soon as your request will be validated by a manager.
{% endblock %}
<h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="Slice" /> Slice request sent</h1>
-We will process your request and get back to you as soon as possible.
+You will receive an email as soon as your request will be validated by a manager.
{% endblock %}
slice_url="<a href='"+val.slice_url+"' target='_blank'>"+val.slice_url+"</a>";
}
- slice_row = "<tr><td>Description:</b></td><td>"+val.slice_description+"</td></tr>";
- slice_row += "<tr><td>url:</td><td><a href='"+val.slice_url+" target='_blank'>"+val.slice_url+"</a></td></tr>";
- slice_row += "<tr><td>users:</td><td>"+user_length+"</td></tr>";
+ // slice_row = "<tr><td>Description:</b></td><td>"+val.slice_description+"</td></tr>";
+ // slice_row += "<tr><td>url:</td><td><a href='"+val.slice_url+" target='_blank'>"+val.slice_url+"</a></td></tr>";
+ //slice_row = "<tr><td>users:</td><td>"+user_length+"</td></tr>";
//slice_row += "<tr><td>resources:</td><td>"+nodes_length+"</td></tr>";
- slice_row += "<tr><td>created:</td><td>"+val.created+"</td></tr>";
- slice_row += "<tr><td>last update:</td><td>"+val.slice_last_updated+"</td></tr>";
- slice_row += "<tr><td>expires:</td><td>"+val.slice_expires+"</td></tr>";
+ //slice_row += "<tr><td>created:</td><td>"+val.created+"</td></tr>";
+ slice_row = "<tr><td>Last updated on:</td><td>"+val.slice_last_updated+"</td></tr>";
+ //slice_row += "<tr><td>expires:</td><td>"+val.slice_expires+"</td></tr>";
table_slices.push(slice_row);
});
$("div#slice-info").html("<table>" + table_slices.join( "" ) + "</table>");
});
+ $('button#renewslices').click(function() {
+ var now = new Date();
+ /* In Javascript getMonth() gives month[0] = january, month[1] = february, and so on... */
+ var month = now.getMonth()+2;
+ var one_month_later = now.getFullYear()+"-"+month+"-"+now.getDate()+" "+now.getHours()+":"+now.getMinutes()+":"+now.getSeconds();
+ $.post("/update/slice/",{'filters':{'slice_hrn':'{{slice}}'},'params':{'expires':one_month_later}}, function(data) {
+ if(data.success){
+ mysliceAlert('Success: slice renewed','success', true);
+ }
+ else{
+ mysliceAlert('Rest Error for: '+data.error,'warning', true);
+ }
+ });
+ });
+ $('button#deleteslices').click(function() {
+ if (confirm('Are you sure? It will remove the slice permanently.')) {
+ $.post("/delete/slice/",{'filters':{'slice_hrn':'{{slice}}'}}, function(data) {
+ if(data.success){
+ localStorage.clear();
+ var user_email = [];
+ user_email.push ('{{username}}');
+ $.post("/credentials/clear/",{'emails':user_email}, function(data) {
+ }); // post credentials clear
+ mysliceAlert('Success: slice deleted','success', true);
+ }else{
+ mysliceAlert('Rest Error for: '+data.error,'warning', true);
+ }
+ window.location.replace("/");
+ });
+ }
+ else {
+ return false;
+ }
+ });
});
+
</script>
+
+<div>
+ <button id="renewslices" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-refresh"></span> Renew slice</button>
+ <button id="deleteslices" type="button" class="btn btn-danger"><span class="glyphicon glyphicon-remove"></span> Delete slice</button>
+</div>
<link rel="stylesheet" href="{{ STATIC_URL }}css/jquery-ui.css">
<script>
function get_users_in_slice(authority_hrn){
- console.log(authority_hrn);
$("table#user-tab").html("<tr><th>+/-</th><th>Email</th><th>User hrn</th></tr>");
var slice_users = [];
var slice_users_removed = [];
var slice_users_emails = [];
var slice_users_emails_removed = [];
- $.post("/rest/user/",{'filters':{'parent_authority': authority_hrn}}, function( data ) {
+ $.post("/rest/myslice:user/",{'filters':{'parent_authority': authority_hrn}}, function( data ) {
var list_users = [];
var table_users = [];
/* Available fields
}); // post rest/use
$('button#addusers').click(function() {
- $.post("/update/slice/",{'filters':{'slice_hrn':'{{slice}}'},'params':{'users':slice_users}}, function(data) {
+ $.post("/update/myslice:slice/",{'filters':{'slice_hrn':'{{slice}}'},'params':{'users':slice_users}}, function(data) {
if(data.success){
// TODO: highlight row after success
//$('tr[id="'+record_id+'"]').highlight();
$(document).ready(function() {
// TODO: Add a filter based on the list of authorities
- $.post("/rest/authority/",{'fields':['authority_hrn']}, function( data ) {
+ $.post("/rest/myslice:authority/",{'fields':['authority_hrn']}, function( data ) {
var list_authorities = [];
$.each( data, function( key, val ) {
auth_hrn = val.authority_hrn;
{% endblock %}
{% block content %}
-
<div class="container">
<div class="row">
<div class="col-md-12">
</div>
</div>
<div class="container-fluid tab-content">
- <div class="tab-pane active row" id="info">...</div>
- <div class="tab-pane row" id="testbeds">...</div>
- <div class="tab-pane row" id="resources">...</div>
- <div class="tab-pane row" id="users">...</div>
+ <div class="tab-pane active row" id="info"></div>
+ <div class="tab-pane row" id="testbeds"></div>
+ <div class="tab-pane row" id="resources"></div>
+ <div class="tab-pane row" id="users"></div>
<!-- <div class="tab-pane row" id="statistics">...</div> -->
- <div class="tab-pane row" id="measurements">...</div>
- <div class="tab-pane row" id="experiment">...</div>
- <div class="tab-pane row" id="sla">...</div>
+ <div class="tab-pane row" id="measurements"></div>
+ <div class="tab-pane row" id="experiment"></div>
+ <div class="tab-pane row" id="sla"></div>
</div>
{% endblock %}
<b>Email :</b> {{email}}</br>
<b>Portal url :</b> {{current_site}}</br>
<p></p>
-<p>You can see new slice request <a href="{{current_site}}/portal/validate">in the portal.</a><p>
+<p>You can see new slice request <a href="{{current_site}}/portal/institution#requests">in the portal.</a><p>
<p>Please be sure that you know the user who is requesting this slice, as you are responsible for his or her actions, as described in the
<a href="{{current_site}}/terms">OneLab terms and conditions.</a></p>
<p>And kindly ensure that the stated experiment purpose is clear, and, if there is a website that explains the website, that a URL is provided.</p>
Organization : {{organization}}
Portal url : {{current_site}}
-You can see new slice request in: {{current_site}}/portal/validate
+You can see new slice request in: {{current_site}}/portal/institution#requests
Please be sure that you know the user who is requesting this slice, as you are responsible for his or her actions, as described in the OneLab terms and conditions:
{{current_site}}/terms
title="Please enter a name for your slice"required="required">
</div>
<div class="form-group">
- {%if 'is_pi' in pi %}
- <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" style="width:300px" placeholder="Authority"
+ {% if request.session.user.pi %}
+ <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" style="width:300px" placeholder="Authority"
title="An authority responsible for vetting your slice" required="required">
- {%else%}
- <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" placeholder="Authority" style="width:300px; display:none;"
+ {% else %}
+ <input type="text" class="form-control" id="authority_hrn" name="authority_hrn" placeholder="Authority" style="width:300px; display:none;"
title="An authority responsible for vetting your slice" required="required" readonly="readonly">
- {%endif%}
+ {% endif %}
</div>
<div class="form-group">
<input type="number" class="form-control" name="number_of_nodes" id="number_of_nodes" style="width:300px" placeholder="Number of nodes"
minLength: 0,
select: function( event, ui ) {console.log(jQuery(this));}
});
+ $('input[name=slice_name]').keyup(function(){
+ this.value = this.value.toLowerCase();
+ });
});
</script>
{% endblock %}
<b>User hrn :</b> {{user_hrn}}<br>
<b>Portal url :</b> {{ current_site }}<br>
<p></p>
-<p>You can validate the user <a href="{{current_site}}/portal/validate">here</a>.<p>
+<p>You can validate the user <a href="{{current_site}}/portal/institution#requests">here</a>.<p>
<br>
<p>Please note that the validation request will only become visible once the user has confirmed his/her email address.</p>
--- /dev/null
+Account validated
def get_context_data(self, **kwargs):
page = Page(self.request)
- #print "UNIVBRIS page"
metadata = page.get_metadata()
page.expose_js_metadata()
from manifoldapi.manifoldapi import execute_query
from manifold.core.query import Query
from unfold.page import Page
+
from myslice.theme import ThemeView
+from myslice.settings import logger
class ValidatePendingView(LoginRequiredAutoLogoutView, ThemeView):
template_name = "validate_pending.html"
sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
sfa_platforms = execute_query(self.request, sfa_platforms_query)
for sfa_platform in sfa_platforms:
- print "SFA PLATFORM > ", sfa_platform['platform']
+ logger.info("SFA PLATFORM > {}".format(sfa_platform['platform']))
if not 'auth_type' in sfa_platform:
continue
auth = sfa_platform['auth_type']
all_authorities.append(auth)
platform_ids.append(sfa_platform['platform_id'])
- print "W: Hardcoding platform myslice"
+ logger.warning("W: Hardcoding platform myslice")
# There has been a tweak on how new platforms are referencing a
# so-called 'myslice' platform for storing authentication tokens.
# XXX This has to be removed in final versions.
#print "=" * 80
for user_account in user_accounts:
- print "USER ACCOUNT", user_account
+ logger.debug("USER ACCOUNT {}".format(user_account))
if user_account['auth_type'] == 'reference':
continue # we hardcoded the myslice platform...
config = json.loads(user_account['config'])
creds = []
- print "CONFIG KEYS", config.keys()
+ logger.debug("CONFIG KEYS {}".format(config.keys()))
if 'authority_credentials' in config:
- print "***", config['authority_credentials'].keys()
+ logger.debug("*** AC {}".format(config['authority_credentials'].keys()))
for authority_hrn, credential in config['authority_credentials'].items():
#if credential is not expired:
credential_authorities.add(authority_hrn)
#else
# credential_authorities_expired.add(authority_hrn)
if 'delegated_authority_credentials' in config:
- print "***", config['delegated_authority_credentials'].keys()
+ logger.debug("*** DAC {}".format(config['delegated_authority_credentials'].keys()))
for authority_hrn, credential in config['delegated_authority_credentials'].items():
#if credential is not expired:
credential_authorities.add(authority_hrn)
#else
# credential_authorities_expired.add(authority_hrn)
- print 'credential_authorities =', credential_authorities
- print 'credential_authorities_expired =', credential_authorities_expired
+ logger.debug('credential_authorities = {}'.format(credential_authorities))
+ logger.debug('credential_authorities_expired = {}'.format(credential_authorities_expired))
# # Using cache manifold-tables to get the list of authorities faster
# all_authorities_query = Query.get('authority').select('name', 'authority_hrn')
try:
for pa in pi_authorities_tmp:
pi_authorities |= set(pa['pi_authorities'])
- except:
- print 'No pi_authorities'
+ except Exception as e:
+ logger.error('No pi_authorities')
# TODO: exception if no parent_authority
# try:
# for pa in pi_authorities_tmp:
dest[auth_hrn].append(request)
context = super(ValidatePendingView, self).get_context_data(**kwargs)
- print "testing"
- print ctx_my_authorities
+ logger.debug("testing")
+ logger.debug(ctx_my_authorities)
context['my_authorities'] = ctx_my_authorities
context['sub_authorities'] = ctx_sub_authorities
context['delegation_authorities'] = ctx_delegation_authorities
config.close()
else:
return 0
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
def pres_view_animation(request, constraints, id):
}]
json_answer = json.dumps(cmd)
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
def pres_view_static(request, constraints, id):
#constraints = "']date_created':1262325600"
}]
json_answer = json.dumps(cmd)
- return HttpResponse (json_answer, mimetype="application/json")
+ return HttpResponse (json_answer, content_type="application/json")
-from manifold.core.query import Query
-from manifoldapi.manifoldapi import execute_query
-from portal.actions import is_pi
+import decimal
+import datetime
+import json
from django.http import HttpResponse
+from manifold.core.query import Query
+from manifoldapi.manifoldapi import execute_query
-import decimal
-import datetime
-import json
+from portal.actions import is_pi
+
+from myslice.settings import logger
# handles serialization of datetime in json
DateEncoder = lambda obj: obj.strftime("%B %d, %Y %H:%M:%S") if isinstance(obj, datetime.datetime) else None
# What about key formed of multiple fields???
query = Query.get('local:object').filter_by('table', '==', self.type).select('key')
results = execute_query(self.request, query)
- print "key of object = %s" % results
+ logger.debug("key of object = {}".format(results))
if results :
for r in results[0]['key'] :
self.id = r
if self.params :
for p in self.params :
for k,v in p.iteritems() :
- print "param: %s : %s" % (k,v)
+ logger.debug("param: {} : {}".format(k, v))
query.set({k : v})
- print "query = ",query
+ logger.debug("query = {}".format(query))
else:
raise Exception, "Params are required for create"
return execute_query(self.request, query)
if self.params :
for p in self.params :
for k,v in p.iteritems() :
- print "param: %s : %s" % (k,v)
+ logger.debug("param: {} : {}".format(k, v))
query.set({k : v})
- print "query = ",query
+ logger.debug("query = {}".format(query))
else:
raise Exception, "Params are required for update"
--- /dev/null
+from django.http import HttpResponse
+from portal.actions import authority_add_pis, authority_remove_pis
+import json
+
+def dispatch(request, action):
+
+ try:
+ if request.method == 'POST':
+ req_items = request.POST
+ elif request.method == 'GET':
+ req_items = request.GET
+
+ if 'user_hrn' in req_items:
+ user_hrn = str(req_items['user_hrn'])
+ if 'authority_hrn' in req_items:
+ authority_hrn = str(req_items['authority_hrn'])
+
+ if (action == 'add') :
+ new_pis = authority_add_pis(request, authority_hrn, user_hrn)
+ result = {'ret':1}
+ elif (action == 'remove'):
+ new_pis = authority_remove_pis(request, authority_hrn, user_hrn)
+ result = {'ret':1}
+ else:
+ raise Exception, "action not supported"
+ except Exception as e:
+ result = {'ret': -1, 'msg':'error: %s' % e}
+ return HttpResponse(json.dumps(result), content_type="application/json")
+
def dispatch(request, action):
if (action == 'clear') :
- query = Query.update('myslice:user').filter_by('user_hrn', '==', '$user_hrn').set({'user_email':str(request.user)})
+ query = Query.update('myslice:user').filter_by('user_hrn', '==', '$user_hrn').set({'user_email':str(request.user)}).select('user_hrn')
try:
res = execute_query(request, query)
except Exception, e:
elif request.method == 'GET':
#return error('only post request is supported')
req_items = request.GET
- print req_items
- for el in req_items.items():
+ for el in list(req_items.items()):
# Filters not used for create
if el[0].startswith('filters'):
o.filters[el[0][8:-1]] = el[1]
else :
return error('an error has occurred')
- except Exception, e:
+ except Exception as e:
return error(str(e))
if el[0].startswith('filters'):
o.filters[el[0][8:-1]] = el[1]
elif el[0].startswith('fields'):
- print req_items.getlist('fields[]')
o.setFields(req_items.getlist('fields[]'))
elif el[0].startswith('options'):
o.options = req_items.getlist('options[]')
error = "Error in delete return value"
except Exception, e:
error = str(e)
- #print "Exception : ",e
if error is not None:
ret = { "ret" : 1, "error" : error }
elif not results :
+import os
+import json
+import ConfigParser
+
+from django.shortcuts import render_to_response
+from django.http import HttpResponse
+
from sfa.trust.certificate import Keypair, Certificate
from sfa.client.sfaserverproxy import SfaServerProxy
from sfa.client.return_value import ReturnValue
from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn, urn_to_hrn
+
from manifold.core.query import Query
from manifold.models import db
from manifold.models.platform import Platform
from manifold.models.user import User
-from django.shortcuts import render_to_response
-
from unfold.loginrequired import LoginRequiredView
-from rest import ObjectRequest, error
-
-from string import join
-
-from django.http import HttpResponse
-from rest import error
-import os,json
-
-import ConfigParser
+from myslice.settings import logger
def dispatch(request, method):
Config = ConfigParser.ConfigParser()
from manifoldapi.manifoldapi import execute_admin_query
for pf in platforms:
platform = get_platform_config(pf)
- print platform
+ logger.debug("platform={}".format(platform))
if 'sm' in platform and len(platform['sm']) > 0:
- print 'sm'
+ logger.debug('sm')
server_url = platform['sm']
if 'rm' in platform and len(platform['rm']) > 0:
- print 'rm'
+ logger.debug('rm')
server_url = platform['rm']
if 'registry' in platform and len(platform['registry']) > 0:
- print 'registry'
+ logger.debug('registry')
server_url = platform['registry']
if not Config.has_option('monitor', 'cert') :
+from rest import ObjectRequest, error, success
+
from django.views.generic.base import TemplateView
from django.shortcuts import render_to_response
+from django.http import HttpResponse
from unfold.loginrequired import LoginRequiredView
-from django.http import HttpResponse
from manifold.core.query import Query, AnalyzedQuery
from manifoldapi.manifoldapi import execute_query
-from rest import ObjectRequest, error, success
-
-from string import join
-
-import json
-
+from myslice.settings import logger
def dispatch(request, object_type, object_name):
elif request.method == 'GET':
#return error('only post request is supported')
req_items = request.GET
- print req_items
+ logger.debug(req_items)
for el in req_items.items():
- print "#===============>",el
+ logger.debug("#===============> {}".format(el))
if el[0].startswith('filters'):
o.filters[el[0][8:-1]] = el[1]
elif el[0].startswith('params'):
- print "#======> 0 ", el[0]
- print "#======> 1 ", req_items.getlist(el[0])
+ logger.debug("#======> 0 {}".format(el[0]))
+ logger.debug("#======> 1 {}".format(req_items.getlist(el[0])))
if (el[0][-2:] == '[]') :
# when receiving params[key][] = 'value1' ...
# when receiving params[key] = 'value'
o.params.append({el[0][7:-1]:el[1]})
- print "o.params = ",o.params
+ logger.debug("o.params = {}".format(o.params))
elif el[0].startswith('fields'):
o.fields=req_items.getlist('fields[]')
# tmp
from trashutils import lorem, hard_wired_slice_names
+from myslice.settings import logger
+
@login_required
def tab_view (request):
- print "request", request.__class__
- print request
+ logger.info("request {}".format(request.__class__))
+ logger.info("{}".format(request))
prelude=Prelude( js_files='js/bootstrap.js', css_files='css/bootstrap.css')
tab_env = {'title':'Page for playing with Tabs',
from ui.topmenu import topmenu_items_live, the_user
+from myslice.settings import logger
+
class TopmenuValidationView (TemplateView):
# mention a user name in the URL as .../trash/simpletopmenuvalidation/ple.inria.thierry_parmentelat
# define {js,css}_{files,chunks}
prelude_env = page.prelude_env()
-# print prelude_env.keys()
+# logger.info(prelude_env.keys())
# for k in [ 'js_files' ] :
-# print 'prelude_env',prelude_env,k,prelude_env[k]
+# logger.info('prelude_env {} {} {}'.format(prelude_env,k,prelude_env[k]))
template_env.update(prelude_env)
result=render_to_response ('view-unfold1.html',template_env,
+++ /dev/null
-This is the README.txt file for sla-dashboard application.\r
-\r
-sla-dashboard application is composed by the following directories:\r
-* sladashboard: the app related to the application itself. The settings\r
- file maybe need to be modified: read below.\r
-* slagui: the sla dashboard GUI project.\r
-* slaclient: this project contains all the code needed to connect to\r
- SLA Manager REST interface, and the conversion from xml/json to python\r
- objects.\r
-* samples: this directory contains sample files to load in the SLA Manager for\r
- testing.\r
-* bin: some useful scripts\r
-\r
-\r
-Software requirements\r
----------------------\r
-Python version: 2.7.x\r
-\r
-The required python packages are listed in requirements.txt\r
-\r
-Installing the requirements inside a virtualenv is recommended.\r
-\r
-SLA Manager (java backend) needs to be running in order to use the dashboard.\r
-\r
-Installing\r
-----------\r
-(to be corrected/completed)\r
-\r
-#\r
-# Install virtualenv\r
-#\r
-$ pip install virtualenv\r
-\r
-\r
-#\r
-# Create virtualenv.\r
-# E.g.: VIRTUALENVS_DIR=~/virtualenvs\r
-#\r
-$ virtualenv $VIRTUALENVS_DIR/sla-dashboard\r
-\r
-#\r
-# Activate virtualenv\r
-#\r
-$ . $VIRTUALENVS_DIR/sla-dashboard/bin/activate\r
-\r
-#\r
-# Change to application dir and install requirements\r
-#\r
-$ cd $SLA_DASHBOARD\r
-$ pip install -r requirements.txt\r
-\r
-#\r
-# Create needed tables for sessions, admin, etc\r
-#\r
-$ ./manage.py syncdb\r
-\r
-Settings\r
---------\r
-\r
-* sladashboard/settings.py:\r
- - SLA_MANAGER_URL : The URL of the SLA Manager REST interface.\r
- - DEBUG: Please, set this to FALSE in production\r
-\r
-* sladashboard/urls.py:\r
- - dashboard root url: the slagui project is accessed by default\r
- in $server:$port/slagui. Change "slagui" with the desired path.\r
-\r
-\r
-Running\r
--------\r
-NOTE: this steps are not suitable in production mode.\r
-\r
-#\r
-# Activate virtualenv\r
-#\r
-$ . $VIRTUALENVS_DIR/sla-dashboard/bin/activate\r
-\r
-#\r
-# Cd to application dir\r
-#\r
-$ cd $SLA_DASHBOARD\r
-\r
-#\r
-# Start server listing in port 8000 (change port as desired)\r
-#\r
-$ ./manage.py runserver 0.0.0.0:8000\r
-\r
-#\r
-# Test\r
-#\r
-curl http://localhost:8000/slagui
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<wsag:Template xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"
- TemplateId="iMindsServiceTemplate">
- <wsag:Name>Template for iMinds service</wsag:Name>
- <wsag:Context>
- <wsag:AgreementInitiator>iMinds</wsag:AgreementInitiator>
- <wsag:ServiceProvider>AgreementInitiator</wsag:ServiceProvider>
- <wsag:ExpirationTime>2015-03-07T12:00:00:000</wsag:ExpirationTime>
- <sla:Service xmlns:sla="http://sla.atos.eu">iMinds service</sla:Service>
- </wsag:Context>
- <wsag:Terms>
- <wsag:All>
- <!-- FUNCTIONAL DESCRIPTION -->
- <wsag:ServiceDescriptionTerm wsag:Name="SDTName1" wsag:ServiceName="iMinds service">
- The template for iMinds service
- </wsag:ServiceDescriptionTerm>
-
- <!-- OPTIONAL SERVICE REFERENCE -->
-
- <!-- OPTIONAL SERVICE PROPERTIES : non funcional properties-->
- <wsag:ServiceProperties wsag:Name="NonFunctional" wsag:ServiceName="iMinds service">
- <wsag:VariableSet>
- <wsag:Variable Name="UpTime" Metric="xs:double">
- <wsag:Location>iMinds/UpTime</wsag:Location>
- </wsag:Variable>
- <wsag:Variable Name="Performance" Metric="xs:decimal">
- <wsag:Location>iMinds/Performance</wsag:Location>
- </wsag:Variable>
- </wsag:VariableSet>
- </wsag:ServiceProperties>
- <wsag:GuaranteeTerm Name="GT_CPULoad">
- <wsag:ServiceScope ServiceName="iMinds service"/>
- <wsag:ServiceLevelObjective>
- <wsag:KPITarget>
- <wsag:KPIName>UpTime</wsag:KPIName>
- <wsag:CustomServiceLevel>
- {"constraint" : "UpTime GT 75"}
- </wsag:CustomServiceLevel>
- </wsag:KPITarget>
- </wsag:ServiceLevelObjective>
- </wsag:GuaranteeTerm>
- <wsag:GuaranteeTerm Name="GT_Performance">
- <wsag:ServiceScope ServiceName="iMinds service"/>
- <wsag:ServiceLevelObjective>
- <wsag:KPITarget>
- <wsag:KPIName>Performance</wsag:KPIName>
- <wsag:CustomServiceLevel>
- {"constraint" : "Performance GT 50"}
- </wsag:CustomServiceLevel>
- </wsag:KPITarget>
- </wsag:ServiceLevelObjective>
- </wsag:GuaranteeTerm>
- </wsag:All>
- </wsag:Terms>
-</wsag:Template>
+++ /dev/null
-curl -u normal_user:password -H "Content-type: application/xml" -d@providerIMinds.xml localhost:8080/sla-service/providers -X POST
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<provider>
- <uuid>iMinds</uuid>
- <name>iMinds Testbed</name>
-</provider>
+++ /dev/null
-curl -Umyuser:mypassword -H "Content-type: application/json" -d@simpleAgreementCreationParameters.json localhost:8000/sla/agreements/simplecreate -X POST
\ No newline at end of file
+++ /dev/null
-{"template_id":"iMindsServiceTemplate","user":"imauser"}
+++ /dev/null
-curl -u normal_user:password -H "Content-type: application/xml" -d@TemplateIMindsService.xml localhost:8080/sla-service/templateso -X POST
\ No newline at end of file
+++ /dev/null
-#!/usr/bin/env bash
-#
-# To be executed from application root path
-#
-
-#cmd=$($(grep SLA_MANAGER sladashboard/settings.py) && eval $cmd & print $SLA_MANAGER))
-#eval $(grep SLA_MANAGER_URL sladashboard/settings.py)
-#echo SLA_MANAGER_URL=$SLA_MANAGER_URL
-
-SLA_MANAGER_URL="http://localhost:8080/sla-service"
-
-#
-echo \#Add provider virtualwall
-#
-curl -H "Content-type: application/xml" -d @samples/provider-virtualwall.xml $SLA_MANAGER_URL/providers -X POST
-
-#
-echo \#Add provider wiLab2
-#
-curl -H "Content-type: application/xml" -d @samples/provider-wilab2.xml $SLA_MANAGER_URL/providers -X POST
-
-#
-echo \#Add template
-#
-curl -H "Content-type: application/xml" -d @samples/template.xml $SLA_MANAGER_URL/templates -X POST
-
-#
-echo \#Add agreement03
-#
-curl -H "Content-type: application/xml" -d @samples/agreement03.xml $SLA_MANAGER_URL/agreements -X POST
-curl -H "Content-type: application/xml" -d @samples/enforcement03.xml $SLA_MANAGER_URL/enforcements -X POST
-#curl $SLA_MANAGER_URL/enforcements/agreement03/start -X PUT
-
-#
-echo \#Add agreement04
-#
-curl -H "Content-type: application/xml" -d @samples/agreement04.xml $SLA_MANAGER_URL/agreements -X POST
-curl -H "Content-type: application/xml" -d @samples/enforcement04.xml $SLA_MANAGER_URL/enforcements -X POST
-#curl $SLA_MANAGER_URL/enforcements/agreement04/start -X PUT
-
-#
-#echo \#Add agreement05
-#
-#curl -H "Content-type: application/xml" -d@samples/agreement05.xml $SLA_MANAGER_URL/agreements -X POST
-#curl -d@samples/enforcement05.xml -H "Content-type: application/xml" $SLA_MANAGER_URL/enforcements -X POST
-#curl $SLA_MANAGER_URL/enforcements/agreement05/start -X PUT
-
+++ /dev/null
-#!/bin/bash
-
-if [ $# -eq 1 ] ; then
- curl localhost:8080/sla-service/enforcements/agreement0$1/start -X PUT
-else
- curl localhost:8080/sla-service/enforcements/agreement03/start -X PUT
- curl localhost:8080/sla-service/enforcements/agreement04/start -X PUT
-fi
-
+++ /dev/null
-#!/bin/bash
-
-if [ $# -eq 1 ] ; then
- curl localhost:8080/sla-service/enforcements/agreement0$1/stop -X PUT
-else
- curl localhost:8080/sla-service/enforcements/agreement03/stop -X PUT
- curl localhost:8080/sla-service/enforcements/agreement04/stop -X PUT
-fi
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement03">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>experimenter01</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>virtualwall</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">Testbed_guarantee_0.99_Uptime_rate_for_0.99_rate_of_the_resources_during_the_sliver</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- \r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="UpTime" Metric="xs:double">\r
- <wsag:Location>qos:UpTime</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="Performance" Metric="xs:double">\r
- <wsag:Location>qos:Performance</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
-\r
- <!-- Uptime GuaranteTerm-->\r
- <wsag:GuaranteeTerm Name="GT_UpTime">\r
- <wsag:ServiceScope ServiceName="sla:virtualwall" />\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>UpTime</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "UpTime GT 0.99"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
-\r
- <!-- Resource Performance GuaranteTerm-->\r
- <wsag:GuaranteeTerm Name="GT_Performance">\r
- <wsag:ServiceScope ServiceName="sla:virtualwall" />\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>Performance</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "Performance GT 0.99"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement04">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>experimenter01</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>wiLab2</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">Testbed_guarantee_0.99_Uptime_rate_for_0.99_rate_of_the_resources_during_the_sliver</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- \r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="UpTime" Metric="xs:double">\r
- <wsag:Location>qos:UpTime</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="Performance" Metric="xs:double">\r
- <wsag:Location>qos:Performance</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
-\r
- <!-- Uptime GuaranteTerm-->\r
- <wsag:GuaranteeTerm Name="GT_UpTime">\r
- <wsag:ServiceScope ServiceName="sla:wiLab2" />\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>UpTime</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "UpTime GT 0.99"}\r
- </wsag:CustomServiceLevel> \r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
-\r
- <!-- Resource Performance GuaranteTerm-->\r
- <wsag:GuaranteeTerm Name="GT_Performance">\r
- <wsag:ServiceScope ServiceName="sla:wiLab2" />\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>Performance</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "Performance GT 0.99"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<enforcement_job>
- <agreement_id>agreement03</agreement_id>
- <enabled>false</enabled>
-</enforcement_job>
+++ /dev/null
-<enforcement_job>
- <agreement_id>agreement04</agreement_id>
- <enabled>false</enabled>
-</enforcement_job>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement">\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>RandomClient</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>Provider01</wsag:AgreementResponder>\r
- <!-- The AgreementResponder (in this case) is mandatory if sla is multi \r
- service provider -->\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>contract-template-2007-12-04</wsag:TemplateId>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <!-- FUNCTIONAL DESCRIPTION -->\r
- <!-- <wsag:ServiceDescriptionTerm wsag:Name="SDTName" wsag:ServiceName="ServiceName"> \r
- DSL expression </wsag:ServiceDescriptionTerm> -->\r
-\r
- <!-- OPTIONAL SERVICE REFERENCE -->\r
-\r
- <!-- OPTIONAL SERVICE PROPERTIES : non funcional properties -->\r
- <wsag:ServiceProperties wsag:Name="NonFunctional"\r
- wsag:ServiceName="ServiceName">\r
- <wsag:Variables>\r
- <wsag:Variable wsag:Name="ResponseTime" wsag:Metric="xs:double">\r
- <wsag:Location>qos:ResponseTime</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:Variables>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm wsag:Name="GT_ResponseTime">\r
- <wsag:ServiceScope wsag:ServiceName="ServiceName" />\r
- <!-- The qualifying conditions that must be met before the guarantee \r
- is evaluated -->\r
- <!-- <wsag:QualifyingCondition>state EQ 'ready'</wsag:QualifyingCondition> -->\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>ResponseTime</wsag:KPIName> <!-- same name as property for the moment -->\r
- <wsag:CustomServiceLevel>{"contraint" : "ResponseTime LT 100"}</wsag:CustomServiceLevel> <!-- the ServiceProperty is referenced here -->\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement02">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>RandomClient</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>provider-prueba</wsag:AgreementResponder>\r
- <!--\r
- The AgreementResponder (in this case) is mandatory if sla is multi service provider \r
- -->\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template02</wsag:TemplateId>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <!-- FUNCTIONAL DESCRIPTION -->\r
- <wsag:ServiceDescriptionTerm Name="SDTName1" ServiceName="ServiceName">\r
- DSL expression\r
- </wsag:ServiceDescriptionTerm>\r
- <wsag:ServiceDescriptionTerm Name="SDTName2" ServiceName="ServiceName">\r
- DSL expression\r
- </wsag:ServiceDescriptionTerm>\r
- \r
- <!-- OPTIONAL SERVICE REFERENCE -->\r
- \r
- <!-- OPTIONAL SERVICE PROPERTIES : non funcional properties-->\r
- <wsag:ServiceProperties Name="NonFunctional" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="ResponseTime" Metric="xs:double">\r
- <wsag:Location>qos:ResponseTime</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="Performance" Metric="xs:double">\r
- <wsag:Location>qos:Performance</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm Name="GT_ResponseTime">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <!-- The qualifying conditions that must be met before the guarantee is evaluated -->\r
- <!-- \r
- <wsag:QualifyingCondition>state EQ 'ready'</wsag:QualifyingCondition>\r
- -->\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>ResponseTime</wsag:KPIName> <!-- same name as property for the moment -->\r
- <wsag:CustomServiceLevel>{"constraint" : "ResponseTime LT 0.9"}</wsag:CustomServiceLevel> <!-- the ServiceProperty is referenced here -->\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Performance">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>Performance</wsag:KPIName> <!-- same name as property for the moment -->\r
- <wsag:CustomServiceLevel>{"constraint" : "Performance GT 0.1"}</wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- <wsag:BusinessValueList>\r
- <wsag:Importante>3</wsag:Importante> <!-- optional importance (integer) -->\r
- <wsag:Penalty>\r
- <wsag:AssessmentInterval>\r
- <wsag:Count>10</wsag:Count>\r
- </wsag:AssessmentInterval>\r
- <wsag:ValueUnit>EUR</wsag:ValueUnit>\r
- <wsag:ValueExpression>99</wsag:ValueExpression>\r
- </wsag:Penalty>\r
- \r
- <wsag:Reward></wsag:Reward>\r
- <wsag:Preference></wsag:Preference>\r
- <wsag:CustomBusinessValue></wsag:CustomBusinessValue>\r
- </wsag:BusinessValueList>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement03">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>experimenter01</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>virtualwall</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template02</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">Testbed_guarantee_0.75_Uptime_rate_for_0.8_rate_of_the_resources_during_the_sliver</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <!--\r
- <wsag:ServiceDescriptionTerm Name="SDTName1" ServiceName="ServiceName">\r
- { "servicename": "service-prueba" }\r
- </wsag:ServiceDescriptionTerm>\r
- -->\r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="ResponseTime" Metric="xs:double">\r
- <wsag:Location>service-prueba/ResponseTime</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="Performance" Metric="xs:double">\r
- <wsag:Location>service-prueba/Performance</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm Name="GT_ResponseTime">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>ResponseTime</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "ResponseTime BETWEEN (0, 200)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Performance">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>Performance</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "Performance BETWEEN (0.1,1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement04">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>experimenter01</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>wiLab2</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template02</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">Testbed_guarantee_0.80_uptime_rate_for_0.75_rate_of_the_resources_during_the_sliver</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="metric1" Metric="xs:double">\r
- <wsag:Location>metric1</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric2" Metric="xs:double">\r
- <wsag:Location>metric2</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric3" Metric="xs:double">\r
- <wsag:Location>metric3</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm Name="GT_Metric1">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric1</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric1 BETWEEN (0.1, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric2">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric2</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric2 BETWEEN (0.15, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric3">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric3</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric3 BETWEEN (0.2, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement05">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>client-prueba</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>f4c993580-03fe-41eb-8a21-a56709f9370f</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template02</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">service5</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="metric1" Metric="xs:double">\r
- <wsag:Location>metric1</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric2" Metric="xs:double">\r
- <wsag:Location>metric2</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric3" Metric="xs:double">\r
- <wsag:Location>metric3</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric4" Metric="xs:double">\r
- <wsag:Location>metric4</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm Name="GT_Metric1">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric1</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric1 BETWEEN (0.05, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric2">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric2</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric2 BETWEEN (0.1, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric3">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric3</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric3 BETWEEN (0.15, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric4">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric4</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric4 BETWEEN (0.2, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<wsag:Agreement xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"\r
- AgreementId="agreement05">\r
-\r
- <wsag:Name>ExampleAgreement</wsag:Name>\r
- <wsag:Context>\r
- <wsag:AgreementInitiator>experimenter01</wsag:AgreementInitiator>\r
- <wsag:AgreementResponder>virtualwall</wsag:AgreementResponder>\r
- <wsag:ServiceProvider>AgreementResponder</wsag:ServiceProvider>\r
- <wsag:ExpirationTime>2014-03-07T12:00:00</wsag:ExpirationTime>\r
- <wsag:TemplateId>template02</wsag:TemplateId>\r
- <sla:Service xmlns:sla="http://sla.atos.eu">service5</sla:Service>\r
- </wsag:Context>\r
- <wsag:Terms>\r
- <wsag:All>\r
- <wsag:ServiceProperties Name="ServiceProperties" ServiceName="ServiceName">\r
- <wsag:VariableSet>\r
- <wsag:Variable Name="metric1" Metric="xs:double">\r
- <wsag:Location>metric1</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric2" Metric="xs:double">\r
- <wsag:Location>metric2</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric3" Metric="xs:double">\r
- <wsag:Location>metric3</wsag:Location>\r
- </wsag:Variable>\r
- <wsag:Variable Name="metric4" Metric="xs:double">\r
- <wsag:Location>metric4</wsag:Location>\r
- </wsag:Variable>\r
- </wsag:VariableSet>\r
- </wsag:ServiceProperties>\r
- <wsag:GuaranteeTerm Name="GT_Metric1">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric1</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric1 BETWEEN (0.05, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric2">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric2</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric2 BETWEEN (0.1, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric3">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric3</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric3 BETWEEN (0.15, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- <wsag:GuaranteeTerm Name="GT_Metric4">\r
- <wsag:ServiceScope ServiceName="ServiceName"/>\r
- <wsag:ServiceLevelObjective>\r
- <wsag:KPITarget>\r
- <wsag:KPIName>metric4</wsag:KPIName>\r
- <wsag:CustomServiceLevel>\r
- {"constraint" : "metric4 BETWEEN (0.2, 1)"}\r
- </wsag:CustomServiceLevel>\r
- </wsag:KPITarget>\r
- </wsag:ServiceLevelObjective>\r
- </wsag:GuaranteeTerm>\r
- </wsag:All>\r
- </wsag:Terms>\r
-</wsag:Agreement>\r
+++ /dev/null
-<enforcement_job>
- <agreement_id>agreement04</agreement_id>
- <enabled>false</enabled>
-</enforcement_job>
+++ /dev/null
-<enforcement_job>
- <agreement_id>agreement02</agreement_id>
- <enabled>true</enabled>
-</enforcement_job>
+++ /dev/null
-<enforcement_job>
- <agreement_id>agreement05</agreement_id>
- <enabled>true</enabled>
-</enforcement_job>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-From http://serviceqos.wikispaces.com/WSAgExample
- -->
-<wsag:Template xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement" TemplateId="contract-template-2007-12-04">
- <wsag:Name>ExampleTemplate</wsag:Name>
- <wsag:Context>
- <wsag:AgreementInitiator>Provider</wsag:AgreementInitiator>
- <wsag:ServiceProvider>AgreementInitiator</wsag:ServiceProvider>
- <wsag:ExpirationTime>2013-12-15-1200</wsag:ExpirationTime>
- <wsag:TemplateId>contract-template-2013-12-15</wsag:TemplateId>
- </wsag:Context>
- <wsag:Terms>
- <wsag:All>
- <!-- functional description -->
- <wsag:ServiceDescriptionTerm
- wsag:Name="General"
- wsag:ServiceName="Service0001">
- A GPS service
- </wsag:ServiceDescriptionTerm>
- <wsag:ServiceDescriptionTerm
- wsag:Name="GetCoordsOperation"
- wsag:ServiceName="GPSService0001">
- operation to call to get the coords
- </wsag:ServiceDescriptionTerm>
- <!-- domain specific reference to a service (additional or optional to SDT) -->
- <wsag:ServiceReference
- wsag:Name="CoordsRequest"
- wsag:ServiceName="GPSService0001">
- <wsag:EndpointReference>
- <wsag:Address>http://www.gps.com/coordsservice/getcoords</wsag:Address>
- <wsag:ServiceName>gps:CoordsRequest</wsag:ServiceName>
- </wsag:EndpointReference>
- </wsag:ServiceReference>
- <!-- non-functional properties -->
- <wsag:ServiceProperties
- wsag:Name="AvailabilityProperties"
- wsag:ServiceName="GPS0001">
- <wsag:Variables>
- <wsag:Variable
- wsag:Name="ResponseTime"
- wsag:Metric="metric:Duration">
- <wsag:Location>qos:ResponseTime</wsag:Location>
- </wsag:Variable>
- </wsag:Variables>
- </wsag:ServiceProperties>
- <wsag:ServiceProperties
- wsag:Name="UsabilityProperties"
- wsag:ServiceName="GPS0001">
- <wsag:Variables>
- <wsag:Variable
- wsag:Name="CoordDerivation"
- wsag:Metric="metric:CoordDerivationMetric">
- <wsag:Location>qos:CoordDerivation</wsag:Location>
- </wsag:Variable>
- </wsag:Variables>
- </wsag:ServiceProperties>
- <!-- statements to offered service level(s) -->
- <wsag:GuaranteeTerm
- Name="FastReaction" Obligated="ServiceProvider">
- <wsag:ServiceScope ServiceName="GPS0001">
- http://www.gps.com/coordsservice/getcoords
- </wsag:ServiceScope>
- <wsag:QualifyingCondition>
- applied when current time in week working hours
- </wsag:QualifyingCondition>
- <wsag:ServiceLevelObjective>
- <wsag:KPITarget>
- <wsag:KPIName>FastResponseTime</wsag:KPIName>
- <wsag:Target>
- //Variable/@Name="ResponseTime" LOWERTHAN 1 second
- </wsag:Target>
- </wsag:KPITarget>
- </wsag:ServiceLevelObjective>
- </wsag:GuaranteeTerm>
- </wsag:All>
- </wsag:Terms>
-</wsag:Template>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<provider>
- <uuid>virtualwall</uuid>
- <name>virtualwall</name>
-</provider>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<provider>
- <uuid>wiLab2</uuid>
- <name>wiLab2</name>
-</provider>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<wsag:Template xmlns:wsag="http://www.ggf.org/namespaces/ws-agreement"
- TemplateId="template">
- <wsag:Name>ExampleTemplate2</wsag:Name>
- <wsag:Context>
- <wsag:ExpirationTime>2014-03-07T12:00:00:000</wsag:ExpirationTime>
- </wsag:Context>
- <wsag:Terms>
- <wsag:All>
- <!-- FUNCTIONAL DESCRIPTION -->
- <wsag:ServiceDescriptionTerm wsag:Name="SDTName1" wsag:ServiceName="ServiceName">
- DSL expression
- </wsag:ServiceDescriptionTerm>
- <wsag:ServiceDescriptionTerm wsag:Name="SDTName2" wsag:ServiceName="ServiceName">
- DSL expression
- </wsag:ServiceDescriptionTerm>
-
- <!-- OPTIONAL SERVICE REFERENCE -->
-
- <!-- OPTIONAL SERVICE PROPERTIES : non funcional properties-->
- <wsag:ServiceProperties wsag:Name="NonFunctional" wsag:ServiceName="ServiceName">
- <wsag:Variables>
- <wsag:Variable wsag:Name="ResponseTime" wsag:Metric="xs:double">
- <wsag:Location>qos:ResponseTime</wsag:Location>
- </wsag:Variable>
- <wsag:Variable wsag:Name="Performance" wsag:Metric="xs:double">
- <wsag:Location>qos:Performance</wsag:Location>
- </wsag:Variable>
- </wsag:Variables>
- </wsag:ServiceProperties>
- <wsag:GuaranteeTerm wsag:Name="GT_ResponseTime">
- <wsag:ServiceScope wsag:ServiceName="ServiceName"/>
- <!-- The qualifying conditions that must be met before the guarantee is evaluated -->
- <!--
- <wsag:QualifyingCondition>state EQ 'ready'</wsag:QualifyingCondition>
- -->
- <wsag:ServiceLevelObjective>
- <wsag:KPITarget>
- <wsag:KPIName>ResponseTime</wsag:KPIName> <!-- same name as property for the moment -->
- <wsag:CustomServiceLevel>{"constraint" : "ResponseTime LT qos:ResponseTime"}</wsag:CustomServiceLevel> <!-- the ServiceProperty is referenced here -->
- </wsag:KPITarget>
- </wsag:ServiceLevelObjective>
- </wsag:GuaranteeTerm>
- <wsag:GuaranteeTerm wsag:Name="GT_Performance">
- <wsag:ServiceScope wsag:ServiceName="ServiceName"/>
- <wsag:ServiceLevelObjective>
- <wsag:KPITarget>
- <wsag:KPIName>Performance</wsag:KPIName> <!-- same name as property for the moment -->
- <wsag:CustomServiceLevel>{"constraint" : "Performance GT qos:Performance"}</wsag:CustomServiceLevel>
- </wsag:KPITarget>
- </wsag:ServiceLevelObjective>
- <wsag:BusinessValueList>
- <wsag:Importante>3</wsag:Importante> <!-- optional importance (integer) -->
- <wsag:Penalty>
- <wsag:AssessmentInterval>
- <wsag:Count>10</wsag:Count>
- </wsag:AssessmentInterval>
- <wsag:ValueUnit>EUR</wsag:ValueUnit>
- <wsag:ValueExpression>99</wsag:ValueExpression>
- </wsag:Penalty>
-
- <wsag:Reward></wsag:Reward>
- <wsag:Preference></wsag:Preference>
- <wsag:CustomBusinessValue></wsag:CustomBusinessValue>
- </wsag:BusinessValueList>
- </wsag:GuaranteeTerm>
- </wsag:All>
- </wsag:Terms>
-</wsag:Template>
import requests
from requests.auth import HTTPBasicAuth
+from myslice.settings import logger
import xmlconverter
import wsag_model
_VIOLATIONS_PATH = "violations"
_ENFORCEMENTJOBS_PATH = "enforcements"
-rooturl = settings.SLA_MANAGER_URL
+rooturl = settings.SLA_COLLECTOR_URL
class Factory(object):
@staticmethod
- def agreements(path=_AGREEMENTS_PATH):
+ def agreements():
"""Returns a REST client for Agreements
:rtype : Agreements
"""
- return Agreements(rooturl, path)
+ return Agreements(rooturl)
@staticmethod
def providers():
c = Client("http://localhost:8080/service")
c.get("/resource", headers = { "accept": "application/json" })
"""
- url = _buildpath_(self.rooturl, path)
+ url = _buildpath(self.rooturl, path)
if "testbed" in kwargs:
url = url + "?testbed=" + kwargs["testbed"]
if "headers" not in kwargs:
kwargs["headers"] = {"accept": "application/xml"}
- kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER,
- settings.SLA_MANAGER_PASSWORD)
+
+ kwargs["auth"] = HTTPBasicAuth(settings.SLA_COLLECTOR_USER,
+ settings.SLA_COLLECTOR_PASSWORD)
# for key, values in kwargs.iteritems():
# print key, values
result = requests.get(url, **kwargs)
- print "GET {} {} {}".format(
- result.url, result.status_code, result.text[0:70])
- print result.encoding
+ logger.debug('SLA GET {} - result: {}'.format(result.url, result.status_code))
+ # print "GET {} {} {}".format(
+ # result.url, result.status_code, result.text[0:70])
+ # print result.encoding
return result
}
)
"""
- url = _buildpath_(self.rooturl, path)
+ url = _buildpath(self.rooturl, path)
if "testbed" in kwargs:
url = url + "?testbed=" + kwargs["testbed"]
+ del kwargs["testbed"]
if "headers" not in kwargs:
kwargs["headers"] = {"accept": "application/xml",
"content-type": "application/xml"}
- kwargs["auth"] = HTTPBasicAuth(settings.SLA_MANAGER_USER,
- settings.SLA_MANAGER_PASSWORD)
+ kwargs["auth"] = HTTPBasicAuth(settings.SLA_COLLECTOR_USER,
+ settings.SLA_COLLECTOR_PASSWORD)
result = requests.post(url, data, **kwargs)
location = result.headers["location"] \
if "location" in result.headers else "<null>"
- print "POST {} {} Location: {}".format(
+ print "POST {} {} - Location: {}".format(
result.url, result.status_code, location)
return result
resource = _Resource._processresult(r, self.converter)
return resource, r
- def get(self, path, params):
+ def get(self, path="", params={}):
"""Generic query over resource: GET /resource?q1=v1&q2=v2...
:param dict[str,str] params: values to pass as get parameters
"""
- if path is None:
- path = ""
r = self.client.get(path, params=params)
resources = self._processresult(r, self.listconverter)
The final url to the resource is root_url + "/" + path
"""
- resourceurl = _buildpath_(root_url, path)
- converter = xmlconverter.AgreementConverter()
- self.res = _Resource(resourceurl, converter)
+ self.resourceurl = _buildpath(root_url, path)
+ self.converter = xmlconverter.AgreementConverter()
+ self.res = _Resource(self.resourceurl, self.converter)
def getall(self):
"""
:param str agreementid :
:rtype : wsag_model.AgreementStatus
"""
- path = _buildpath_(_AGREEMENTS_PATH, agreementid, "guaranteestatus")
+ # path = _buildpath(_AGREEMENTS_PATH, agreementid, "guaranteestatus")
+ path = _buildpath(agreementid, "guaranteestatus")
r = self.res.client.get(path, headers={'accept': 'application/json'},
params={'testbed': testbed})
json_obj = r.json()
-
status = wsag_model.AgreementStatus.json_decode(json_obj)
return status, r
:rtype : list[wsag_model.Agreement]
"""
- return self.res.get(slicename, dict())
+ self.resourceurl = _buildpath(rooturl, 'slice')
+ self.res = _Resource(self.resourceurl, self.converter)
+ return self.res.get(slicename)
def create(self, agreement, testbed):
"""Create a new agreement
The final url to the resource is root_url + "/" + path
"""
- resourceurl = _buildpath_(root_url, path)
+ resourceurl = _buildpath(root_url, path)
converter = xmlconverter.AgreementConverter()
self.res = _Resource(resourceurl, converter)
The final url to the resource is root_url + "/" + path
"""
- resourceurl = _buildpath_(root_url, path)
+ resourceurl = _buildpath(root_url, path)
converter = xmlconverter.ProviderConverter()
self.res = _Resource(resourceurl, converter)
The final url to the resource is root_url + "/" + path
"""
- resourceurl = _buildpath_(root_url, path)
+ resourceurl = _buildpath(root_url, path)
converter = xmlconverter.ViolationConverter()
self.res = _Resource(resourceurl, converter)
The final url to the resource is root_url + "/" + path
"""
- resourceurl = _buildpath_(root_url, path)
+ resourceurl = _buildpath(root_url, path)
converter = xmlconverter.EnforcementConverter()
self.res = _Resource(resourceurl, converter)
return self.res.getbyid(agreement_id, params={"testbed": testbed})
-def _buildpath_(*paths):
+def _buildpath(*paths):
if "" in paths:
paths = [path for path in paths if path != ""]
s = "<GuaranteeTermStatus(name='{}' status='{}')>"
return s.format(self.name, self.status)
- def __init__(self):
+ def __init__(self, lst=None):
self.agreement_id = ""
self.guaranteestatus = ""
- self.guaranteeterms = []
+ if lst is None:
+ self.guaranteeterms = []
+ else:
+ self.guaranteeterms = lst
def __repr__(self):
return (
c.convert(root.getroot())
"""
+from myslice.settings import logger
try:
# Much faster and lighter library (C implementation)
:param Element xmlroot: root element of xml to convert.
:rtype: wsag_model.Agreement
"""
- for name, value in xmlroot.attrib.items():
- print '{0}="{1}"'.format(name, value)
+ # for name, value in xmlroot.attrib.items():
+ # logger.debug('SLA xmlconverter: {} = {}'.format(name, value))
if xmlroot.tag in self.agreement_tags:
result = Agreement()
nss = self._namespaces
for element in elements:
servicename = _get_attribute(element, "ServiceName")
- for var in element.findall("wsag:Variables/wsag:Variable", nss):
+ for var in element.findall("wsag:VariableSet/wsag:Variable", nss):
key, value = self._parse_property(var, servicename)
result[key] = value
+from __future__ import print_function
+
# this somehow is not used anymore - should it not be ?
+import ast
+from datetime import datetime
+import json
+import pytz
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.shortcuts import render
from django import forms
+import re
-from unfold.loginrequired import FreeAccessView
+from unfold.loginrequired import LoginRequiredView, FreeAccessView
from unfold.page import Page
from sla.slaclient import restclient
from sla.slaclient import wsag_model
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import slaclient.service.fed4fire.fed4fireservice as fed4fireservice
-from rest_framework.views import APIView
from django.http import HttpResponse
-import json
-import traceback
-import re
-from math import ceil
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-from dateutil.tz import tzlocal
-from django.conf import settings
-
-
-class Rol:
- CONSUMER = "CONSUMER"
- PROVIDER = "PROVIDER"
-
-
-class AgreementsFilter(object):
- def __init__(self, status=None, provider=None, consumer=None):
- self.status = status
- self.provider = provider
- self.consumer = consumer
-
- def __repr__(self):
- return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
- self.status, self.provider, self.consumer
- )
-
- @staticmethod
- def _check(expectedvalue, actualvalue):
- if expectedvalue is None or expectedvalue == '':
- return True
- else:
- return actualvalue == expectedvalue
-
- def check(self, agreement):
- """Check if this agreement satisfy the filter.
-
- The agreement must be previously annotated
- """
- guaranteestatus = agreement.guaranteestatus
- provider = agreement.context.provider
- consumer = agreement.context.consumer
- return (
- AgreementsFilter._check(self.status, guaranteestatus) and
- AgreementsFilter._check(self.provider, provider) and
- AgreementsFilter._check(self.consumer, consumer)
- )
-
-
-class FilterForm(forms.Form):
- _attrs = {'class': 'form-control'}
- exclude = ()
- status = forms.ChoiceField(
- choices=[
- ('', 'All'),
- (wsag_model.AgreementStatus.StatusEnum.FULFILLED, 'Fulfilled'),
- (wsag_model.AgreementStatus.StatusEnum.VIOLATED, 'Violated'),
- (wsag_model.AgreementStatus.StatusEnum.NON_DETERMINED, 'Non determined')],
- widget=forms.Select(attrs=_attrs),
- required=False
- )
- provider = forms.CharField(
- widget=forms.TextInput(attrs=_attrs),
- required=False
- )
- consumer = forms.CharField(
- widget=forms.TextInput(attrs=_attrs),
- required=False
- )
-
-
-class SLAView (FreeAccessView, ThemeView):
+from myslice.settings import logger, SLA_COLLECTOR_URL
+
+
+# class AgreementsFilter(object):
+# def __init__(self, status=None, provider=None, consumer=None):
+# self.status = status
+# self.provider = provider
+# self.consumer = consumer
+#
+# def __repr__(self):
+# return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
+# self.status, self.provider, self.consumer
+# )
+#
+# @staticmethod
+# def _check(expectedvalue, actualvalue):
+# if expectedvalue is None or expectedvalue == '':
+# return True
+# else:
+# return actualvalue == expectedvalue
+#
+# def check(self, agreement):
+# """Check if this agreement satisfy the filter.
+#
+# The agreement must be previously annotated
+# """
+# guaranteestatus = agreement.guaranteestatus
+# provider = agreement.context.provider
+# consumer = agreement.context.consumer
+# return (
+# AgreementsFilter._check(self.status, guaranteestatus) and
+# AgreementsFilter._check(self.provider, provider) and
+# AgreementsFilter._check(self.consumer, consumer)
+# )
+
+
+# class FilterForm(forms.Form):
+# _attrs = {'class': 'form-control'}
+# exclude = ()
+# status = forms.ChoiceField(
+# choices=[
+# ('', 'All'),
+# (wsag_model.AgreementStatus.StatusEnum.FULFILLED, 'Fulfilled'),
+# (wsag_model.AgreementStatus.StatusEnum.VIOLATED, 'Violated'),
+# (wsag_model.AgreementStatus.StatusEnum.NON_DETERMINED, 'Non determined')],
+# widget=forms.Select(attrs=_attrs),
+# required=False
+# )
+# provider = forms.CharField(
+# widget=forms.TextInput(attrs=_attrs),
+# required=False
+# )
+# consumer = forms.CharField(
+# widget=forms.TextInput(attrs=_attrs),
+# required=False
+# )
+
+
+class SLAView(FreeAccessView, ThemeView):
template_name = 'slice-tab-sla.html'
- def get (self, request, slicename, state=None):
+ def get(self, request, slicename):
+
+ page = Page(request)
- page=Page(request)
+ # logger.debug("SLA slice name: {}".format(slicename))
- consumer_id = None
+ # consumer_id = None
agreement_id = None
enforcements = {}
violations = {}
- keys = ['provider','agreement','date','status','result','ok']
+ keys = ['provider', 'agreement',
+ 'date', 'status', 'result',
+ 'ok', 'slivers']
ag_info = []
- filter_ = None
- form = FilterForm(request.GET)
- if form.is_valid():
- filter_ = _get_filter_from_form(form)
+ # filter_ = None
+ # form = FilterForm(request.GET)
+ # if form.is_valid():
+ # filter_ = _get_filter_from_form(form)
- consumer_id = _get_consumer_id(request)
+ # consumer_id = _get_consumer_id(request)
- #agreements = _get_agreements(agreement_id, consumer_id=consumer_id, filter_=filter_)
- agreements = _get_agreements(agreement_id, slice=slicename)
+ # agreements = _get_agreements(agreement_id, consumer_id=consumer_id, filter_=filter_)
+ agreements = _get_agreements_by_slice(slicename)
for agreement in agreements:
row = []
provider = agreement.context.provider
- row.append(provider) # Provider
- row.append(agreement) # Agreement
- row.append(agreement.context.time_formatted()) # Date
+ row.append(provider) # Provider
+ row.append(agreement) # Agreement
+ row.append(agreement.context.time_formatted()) # Date
enf = _get_enforcement(agreement.agreement_id, provider)
+ # logger.debug("SLA guarantee status {}: {}".format(agreement.agreement_id,
+ # agreement.guaranteestatus))
if enf.enabled == 'true':
- row.append('Evaluating') # Status
- row.append('') # Result
- row('') # Ok
+ row.append('Evaluating') # Status
+ row.append('') # Result
+ row.append('') # Ok
else:
if agreement.guaranteestatus == "NON_DETERMINED":
- row.append('Provisioned') # Status
- row.append('') # Result
- row.append('') # Ok
-
+ row.append('Provisioned') # Status
+ row.append('') # Result
+ row.append('') # Ok
+
else:
- row.append('Finished') # Status
+ row.append('Finished') # Status
violations_list = _get_agreement_violations(agreement.agreement_id, provider, "GT_Performance")
-
+
if len(violations_list) > 0:
- value = '%.2f'%float(violations_list[0].actual_value)
- row.append('%d'%(float(value)*100)) # Result
+ value = '%.2f' % float(violations_list[0].actual_value)
+ row.append('%d' % (float(value) * 100)) # Result
else:
- row.append('100') # Result
+ row.append('100') # Result
if agreement.guaranteestatus == "VIOLATED":
- row.append('false') # Ok
+ row.append('false') # Ok
if agreement.guaranteestatus == "FULFILLED":
- row.append('true') # Ok
+ row.append('true') # Ok
- ag_info.append(dict(zip(keys,row)))
+ for _, terms in agreement.guaranteeterms.items():
+ try:
+ s = ast.literal_eval(terms.scopes[0].scope.lstrip())
+ logger.debug('SLA scope: {}'.format(s))
+ row.append(s)
+ break
+ except Exception as e:
+ logger.debug("SLA EXCEPTION: {}".format(e.message))
+
+ ag_info.append(dict(zip(keys, row)))
template_env = {}
- # write something of our own instead
- # more general variables expected in the template
+ # write something of our own instead
+ # more general variables expected in the template
template_env['title'] = 'SLA Agreements'
template_env['agreements'] = agreements
template_env['username'] = request.user
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}
+ # 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))
-class AgreementsFilter(object):
- def __init__(self, status=None, provider=None, consumer=None):
- self.status = status
- self.provider = provider
- self.consumer = consumer
-
- def __repr__(self):
- return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
- self.status, self.provider, self.consumer
- )
-
- @staticmethod
- def _check(expectedvalue, actualvalue):
- if expectedvalue is None or expectedvalue == '':
- return True
- else:
- return actualvalue == expectedvalue
-
- def check(self, agreement):
- """Check if this agreement satisfy the filter.
-
- The agreement must be previously annotated
- """
- guaranteestatus = agreement.guaranteestatus
- provider = agreement.context.provider
- consumer = agreement.context.consumer
- return (
- AgreementsFilter._check(self.status, guaranteestatus) and
- AgreementsFilter._check(self.provider, provider) and
- AgreementsFilter._check(self.consumer, consumer)
- )
-
-
-class ContactForm(forms.Form):
- subject = forms.CharField(max_length=100)
- message = forms.CharField()
- sender = forms.EmailField()
- cc_myself = forms.BooleanField(required=False)
-
-
-def _get_agreements_client(path=""):
- return restclient.Factory.agreements(path)
+# class AgreementsFilter(object):
+# def __init__(self, status=None, provider=None, consumer=None):
+# self.status = status
+# self.provider = provider
+# self.consumer = consumer
+#
+# def __repr__(self):
+# return "<AgreementsFilter(status={}, provider={}, consumer={})>".format(
+# self.status, self.provider, self.consumer
+# )
+#
+# @staticmethod
+# def _check(expectedvalue, actualvalue):
+# if expectedvalue is None or expectedvalue == '':
+# return True
+# else:
+# return actualvalue == expectedvalue
+#
+# def check(self, agreement):
+# """Check if this agreement satisfy the filter.
+#
+# The agreement must be previously annotated
+# """
+# guaranteestatus = agreement.guaranteestatus
+# provider = agreement.context.provider
+# consumer = agreement.context.consumer
+# return (
+# AgreementsFilter._check(self.status, guaranteestatus) and
+# AgreementsFilter._check(self.provider, provider) and
+# AgreementsFilter._check(self.consumer, consumer)
+# )
+
+
+# class ContactForm(forms.Form):
+# subject = forms.CharField(max_length=100)
+# message = forms.CharField()
+# sender = forms.EmailField()
+# cc_myself = forms.BooleanField(required=False)
+
+
+def _get_agreements_client():
+ return restclient.Factory.agreements()
def _get_violations_client():
return restclient.Factory.violations()
+
def _get_enforcements_client():
return restclient.Factory.enforcements()
+
def _get_consumer_id(request):
return request.user
def _get_agreement(agreement_id):
-
agreements_client = _get_agreements_client()
agreement, response = agreements_client.getbyid(agreement_id)
return agreement
-def _get_enforcement(agreement_id, testbed):
+def _get_enforcement(agreement_id, testbed):
enforcements_client = _get_enforcements_client()
enforcement, response = enforcements_client.getbyagreement(agreement_id, testbed)
return enforcement
-def _get_filter_from_form(form):
- data = form.cleaned_data
- result = AgreementsFilter(
- data["status"], data["provider"], data["consumer"])
- return result
+# def _get_filter_from_form(form):
+#
+# data = form.cleaned_data
+# result = AgreementsFilter(
+# data["status"], data["provider"], data["consumer"])
+# return result
def agreement_term_violations(request, agreement_id, guarantee_name):
-
page = Page(request)
prelude_env = page.prelude_env()
agreement = _get_agreement(agreement_id)
violations = _get_agreement_violations(agreement_id, guarantee_name)
annotator.annotate_agreement(agreement)
-
+
slicename = request.POST.get('slicename')
-
- paginator = Paginator(violations, 25) # Show 25 violations per page
+
+ paginator = Paginator(violations, 25) # Show 25 violations per page
page_num = request.GET.get('page')
-
+
try:
violation_page = paginator.page(page_num)
except PageNotAnInteger:
except EmptyPage:
# If page is out of range (e.g. 9999), deliver first page.
violation_page = paginator.page(1)
-
+
context = {
'agreement_id': agreement_id,
'guarantee_term': agreement.guaranteeterms[guarantee_name],
'slicename': slicename,
'last_violation': violations[-1].actual_value
}
-
+
context.update(prelude_env)
-
- return render_to_response ('violations_template.html', context, context_instance=RequestContext(request))
+
+ return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
+
+
# return render(request, 'violations_template.html', context)
+
+# TODO Change function to class
def agreement_details(request, agreement_id):
-
page = Page(request)
prelude_env = page.prelude_env()
-
+
annotator = wsag_helper.AgreementAnnotator()
agreement = _get_agreement(agreement_id)
violations = _get_agreement_violations(agreement_id)
'status': status,
'violations_by_date': violations_by_date
}
-
- context.update(prelude_env)
-
- return render_to_response ('violations_template.html', context, context_instance=RequestContext(request))
- #return render(request, 'agreement_detail.html', context)
-def _get_agreement(agreement_id):
+ context.update(prelude_env)
- agreements_client = _get_agreements_client()
- agreement, response = agreements_client.getbyid(agreement_id)
- return agreement
+ return render_to_response('violations_template.html', context, context_instance=RequestContext(request))
+ #return render(request, 'agreement_detail.html', context)
-def _get_agreements(agreement_id, slice=None, provider_id=None, consumer_id=None, filter_=None):
+# def _get_agreements(agreement_id, slice=None, provider_id=None, consumer_id=None, filter_=None):
+#
+# agreements_client = _get_agreements_client()
+# if agreement_id is None:
+# if consumer_id is not None:
+# agreements, response = agreements_client.getbyconsumer(consumer_id)
+# elif provider_id is not None:
+# agreements, response = agreements_client.getbyprovider(provider_id)
+# elif slice is not None:
+# agreements_client = _get_agreements_client("slice")
+# agreements, response = agreements_client.getbyslice(slice)
+# else:
+# raise ValueError(
+# "Invalid values: consumer_id and provider_id are None")
+# else:
+# agreement, response = agreements_client.getbyid(agreement_id)
+# agreements = [agreement]
+#
+# annotator = wsag_helper.AgreementAnnotator()
+# for agreement in agreements:
+# id_ = agreement.agreement_id
+# testbed = agreement.context.provider
+# status = _get_agreement_status(id_, testbed)
+# annotator.annotate_agreement(agreement, status)
+#
+# if filter_ is not None:
+# print "FILTERING ", repr(filter_)
+# agreements = filter(filter_.check, agreements)
+# else:
+# print "NOT FILTERING"
+# return agreements
+
+def _get_agreements_by_slice(slice):
agreements_client = _get_agreements_client()
- if agreement_id is None:
- if consumer_id is not None:
- agreements, response = agreements_client.getbyconsumer(consumer_id)
- elif provider_id is not None:
- agreements, response = agreements_client.getbyprovider(provider_id)
- elif slice is not None:
- agreements_client = _get_agreements_client("slice")
- agreements, response = agreements_client.getbyslice(slice)
- else:
- raise ValueError(
- "Invalid values: consumer_id and provider_id are None")
- else:
- agreement, response = agreements_client.getbyid(agreement_id)
- agreements = [agreement]
+ agreements, response = agreements_client.getbyslice(slice)
annotator = wsag_helper.AgreementAnnotator()
for agreement in agreements:
status = _get_agreement_status(id_, testbed)
annotator.annotate_agreement(agreement, status)
- if filter_ is not None:
- print "FILTERING ", repr(filter_)
- agreements = filter(filter_.check, agreements);
- else:
- print "NOT FILTERING"
return agreements
-def _get_agreements_by_consumer(consumer_id):
-
- agreements_client = _get_agreements_client()
- agreements, response = agreements_client.getbyconsumer(consumer_id)
- return agreements
+# def _get_agreements_by_consumer(consumer_id):
+#
+# agreements_client = _get_agreements_client()
+# agreements, response = agreements_client.getbyconsumer(consumer_id)
+# return agreements
def _get_agreement_status(agreement_id, testbed):
-
agreements_client = _get_agreements_client()
status, response = agreements_client.getstatus(agreement_id, testbed)
return status
-def _get_agreement_violations(agreement_id, testbed, term=None):
+def _get_agreement_violations(agreement_id, testbed, term=None):
violations_client = _get_violations_client()
violations, response = violations_client.getbyagreement(agreement_id, testbed, term)
return violations
-class AgreementSimple(APIView):
+class Testbeds(FreeAccessView, ThemeView):
+ def get(self, request, *args, **kwargs):
+ c = restclient.Client(SLA_COLLECTOR_URL)
+ #url = settings.SLA_MANAGER_URL.replace("/sla","")
+ #c = restclient.Client(url)
+ # print "**** URL ******", url
+ SLAtestbeds = c.get("testbeds/")
+ # Future work: get SLA description for each testbed
- regex = r"[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"
+ return HttpResponse(SLAtestbeds.text, content_type="application/json", status=SLAtestbeds.status_code)
- def build_response(self, code, text):
- response = HttpResponse(text, content_type="text/plain", status=code)
- return response
- def post(self, request, **kwargs):
- #import pdb; pdb.set_trace()
- print "------------------------------------------------1"
- data = request.POST
+class CreateAgreement(LoginRequiredView, ThemeView):
+ def post(self, request, *args, **kwargs):
- url = settings.SLA_MANAGER_URL
- c = restclient.Client(url)
- # for key, value in request.DATA.items(): # jgarcia review this
- # data[key] = value
-
- # print "---- DATA: ----"
- # print "Data type: ", type(data)
- # for key in data:
- # print key, data.getlist(key)
+ c = restclient.Client(SLA_COLLECTOR_URL)
+ data = request.POST.copy()
- try:
- # template_id = data['template_id']
- testbeds = data.getlist("testbeds")
- user = data["user"]
- resources = data.getlist("resources")
- slice_id = data["slice"]
- except:
- print "FAIL!"
- return self.build_response(400, 'Invalid data')
-
- selected_resources = {}
-
- now = datetime.now(tzlocal())
- expiration_time = now + relativedelta(years=1)
-
- for testbed in testbeds:
- selected_resources[testbed] = [r for r in resources if testbed in r]
- template_id = testbed
- try:
- print "Calling createagreementsimplified with template_id:",template_id,"and user:",user
- result = fed4fireservice.createagreementsimplified(
- template_id, user, expiration_time, selected_resources)
- print result
- except Exception, e:
- print traceback.format_exc()
- print '%s (%s)' % (e, type(e))
- return self.build_response(400, 'Problem creating agreement')
-
- agreement_id = re.compile(self.regex).search(result.text).group(0)
-
- data = '{{ "id": "{}", \
- "slice": "{}", \
- "testbed": "{}" }}'.format(agreement_id, slice_id, testbed)
-
- c.post(
- "sliver",
- data,
- headers = {
- "content-type": "application/json",
- "accept": "application/xml"
- }
- )
-
- return self.build_response(200, result)
-
-class Testbeds(APIView):
- def get(self, request, **kwargs):
- c = restclient.Client("http://157.193.215.125:4001/sla-collector")
- #url = settings.SLA_MANAGER_URL.replace("/sla","")
- #c = restclient.Client(url)
- print "**** URL ******", url
- SLAtestbeds = c.get("testbeds")
- # Future work: get SLA description for each testbed
+ testbed_urn_regex = r"\+(.*?)\+"
+ pattern = re.compile(testbed_urn_regex)
+ testbed_urn = pattern.search(data["SLIVER_INFO_AGGREGATE_URN"]).group(1)
- return HttpResponse(SLAtestbeds.text, content_type="application/json", status=SLAtestbeds.status_code)
+ # Fix for django QueryDict list parameters
+ slivers = data.getlist("SLIVER_INFO_URN[]")
+ data["SLIVER_INFO_URN"] = slivers
+ del data["SLIVER_INFO_URN[]"]
+
+ # Timestamp to ISO date + timezone
+ tstmp = data["SLIVER_INFO_EXPIRATION"]
+ dt = datetime.fromtimestamp(float(tstmp))
+ # gmt_2 = pytz.timezone("Etc/GMT-2")
+ # dlocal = gmt_2.localize(dt).isoformat()
+ dlocal = dt.isoformat() + "CET" # FIXME: hardcoded for demo purposes
+ data["SLIVER_INFO_EXPIRATION"] = dlocal
+
+ # logger.debug("SLA Agreement parameters: {}".format(data.dict()))
+ # import pdb; pdb.set_trace()
+
+ try:
+ response = c.post("agreementslist/", data=json.dumps(data),
+ headers={"accept": "application/json",
+ "content-type": "application/json"})
+ except Exception as e:
+ # import traceback, sys
+ #
+ # traceback.print_exc(file=sys.stdout)
+ logger.debug("SLA Error: CreateAgreement {}".format(e.message))
+
+ return HttpResponse(response.text, status=response.status_code)
-<div class="col-md-2">
+<div class="col-md-1">
</div>
- <div class="col-md-9">
+ <div class="col-md-10">
<div class="row" id="agreements" style="padding-top:1em;">
<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>
+ <dd>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the selected resources</dd>
<dt>Testbed</dt>
<dd>{{ row.agreement.context.testbed_formatted }}</dd>
<dt>Expiration date:</dt>
<dd>{{ row.date|default:" " }}</dd>
+
+ <dt>Covered resources:</dt>
+ {% for sliver in row.slivers %}
+ <dd>{{ sliver|default:" " }}</dd>
+ {% endfor %}
+
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<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><a class="agreement-detail" data-toggle="modal" data-target="#agreementModal{{row.agreement.agreement_id}}">{{ row.agreement.agreement_id }}</a></td>
<td>{{ row.date }}</td>
<td>{{ row.status }}</td>
+++ /dev/null
-{
- "auto_complete":
- {
- "selected_items":
- [
- ]
- },
- "buffers":
- [
- {
- "file": "slice-tab-sla.html",
- "settings":
- {
- "buffer_size": 6021,
- "line_ending": "Unix"
- }
- }
- ],
- "build_system": "",
- "command_palette":
- {
- "height": 0.0,
- "selected_items":
- [
- ],
- "width": 0.0
- },
- "console":
- {
- "height": 0.0,
- "history":
- [
- ]
- },
- "distraction_free":
- {
- "menu_visible": true,
- "show_minimap": false,
- "show_open_files": false,
- "show_tabs": false,
- "side_bar_visible": false,
- "status_bar_visible": false
- },
- "file_history":
- [
- ],
- "find":
- {
- "height": 0.0
- },
- "find_in_files":
- {
- "height": 0.0,
- "where_history":
- [
- ]
- },
- "find_state":
- {
- "case_sensitive": false,
- "find_history":
- [
- ],
- "highlight": true,
- "in_selection": false,
- "preserve_case": false,
- "regex": false,
- "replace_history":
- [
- ],
- "reverse": false,
- "show_context": true,
- "use_buffer2": true,
- "whole_word": false,
- "wrap": true
- },
- "groups":
- [
- {
- "selected": 0,
- "sheets":
- [
- {
- "buffer": 0,
- "file": "slice-tab-sla.html",
- "semi_transient": false,
- "settings":
- {
- "buffer_size": 6021,
- "regions":
- {
- },
- "selection":
- [
- [
- 0,
- 0
- ]
- ],
- "settings":
- {
- "syntax": "Packages/HTML/HTML.tmLanguage"
- },
- "translation.x": 0.0,
- "translation.y": 0.0,
- "zoom_level": 1.0
- },
- "stack_index": 0,
- "type": "text"
- }
- ]
- }
- ],
- "incremental_find":
- {
- "height": 0.0
- },
- "input":
- {
- "height": 0.0
- },
- "layout":
- {
- "cells":
- [
- [
- 0,
- 0,
- 1,
- 1
- ]
- ],
- "cols":
- [
- 0.0,
- 1.0
- ],
- "rows":
- [
- 0.0,
- 1.0
- ]
- },
- "menu_visible": true,
- "output.find_results":
- {
- "height": 0.0
- },
- "project": "violations_template.sublime-project",
- "replace":
- {
- "height": 0.0
- },
- "save_all_on_build": true,
- "select_file":
- {
- "height": 0.0,
- "selected_items":
- [
- ],
- "width": 0.0
- },
- "select_project":
- {
- "height": 0.0,
- "selected_items":
- [
- ],
- "width": 0.0
- },
- "select_symbol":
- {
- "height": 0.0,
- "selected_items":
- [
- ],
- "width": 0.0
- },
- "settings":
- {
- },
- "show_minimap": true,
- "show_open_files": false,
- "show_tabs": true,
- "side_bar_visible": true,
- "side_bar_width": 150.0,
- "status_bar_visible": true,
- "template_settings":
- {
- }
-}
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'^agreements/create/$',
+ slicetabsla.CreateAgreement.as_view(), name="agreement_create"),
+ # url(r'^agreements/simplecreate/?$',
+ # slicetabsla.AgreementSimple.as_view(), name="agreementsimple"),
)
import re\r
import datetime\r
+from myslice.settings import logger\r
\r
from slaclient import wsag_model\r
from slaclient.wsag_model import AgreementStatus\r
<!--<link rel='stylesheet' href='{{ STATIC_URL }}css/ui.notify.css' type='text/css' />-->
<script type="text/javascript">
+// XXX disabled since jquery ui conflicts with bootstrap!
+
+/*
function create( template, vars, opts ){
return $container.notify("create", template, vars, opts);
}
// container, but can be overwritten on notification-by-notification
// basis.
- // XXX disabled since jquery ui conflicts with bootstrap!
//$container = $("#notifications").notify();
// create two when the pg loads
});
+*/
</script>
# a set of utilities to help make the global layout consistent across views
+from myslice.settings import logger
+
def the_user (request):
"retrieves logged in user's email, or empty string"
if not request.user.is_authenticated ():
def topmenu_items_static (current, request):
has_user=request.user.is_authenticated()
result=[]
- print request.user
+ logger.debug("request user = {}".format(request.user))
if has_user:
result.append({'label':'Dashboard', 'href': '/portal/dashboard/'})
result.append({'label':'Request a slice', 'href': '/portal/slice_request/'})
# tmp - transition phase
def topmenu_items (current, request):
- print "WARNING -- please now use topmenu_items_live (label, page) toplevel_items is deprecated -- WARNING"
+ logger.warning("WARNING -- please now use topmenu_items_live (label, page) toplevel_items is deprecated -- WARNING")
return topmenu_items_static (current, request)
# integrated helper function for an animated menu
# We might use local storage instead
# REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
- query_pi_auths = Query.get('myslice:user').filter_by('user_hrn', '==', '$user_hrn' ).select('user_hrn','pi_authorities')
- page.enqueue_query(query_pi_auths)
+ if request.user.is_authenticated ():
+ query_pi_auths = Query.get('myslice:user').filter_by('user_hrn', '==', '$user_hrn' ).select('user_hrn','pi_authorities')
+ page.enqueue_query(query_pi_auths)
+ else:
+ query_pi_auths = Query()
# # even though this plugin does not have any html materialization, the corresponding domid
# # must exist because it is searched at init-time to create the JS plugin
# # so we simply piggy-back the target button created in the topmenu
+from __future__ import print_function
+
import os
from django.conf import settings
from django.utils.datastructures import SortedDict
matched_path = os.path.join(path, file)
if not all:
return matched_path
- print 'ThirdPartyFinder, adding',matched_path
+ print('ThirdPartyFinder, adding',matched_path)
matches.append(matched_path)
return matches
from unfold.plugin import Plugin
+from myslice.settings import logger
+
class Composite (Plugin):
"""a simple base class for plugins that contain/arrange a set of other plugins
def __init__ (self, sons=None, active_domid=None, *args, **kwds):
Plugin.__init__ (self, *args, **kwds)
- self.sons= sons if sons else []
- self.active_domid=active_domid
+ self.sons = sons if sons else []
+ self.active_domid = active_domid
# make sure this is valid, unset otherwise, so we always have exactly one active
self.check_active_domid()
def check_active_domid(self):
matches= [ son for son in self.sons if son.domid==self.active_domid ]
if len(matches)!=1:
- print "WARNING: %s has %d valid son(s) for being active - expecting 1, resetting"%\
- (self,len(matches))
- self.active_domid=None
+ logger.warning("WARNING: {} has {} valid son(s) for being active - expecting 1, resetting"\
+ .format(self,len(matches)))
+ self.active_domid = None
def insert (self, plugin):
self.sons.append(plugin)
# {% for son in sons %} {{ son.rendered }} ...
def is_active (son,rank):
# if active_domid is not specified, make the first one active
- if not self.active_domid: return rank==0
- return son.domid==self.active_domid
- ranks=range(len(self.sons))
+ if not self.active_domid:
+ return rank==0
+ return son.domid == self.active_domid
+ ranks = range(len(self.sons))
env = { 'sons':
[ { 'rendered': son.render(request),
'rank': rank,
# for 'as_view' that we need to call in urls.py and the like
from django.views.generic.base import TemplateView
-from manifoldapi.manifoldresult import ManifoldException
+from manifoldapi.manifoldresult import ManifoldException
+
+from myslice.settings import logger
###
# IMPORTANT NOTE
def logout_on_manifold_exception (fun_that_returns_httpresponse):
def wrapped (request, *args, **kwds):
-# print 'wrapped by logout_on_manifold_exception'
try:
return fun_that_returns_httpresponse(request,*args, **kwds)
except ManifoldException, manifold_result:
return HttpResponseRedirect ('/')
except Exception, e:
# xxx we need to sugarcoat this error message in some error template...
- print "Unexpected exception",e
+ logger.error("Unexpected exception {}".format(e))
import traceback
- traceback.print_exc()
+ logger.error(traceback.format_exc())
return HttpResponseRedirect ('/')
return wrapped
from manifoldapi.metadata import MetaData
from unfold.prelude import Prelude
-
+from unfold.sessioncache import SessionCache
+
from myslice.configengine import ConfigEngine
+from myslice.settings import logger
# decorator to deflect calls on this Page to its prelude
def to_prelude (method):
# if cached, use it
if 'metadata' in manifold and isinstance(manifold['metadata'],MetaData):
- if debug: print "Page.get_metadata: return cached value"
+
+# cached_metadata = SessionCache().get_metadata(self.request)
+# if cached_metadata and isinstance(cached_metadata, MetaData):
+ logger.debug("Page.get_metadata: return cached value")
return manifold['metadata']
+# return cached_metadata
metadata_auth = {'AuthMethod':'anonymous'}
- metadata=MetaData (metadata_auth)
+ metadata = MetaData (metadata_auth)
metadata.fetch(self.request)
# store it for next time
manifold['metadata']=metadata
- if debug: print "Page.get_metadata: return new value"
+# SessionCache().store_metadata(self.request, metadata)
+ logger.debug("Page.get_metadata: return new value")
return metadata
def expose_js_metadata (self):
from unfold.page import Page
from unfold.prelude import Prelude
+from myslice.settings import logger
+
####################
# set DEBUG to
# . False : silent
# . [ 'SliceList', 'TabbedView' ] : to debug these classes
# . True : to debug all plugin
-DEBUG= False
-#DEBUG= [ 'SimpleList' ]
-#DEBUG=True
+DEBUG = False
+#DEBUG = [ 'SimpleList' ]
+#DEBUG = True
# decorator to deflect calls on Plugin to its Prelude through self.page.prelude
def to_prelude (method):
def actual (self, *args, **kwds):
if not self.page: # jordan
return None
- prelude_method=Prelude.__dict__[method.__name__]
- return prelude_method(self.page.prelude,*args, **kwds)
+ prelude_method = Prelude.__dict__[method.__name__]
+ return prelude_method(self.page.prelude, *args, **kwds)
return actual
class Plugin:
# using a simple incremental scheme to generate domids for now
# we just need this to be unique in a page
- domid=0
+ domid = 0
# when a domid is not set by the caller, we name plugins after their respective class as well,
# so as to limit name clashes between different views
# and maybe xxx we should just enforce that...
def newdomid(self):
Plugin.domid += 1
- return "plugin-%s-%d"%(self.__class__.__name__.lower(),Plugin.domid)
+ return "plugin-{}-{}".format(self.__class__.__name__.lower(), Plugin.domid)
##########
# Constructor
**settings):
self.page = page
# callers can provide their domid for css'ing
- if not domid: domid=self.newdomid()
- self.domid=domid
+ if not domid:
+ domid=self.newdomid()
+ self.domid = domid
# title is shown when togglable
#if not title: title="Plugin title for %s"%domid
- self.title=title
- self.classname=self._py_classname()
- self.plugin_classname=self._js_classname()
- self.visible=visible
- if togglable is None: self.togglable=self.default_togglable()
- else: self.togglable=togglable
- if toggled is None: self.toggled=self.default_toggled()
- else: self.toggled=toggled
- if outline_complete is None: self.outline_complete=self.default_outline_complete()
- else: self.outline_complete=outline_complete
- if outline_body is None: self.outline_body=self.default_outline_body()
- else: self.outline_body=outline_body
+ self.title = title
+ self.classname = self._py_classname()
+ self.plugin_classname = self._js_classname()
+ self.visible = visible
+ if togglable is None: self.togglable = self.default_togglable()
+ else: self.togglable = togglable
+ if toggled is None: self.toggled = self.default_toggled()
+ else: self.toggled = toggled
+ if outline_complete is None: self.outline_complete = self.default_outline_complete()
+ else: self.outline_complete = outline_complete
+ if outline_body is None: self.outline_body = self.default_outline_body()
+ else: self.outline_body = outline_body
# what comes from subclasses
for (k,v) in settings.iteritems():
- setattr(self,k,v)
- if self.need_debug(): print "%s init - subclass setting %s"%(self.classname,k)
+ setattr(self, k, v)
+ if self.need_debug():
+ logger.debug("{} init - subclass setting {}".format(self.classname, k))
# minimal debugging
if self.need_debug():
- print "%s init dbg .... BEG"%self.classname
- for (k,v) in self.__dict__.items(): print "dbg %s:%s"%(k,v)
- print "%s init dbg .... END"%self.classname
+ logger.debug("{} init dbg .... BEG".format(self.classname))
+ for (k, v) in self.__dict__.items():
+ logger.debug("dbg {}:{}".format(k, v))
+ logger.debug("{} init dbg .... END".format(self.classname))
# do this only once the structure is fine
if self.page: # I assume we can have a None page (Jordan)
self.page.record_plugin(self)
def setting_json (self, setting):
# TMP: js world expects plugin_uuid
- if setting=='plugin_uuid':
- value=self.domid
- elif setting=='query_uuid':
- try: value=self.query.query_uuid
- except: return '%s:"undefined"'%setting
+ if setting == 'plugin_uuid':
+ value = self.domid
+ elif setting == 'query_uuid':
+ try: value = self.query.query_uuid
+ except: return '{}:"undefined"'.format(setting)
else:
- value=getattr(self,setting,None)
- if value is None: value = "unknown-setting-%s"%setting
+ value = getattr(self,setting,None)
+ if value is None:
+ value = "unknown-setting-%s"%setting
# first try to use to_json method (json.dumps not working on class instances)
- try: value_json=value.to_json()
- except: value_json=json.dumps(value,separators=(',',':'))
- return "%s:%s"%(setting,value_json)
+ try: value_json = value.to_json()
+ except: value_json = json.dumps(value,separators=(',',':'))
+ return "{}:{}".format(setting, value_json)
# expose in json format to js the list of fields as described in json_settings_list()
# and add plugin_uuid: domid in the mix
def settings_json (self):
exposed_settings=self.json_settings_list()
if 'query' in exposed_settings:
- print "WARNING, cannot expose 'query' directly in json_settings_list, query_uuid is enough"
+ logger.debug("WARNING, cannot expose 'query' directly in json_settings_list, query_uuid is enough")
result = "{"
result += ",".join([ self.setting_json(setting) for setting in self.json_settings_list() ])
result += "}"
plugin_content = self.render_content (request)
# shove this into plugin.html
env = {}
- env ['plugin_content']= plugin_content
+ env['plugin_content'] = plugin_content
env.update(self.__dict__)
# translate high-level 'toggled' into 4 different booleans
self.need_toggle = False
- if self.toggled=='persistent':
+ if self.toggled == 'persistent':
# start with everything turned off and let the js callback do its job
- env.update({'persistent_toggle':True,'display_hide_button':False,
- 'display_show_button':False,'display_body':False})
- elif self.toggled==False:
- env.update({'persistent_toggle':False,'display_hide_button':False,
- 'display_show_button':True,'display_body':False})
+ env.update({'persistent_toggle' : True, 'display_hide_button' : False,
+ 'display_show_button' : False, 'display_body' : False})
+ elif self.toggled == False:
+ env.update({'persistent_toggle' : False, 'display_hide_button' : False,
+ 'display_show_button' : True, 'display_body' : False})
else:
- env.update({'persistent_toggle':False,'display_hide_button':True,
- 'display_show_button':False,'display_body':True})
+ env.update({'persistent_toggle' : False, 'display_hide_button' : True,
+ 'display_show_button' : False, 'display_body' : True})
if self.need_debug():
- print "rendering plugin.html with env keys %s"%env.keys()
+ logger.debug("rendering plugin.html with env keys {}".format(env.keys()))
for (k,v) in env.items():
- if "display" in k or "persistent" in k: print k,'->',v
+ if "display" in k or "persistent" in k:
+ logger.debug("{} -> {}".format(k, v))
result = render_to_string ('plugin.html',env)
# export this only for relevant plugins
"""Should return an HTML fragment"""
template = self.template_file()
# start with a fresh one
- env={}
+ env = {}
# add our own settings as defaults
env.update(self.__dict__)
# then the things explicitly defined in template_env()
env.update(self.template_env(request))
if not isinstance (env,dict):
raise Exception, "%s.template_env returns wrong type"%self.classname
- result=render_to_string (template, env)
+ result = render_to_string (template, env)
if self.need_debug():
- print "%s.render_content: BEG --------------------"%self.classname
- print "template=%s"%template
- print "env.keys=%s"%env.keys()
- #print "env=%s"%env
- #print result
- print "%s.render_content: END --------------------"%self.classname
+ logger.debug("{}.render_content: BEG --------------------".format(self.classname))
+ logger.debug("template={}".format(template))
+ logger.debug("env.keys={}".format(env.keys()))
+ logger.debug("{}.render_content: END --------------------".format(self.classname))
return result
# or from the result of self.requirements()
def handle_requirements (self, request):
try:
- d=self.requirements()
+ d = self.requirements()
for (k,v) in d.iteritems():
if self.need_debug():
- print "%s: handling requirement %s"%(self.classname,v)
+ logger.debug("{}: handling requirement {}".format(self.classname, v))
# e.g. js_files -> add_js_files
- method_name='add_'+k
- method=Page.__dict__[method_name]
- method(self.page,v)
+ method_name = 'add_' + k
+ method = Page.__dict__[method_name]
+ method(self.page, v)
except AttributeError:
# most likely the object does not have that method defined, which is fine
pass
except:
import traceback
- traceback.print_exc()
+ logger.log(traceback.format_exc())
pass
#################### requirements/prelude management
from django.template.loader import render_to_string
+from myslice.settings import logger
+
debug=False
# the need for js_init_chunks is because we need to have the plugins initialized
result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in Prelude.keys ] )
return result
def inspect (self,msg):
- print self.inspect_string(msg)
+ logger.debug(self.inspect_string(msg))
# first attempt was to use a simple dict like this
# env={}
env['all_js_chunks']= self.js_init_chunks + self.js_chunks
env['css_chunks']=self.css_chunks
if debug:
- print "prelude has %d js_files, %d css files, (%d+%d) js chunks and %d css_chunks"%\
- (len(self.js_files),len(self.css_files),len(self.js_init_chunks),len(self.js_chunks),len(self.css_chunks),)
+ logger.debug("prelude has {} js_files, {} css files, ({}+{}) js chunks and {} css_chunks"\
+ .format (len(self.js_files), len(self.css_files),
+ len(self.js_init_chunks), len(self.js_chunks), len(self.css_chunks),))
# render this with prelude.html and put the result in header_prelude
header_prelude = render_to_string ('prelude.html',env)
return { 'header_prelude' : header_prelude }
--- /dev/null
+import uuid
+
+from manifold.util.singleton import Singleton
+
+from myslice.settings import logger
+
+# the key attached to the session object, where we store
+# the uuid attached to that session in this cache
+cache_key = 'cached_uuid'
+
+class _SessionExtension(object):
+ """
+ This object holds all the data we need to attach to a django session object
+ """
+
+ def __init__(self):
+ self.metadata = None
+ self.auth = None
+
+ def __repr__(self):
+ result = "<SessionExtension"
+ if self.metadata: result += " .metadata"
+ if self.auth: result += " .auth"
+ result += ">"
+ return result
+
+class SessionCache(dict):
+ """
+ As of django1.7, the session object as attached to a django request
+ gets JSON-serialized instead of pickled
+ This breaks our previous or passing data from request to request across
+ a given session - in particular for metadata and auth/session keys
+ Not that the problem is more with metadata as this is a class instance
+ and JSON cannot handle that
+ So instead we decorate the session object with a UID and retrieve all the rest
+ from the present - singleton - cache instance
+ """
+
+ __metaclass__ = Singleton
+
+ def get_auth(self, request):
+ """
+ Get the auth previously attached to the request's session, or None
+ """
+ result = self._get(request, 'auth')
+ return result
+
+ def store_auth(self, request, auth):
+ """
+ Store the auth object attached to this request's session
+ create that extension if needed
+ """
+ return self._store(request, 'auth', auth)
+
+ def get_metadata(self, request):
+ """
+ retrieve metadata attached to this request's session, or None
+ """
+ return self._get(request, 'metadata')
+
+ def store_metadata(self, request, metadata):
+ """
+ Store the metadata object attached to this request's session
+ create that extension if needed
+ """
+ return self._store(request, 'metadata', metadata)
+
+ def _get(self, request, key):
+ "internal - retrieve key - do not create anything"
+ session = request.session
+ logger.debug("sessioncache._get_{} session={}".format(key, SessionCache._debug_session(session)))
+# self._debug(request)
+ if cache_key not in session:
+ return None
+ cached_uuid = session[cache_key]
+ if cached_uuid not in self:
+ return None
+ extension = self[cached_uuid]
+ return getattr(extension, key)
+
+ def _store(self, request, key, value):
+ "internal - set key, attach and create extension if needed"
+ session = request.session
+ if cache_key not in session:
+ session[cache_key] = uuid.uuid1().int
+ cached_uuid = session[cache_key]
+ if cached_uuid not in self:
+ self[cached_uuid] = _SessionExtension()
+ extension = self[cached_uuid]
+ setattr(extension, key, value)
+ logger.debug("sessioncache._store_{} session={}".format(key, SessionCache._debug_session(session)))
+# self._debug(request)
+
+ def end_session(self, request):
+ """
+ Clear all data related to this request's session has we are logging out
+ This is for garbage collection
+ """
+ session = request.session
+ logger.debug("SessionCache.end_session() {}".format(self._debug_session(session)))
+ if cache_key not in session:
+ return
+ cached_uuid = session[cache_key]
+ if cached_uuid in self:
+ del self[cached_uuid]
+
+ def _debug(self, request):
+ session = request.session
+ logger.debug("SessionCache: ---------- with session {}".format(self._debug_session(session)))
+ for k,v in self.iteritems():
+ logger.debug("SessionCache {} -> {}".format(k,v))
+ if cache_key not in session:
+ return
+ cached_uuid = session[cache_key]
+ if cached_uuid not in self:
+ return
+ extension = self[cached_uuid]
+ logger.debug("SessionCache: found extension {}".format(extension))
+ logger.debug("SessionCache: ----------")
+
+ @staticmethod
+ def _debug_session(session):
+ result = ""
+ result += "{} x {}".format(session, session.keys())
+ if cache_key in session:
+ result += " <{} = {}>".format(cache_key, session[cache_key])
+ return result
+from __future__ import print_function
+
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
"""
Tests that 1 + 1 always equals 2.
"""
- print 'test_basic is broken'
+ print('test_basic is broken')
return True
sl = SimpleList (visible=True)
- print 'rendering', sl.render()
+ print('rendering', sl.render())
self.assertEqual(1 + 1, 2)