from operator import attrgetter
from django import template
from django.views.decorators.csrf import csrf_exempt
-from django.http import HttpResponse, HttpResponseServerError
+from django.http import HttpResponse, HttpResponseServerError, HttpResponseForbidden
from django.core import urlresolvers
from django.contrib.gis.geoip import GeoIP
+from django.db.models import Q
from ipware.ip import get_ip
+from operator import itemgetter, attrgetter
import traceback
import socket
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
- userDetails = getUserSliceInfo(request.user)
- #context['site'] = userDetails['site']
-
- context['userSliceInfo'] = userDetails['userSliceInfo']
- context['cdnData'] = userDetails['cdnData']
- context['cdnContentProviders'] = userDetails['cdnContentProviders']
+ context = getDashboardContext(request.user, context)
return self.render_to_response(context=context)
-class DashboardView(TemplateView):
+class DashboardDynamicView(TemplateView):
head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
{% load admin_static %}
{% block content %}
tail_template = r"{% endblock %}"
- def get(self, request, name="hpc_historical", *args, **kwargs):
+ def get(self, request, name="root", *args, **kwargs):
context = self.get_context_data(**kwargs)
+ context = getDashboardContext(request.user, context)
+
+ if name=="root":
+ return self.multiDashboardView(request, context)
+ else:
+ return self.singleDashboardView(request, name, context)
+
+ def readDashboard(self, fn):
+ try:
+ template= open("/opt/planetstack/templates/admin/dashboard/%s.html" % fn, "r").read()
+ if (fn=="tenant"):
+ # fix for tenant view - it writes html to a div called tabs-5
+ template = '<div id="tabs-5"></div>' + template
+ return template
+ except:
+ return "failed to open %s" % fn
+
+ def multiDashboardView(self, request, context):
+ head_template = self.head_template
+ tail_template = self.tail_template
+
+ body = """
+ <div id="hometabs" >
+ <ul id="suit_form_tabs" class="nav nav-tabs nav-tabs-suit" data-tab-prefix="suit-tab">
+ """
+
+ dashboards = request.user.get_dashboards()
+
+ # customize is a special dashboard they always get
+ customize = DashboardView.objects.filter(name="Customize")
+ if customize:
+ dashboards.append(customize[0])
+
+ for i,view in enumerate(dashboards):
+ body = body + '<li><a href="#dashtab-%d">%s</a></li>\n' % (i, view.name)
+
+ body = body + "</ul>\n"
- t = template.Template(self.head_template + open("/opt/planetstack/templates/admin/dashboard/%s.html" % name, "r").read() + self.tail_template)
+ for i,view in enumerate(dashboards):
+ url = view.url
+ body = body + '<div id="dashtab-%d">\n' % i
+ if url.startswith("template:"):
+ fn = url[9:]
+ body = body + self.readDashboard(fn)
+ body = body + '</div>\n'
- userDetails = getUserSliceInfo(request.user)
- #context['site'] = userDetails['site']
+ body=body+"</div>\n"
- context['userSliceInfo'] = userDetails['userSliceInfo']
- context['cdnData'] = userDetails['cdnData']
- context['cdnContentProviders'] = userDetails['cdnContentProviders']
+ t = template.Template(head_template + body + self.tail_template)
response_kwargs = {}
response_kwargs.setdefault('content_type', self.content_type)
context = context,\r
**response_kwargs)
-def getUserSliceInfo(user, tableFormat = False):
- userDetails = {}
+ def singleDashboardView(self, request, name, context):
+ head_template = self.head_template
+ tail_template = self.tail_template
+
+ t = template.Template(head_template + self.readDashboard(name) + self.tail_template)
+
+ response_kwargs = {}
+ response_kwargs.setdefault('content_type', self.content_type)
+ return self.response_class(\r
+ request = request,\r
+ template = t,\r
+ context = context,\r
+ **response_kwargs)
+
+def getDashboardContext(user, context={}, tableFormat = False):
+ context = {}
userSliceData = getSliceInfo(user)
if (tableFormat):
-# pprint("******* GET USER SLICE INFO")
- userDetails['userSliceInfo'] = userSliceTableFormatter(userSliceData)
+ context['userSliceInfo'] = userSliceTableFormatter(userSliceData)
else:
- userDetails['userSliceInfo'] = userSliceData
- userDetails['cdnData'] = getCDNOperatorData(wait=False)
- userDetails['cdnContentProviders'] = getCDNContentProviderData()
- return userDetails
+ context['userSliceInfo'] = userSliceData
+ context['cdnData'] = getCDNOperatorData(wait=False)
+ context['cdnContentProviders'] = getCDNContentProviderData()
+
+ (dashboards, unusedDashboards)= getDashboards(user)
+ unusedDashboards=[x for x in unusedDashboards if x!="Customize"]
+ context['dashboards'] = dashboards
+ context['unusedDashboards'] = unusedDashboards
+
+ return context
+
+def getDashboards(user):
+ #dashboards = sorted(list(user.dashboardViews.all()), key=attrgetter('order'))
+ dashboards = user.get_dashboards()
+
+ dashboard_names = [d.name for d in dashboards]
+
+ unused_dashboard_names = []
+ for dashboardView in DashboardView.objects.all():
+ if not dashboardView.name in dashboard_names:
+ unused_dashboard_names.append(dashboardView.name)
+
+ return (dashboard_names, unused_dashboard_names)
class TenantCreateSlice(View):
def post(self, request, *args, **kwargs):
+ if request.user.isReadOnlyUser():
+ return HttpResponseForbidden("User is in read-only mode")
+
sliceName = request.POST.get("sliceName", "0")
serviceClass = request.POST.get("serviceClass", "0")
imageName = request.POST.get("imageName", "0")
actionToDo = request.POST.get("actionToDo", "0")
- #network = request.POST.get("network","0")
+ networkPorts = request.POST.get("network","0")
mountDataSets = request.POST.get("mountDataSets","0")
+ privateVolume = request.POST.get("privateVolume","0")
if (actionToDo == "add"):
serviceClass = ServiceClass.objects.get(name=serviceClass)
site = request.user.site
image = Image.objects.get(name=imageName)
newSlice = Slice(name=sliceName,serviceClass=serviceClass,site=site,imagePreference=image,mountDataSets=mountDataSets)
newSlice.save()
+ privateTemplate="Private"
+ publicTemplate="Public shared IPv4"\r
+ privateNetworkName = sliceName+"-"+privateTemplate\r
+ publicNetworkName = sliceName+"-"+publicTemplate\r
+ slice=Slice.objects.get(name=sliceName)\r
+ addNetwork(privateNetworkName,privateTemplate,slice)\r
+ addNetwork(publicNetworkName,publicTemplate,slice)\r
+ addOrModifyPorts(networkPorts,sliceName)\r
+ if privateVolume=="true":\r
+ privateVolForSlice(request.user,sliceName)
return HttpResponse("Slice created")
+def privateVolForSlice(user,sliceName):
+ if not hasPrivateVolume(sliceName):\r
+ volumeName=createPrivateVolume(user,sliceName)\r
+ readWrite="true"\r
+ mountVolume(sliceName,volumeName,readWrite)
+
class TenantUpdateSlice(View):
def post(self, request, *args, **kwargs):\r
+ if request.user.isReadOnlyUser():\r
+ return HttpResponseForbidden("User is in read-only mode")\r
+\r
sliceName = request.POST.get("sliceName", "0")\r
serviceClass = request.POST.get("serviceClass", "0")\r
imageName = request.POST.get("imageName", "0")\r
actionToDo = request.POST.get("actionToDo", "0")\r
- #network = request.POST.get("network","0")\r
+ networkPorts = request.POST.get("networkPorts","0")\r
dataSet = request.POST.get("dataSet","0")\r
+ privateVolume = request.POST.get("privateVolume","0")\r
slice = Slice.objects.all()\r
for entry in slice:\r
serviceClass = ServiceClass.objects.get(name=serviceClass)\r
if (actionToDo == "update"):\r
setattr(entry,'serviceClass',serviceClass)\r
setattr(entry,'imagePreference',imageName)\r
- #setattr(entry,'network',network)\r
setattr(entry,'mountDataSets',dataSet)\r
entry.save()\r
break\r
+ addOrModifyPorts(networkPorts,sliceName)\r
+ if privateVolume=="true":\r
+ privateVolForSlice(request.user,sliceName)\r
return HttpResponse("Slice updated")\r
\r
+def addNetwork(name,template,sliceName):\r
+ networkTemplate=NetworkTemplate.objects.get(name=template)\r
+ newNetwork = Network(name = name,\r
+ template = networkTemplate,\r
+ owner = sliceName)\r
+ newNetwork.save()\r
+ addNetworkSlice(newNetwork,sliceName)\r
+\r
+def addNetworkSlice(networkSlice,sliceName):\r
+ newNetworkSlice=NetworkSlice(network =networkSlice,\r
+ slice=sliceName)\r
+ newNetworkSlice.save()\r
+\r
+def addOrModifyPorts(networkPorts,sliceName):\r
+ networkList = Network.objects.all()\r
+ networkInfo = []\r
+ if networkPorts:\r
+ for networkEntry in networkList:\r
+ networkSlices = networkEntry.slices.all()\r
+ for slice in networkSlices:\r
+ if slice.name==sliceName:\r
+ if networkEntry.template.name=="Public shared IPv4":\r
+ setattr(networkEntry,'ports',networkPorts)\r
+ networkEntry.save()\r
+\r
def getTenantSliceInfo(user, tableFormat = False):
tenantSliceDetails = {}
tenantSliceData = getTenantInfo(user)
tenantSliceDetails['userSliceInfo'] = tenantSliceData
tenantSliceDetails['sliceServiceClass']=userSliceTableFormatter(tenantServiceClassData)
tenantSliceDetails['image']=userSliceTableFormatter(getImageInfo(user))
- #tenantSliceDetails['network']=userSliceTableFormatter(getNetworkInfo(user))
tenantSliceDetails['deploymentSites']=userSliceTableFormatter(getDeploymentSites())
tenantSliceDetails['sites'] = userSliceTableFormatter(getTenantSitesInfo())
tenantSliceDetails['mountDataSets'] = userSliceTableFormatter(getMountDataSets())
slice = Slice.objects.get(name=Slice.objects.get(id=entry.id).name)
sliceServiceClass = entry.serviceClass.name
preferredImage = entry.imagePreference
- sliceDataSet = entry.mountDataSets
- #sliceNetwork = entry.network
+ #sliceDataSet = entry.mountDataSets
+ sliceNetwork = {}
numSliver = 0
sliceImage=""
sliceSite = {}
sliceNode = {}
sliceInstance= {}
+ #createPrivateVolume(user,sliceName)
for sliver in slice.slivers.all():
if sliver.node.site.name in BLESSED_SITES:
sliceSite[sliver.node.site.name] = sliceSite.get(sliver.node.site.name,0) + 1
sliceNode[str(sliver)] = sliver.node.name
numSliver = sum(sliceSite.values())
numSites = len(sliceSite)
- userSliceInfo.append({'sliceName': sliceName,'sliceServiceClass': sliceServiceClass,'preferredImage':preferredImage,'numOfSites':numSites, 'sliceSite':sliceSite,'sliceImage':sliceImage,'numOfSlivers':numSliver,'sliceDataSet':sliceDataSet,'instanceNodePair':sliceNode})
+ userSliceInfo.append({'sliceName': sliceName,'sliceServiceClass': sliceServiceClass,'preferredImage':preferredImage,'numOfSites':numSites, 'sliceSite':sliceSite,'sliceImage':sliceImage,'numOfSlivers':numSliver,'instanceNodePair':sliceNode})
return userSliceInfo
def getTenantSitesInfo():
getattr(Volume.default_gateway_caps,"host files")
v = Volume(name="private_" + sliceName, owner_id=user, description="private volume for %s" % sliceName, blocksize=61440, private=True, archive=False, default_gateway_caps = caps)
v.save()
+ return v
SYNDICATE_REPLICATE_PORTNUM = 1025
inuse[vs.peer_portnum]=True
inuse[vs.replicate_portnum]=True
for network in Network.objects.all():
+ if not network.ports:
+ continue
network_ports = [x.strip() for x in network.ports.split(",")]
for network_port in network_ports:
try:
\r
return dataSetInfo
-def getNetworkInfo(user):
- #networkList = Network.objects.all()
- networkList = ['Private Only','Private and Publicly Routable']
- networkInfo = []
- for networkEntry in networkList:
- #networkInfo.append({'Network':networkEntry.name})
- networkInfo.append({'Network':networkEntry})
- return networkInfo
-
def getDeploymentSites():
deploymentList = Deployment.objects.all()
deploymentInfo = []
class DashboardUserSiteView(View):
def get(self, request, **kwargs):
- return HttpResponse(json.dumps(getUserSliceInfo(request.user, True)), mimetype='application/javascript')
+ return HttpResponse(json.dumps(getDashboardContext(request.user, tableFormat=True)), mimetype='application/javascript')
class TenantViewData(View):
def get(self, request, **kwargs):
class TenantDeleteSliceView(View):
def post(self,request):\r
+ if request.user.isReadOnlyUser():\r
+ return HttpResponseForbidden("User is in read-only mode")\r
sliceName = request.POST.get("sliceName",None)\r
slice = Slice.objects.get(name=sliceName)\r
#print slice, slice.id\r
siteList = [Site.objects.get(name=siteName)]
slice = Slice.objects.get(name="HyperCache")
+ if request.user.isReadOnlyUser():
+ return HttpResponseForbidden("User is in read-only mode")
+
if (actionToDo == "add"):
user_ip = request.GET.get("ip", get_ip(request))
slice_increase_slivers(request.user, user_ip, siteList, slice, 1)
print '*' * 50
print 'Ask for site: ' + siteName + ' to ' + actionToDo + ' another HPC Sliver'
- return HttpResponse('This is POST request ')
+ return HttpResponse(json.dumps("Success"), mimetype='application/javascript')
class DashboardAjaxView(View):
def get(self, request, **kwargs):
if (name == "hpcSummary"):
return HttpResponse(json.dumps(hpc_wizard.get_hpc_wizard().get_summary_for_view()), mimetype='application/javascript')
elif (name == "hpcUserSite"):
- return HttpResponse(json.dumps(getUserSliceInfo(request.user, True)), mimetype='application/javascript')
+ return HttpResponse(json.dumps(getDashboardContext(request.user, tableFormat=True)), mimetype='application/javascript')
elif (name == "hpcMap"):
return HttpResponse(json.dumps(getCDNOperatorData(True)), mimetype='application/javascript')
elif (name == "bigquery"):
else:
return HttpResponse(json.dumps("Unknown"), mimetype='application/javascript')
+class DashboardCustomize(View):
+ def post(self, request, *args, **kwargs):\r
+ if request.user.isReadOnlyUser():\r
+ return HttpResponseForbidden("User is in read-only mode")\r
+\r
+ dashboards = request.POST.get("dashboards", None)\r
+ if not dashboards:\r
+ dashboards=[]\r
+ else:\r
+ dashboards = [x.strip() for x in dashboards.split(",")]\r
+ dashboards = [DashboardView.objects.get(name=x) for x in dashboards]\r
+\r
+ request.user.dashboardViews.all().delete()\r
+\r
+ for i,dashboard in enumerate(dashboards):\r
+ udbv = UserDashboardView(user=request.user, dashboardView=dashboard, order=i)\r
+ udbv.save()\r
+\r
+ return HttpResponse(json.dumps("Success"), mimetype='application/javascript')\r
+
+class DashboardSliceInteractions(View):
+ def get(self, request, name="users", **kwargs):
+ colors = ["#005586", "#6ebe49", "orange", "#707170", "#00c4b3", "#077767", "dodgerblue", "#a79b94", "#c4e76a", "red"]
+
+ groups = []
+ matrix = []
+ slices = list(Slice.objects.all())
+
+ ids_by_slice = self.build_id_list(slices, name)
+
+ slices = [x for x in slices if (len(ids_by_slice[x])>0)]
+
+ for i,slice in enumerate(slices):
+ groups.append({"name": slice.name, "color": colors[i%len(colors)]})
+ row=self.buildMatrix(slice, slices, name, ids_by_slice)
+ matrix.append(row)
+
+ result = {"groups": groups, "matrix": matrix}
+
+ if name=="users":
+ result["title"] = "Slice interactions by user privilege"
+ result["objectName"] = "users"
+ elif name=="networks":
+ result["title"] = "Slice interactions by network membership"
+ result["objectName"] = "networks"
+ elif name=="sites":
+ result["title"] = "Slice interactions by site ownership"
+ result["objectName"] = "sites"
+ elif name=="sliver_sites":
+ result["title"] = "Slice interactions by sliver sites"
+ result["objectName"] = "sites"
+ elif name=="sliver_nodes":
+ result["title"] = "Slice interactions by sliver nodes"
+ result["objectName"] = "nodes"
+
+ return HttpResponse(json.dumps(result), mimetype='application/javascript')
+
+ def build_id_list(self, slices, name):
+ ids_by_slice = {}
+ for slice in slices:
+ # build up a list of object ids that are used by each slice
+ ids_by_slice[slice] = self.getIds(slice, name)
+
+ return ids_by_slice
+
+ def buildMatrix(self, slice, slices, name, ids_by_slice):
+ not_only_my_ids = []
+
+ # build up a list of object ids that are used by other slices
+ for otherSlice in ids_by_slice.keys():
+ if (slice != otherSlice):
+ for id in ids_by_slice[otherSlice]:
+ if not id in not_only_my_ids:
+ not_only_my_ids.append(id)
+
+ # build up a list of ids that are used only by the slice, and not
+ # shared with any other slice
+ only_my_ids = []
+ for id in ids_by_slice[slice]:
+ if id not in not_only_my_ids:
+ only_my_ids.append(id)
+
+ row = []
+ for otherSlice in ids_by_slice.keys():
+ if (otherSlice == slice):
+ row.append(len(only_my_ids))
+ else:
+ row.append(self.inCommonIds(ids_by_slice[slice], ids_by_slice[otherSlice]))
+
+ return row
+
+ def getIds(self, slice, name):
+ ids=[]
+ if name=="users":
+ for sp in slice.slice_privileges.all():
+ if sp.user.id not in ids:
+ ids.append(sp.user.id)
+ elif name=="networks":
+ for sp in slice.networkslice_set.all():
+ if sp.network.id not in ids:
+ ids.append(sp.network.id)
+ elif name=="sites":
+ ids = [slice.site.id]
+ elif name=="sliver_sites":
+ for sp in slice.slivers.all():
+ if sp.node.site.id not in ids:
+ ids.append(sp.node.site.id)
+ elif name=="sliver_nodes":
+ for sp in slice.slivers.all():
+ if sp.node.id not in ids:
+ ids.append(sp.node.id)
+ return ids
+
+ def inCommonIds(self, ids1, ids2):
+ count = 0
+ for id in ids1:
+ if id in ids2:
+ count+=1
+ return count
+
+ def isEmpty(self, slice, name):
+ if (name in ["users", "networks", "sites", "sliver_nodes", "sliver_sites"]):
+ return (len(self.getIds(slice,name)) == 0)
+