From 6b6542030c5d836acb773dc86d0de00797549929 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Tue, 27 May 2014 16:55:00 -0700 Subject: [PATCH] slice_interactions dynamic update --- planetstack/core/plus/sites.py | 7 +- planetstack/core/plus/views.py | 120 +++++++++++- .../admin/dashboard/slice_interactions.html | 185 +++++++++--------- 3 files changed, 215 insertions(+), 97 deletions(-) diff --git a/planetstack/core/plus/sites.py b/planetstack/core/plus/sites.py index 66c5d00..5d670d0 100644 --- a/planetstack/core/plus/sites.py +++ b/planetstack/core/plus/sites.py @@ -12,7 +12,10 @@ class AdminMixin(object): def get_urls(self): """Add our dashboard view to the admin urlconf. Deleted the default index.""" from django.conf.urls import patterns, url - from views import DashboardCustomize, DashboardDynamicView, DashboardWelcomeView, DashboardAjaxView, SimulatorView, DashboardSummaryAjaxView, DashboardAddOrRemoveSliverView, DashboardUserSiteView, DashboardAnalyticsAjaxView, TenantViewData,TenantCreateSlice, TenantAddOrRemoveSliverView, TenantPickSitesView, TenantDeleteSliceView,TenantUpdateSlice + from views import DashboardCustomize, DashboardDynamicView, DashboardWelcomeView, DashboardAjaxView, SimulatorView, \ + DashboardSummaryAjaxView, DashboardAddOrRemoveSliverView, DashboardUserSiteView, DashboardAnalyticsAjaxView, \ + TenantViewData,TenantCreateSlice, TenantAddOrRemoveSliverView, TenantPickSitesView, TenantDeleteSliceView, \ + TenantUpdateSlice, DashboardSliceInteractions urls = super(AdminMixin, self).get_urls() del urls[0] @@ -21,6 +24,8 @@ class AdminMixin(object): name="index"), url(r'^test/', self.admin_view(DashboardUserSiteView.as_view()), name="test"), + url(r'^sliceinteractions/(?P\w+)/$', self.admin_view(DashboardSliceInteractions.as_view()), + name="interactions"), url(r'^dashboard/(?P\w+)/$', self.admin_view(DashboardDynamicView.as_view()), name="dashboard"), url(r'^customize/$', self.admin_view(DashboardCustomize.as_view()), diff --git a/planetstack/core/plus/views.py b/planetstack/core/plus/views.py index f57f587..886db20 100644 --- a/planetstack/core/plus/views.py +++ b/planetstack/core/plus/views.py @@ -16,6 +16,7 @@ from django.views.decorators.csrf import csrf_exempt 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 @@ -61,10 +62,6 @@ class DashboardDynamicView(TemplateView): if (fn=="tenant"): # fix for tenant view - it writes html to a div called tabs-5 template = '
' + template - if (fn=="slice_interactions"): - # fix for slice_interactions - it gives its container div a 40px - # margin, and then positions it's header at -40px - template = '
' + template + '
' return template except: return "failed to open %s" % fn @@ -114,7 +111,7 @@ class DashboardDynamicView(TemplateView): head_template = self.head_template tail_template = self.tail_template - t = template.Template(head_template + self.readDashboard(fn) + self.tail_template) + t = template.Template(head_template + self.readDashboard(name) + self.tail_template) response_kwargs = {} response_kwargs.setdefault('content_type', self.content_type) @@ -341,7 +338,7 @@ def get_free_port(): inuse[vs.peer_portnum]=True inuse[vs.replicate_portnum]=True for network in Network.objects.all(): - if not network_ports: + if not network.ports: continue network_ports = [x.strip() for x in network.ports.split(",")] for network_port in network_ports: @@ -797,3 +794,114 @@ class DashboardCustomize(View): return HttpResponse(json.dumps("Success"), mimetype='application/javascript') +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()) + + slices = [x for x in slices if not self.isEmpty(x,name)] + + for i,slice in enumerate(slices): + groups.append({"name": slice.name, "color": colors[i%len(colors)]}) + matrix.append(self.buildMatrix(slice, slices, name)) + + 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 buildMatrix(self, slice, slices, name): + row = [] + for otherSlice in slices: + if (otherSlice == slice): + row.append(self.getCount(slice, name)) + else: + row.append(self.getInCommon(slice, otherSlice, name)) + return row + + def other_slice_sites(self, slice): + ids=[] + for sliver in Sliver.objects.all(): + if sliver.slice!=slice: + if sliver.node.site.id not in ids: + ids.append(sliver.node.site.id) + return ids + + def other_slice_nodes(self, slice): + ids=[] + for sliver in Sliver.objects.all(): + if sliver.slice!=slice: + if sliver.node.id not in ids: + ids.append(sliver.node.id) + return ids + + def getIds(self, slice, name, onlySelf=False): + ids=[] + if name=="users": + for sp in slice.slice_privileges.all(): + if (not onlySelf) or (len(sp.user.slice_privileges.all())==1): + if sp.user.id not in ids: + ids.append(sp.user.id) + elif name=="networks": + for sp in slice.networkslice_set.all(): + if (not onlySelf) or (len(sp.network.networkslice_set.all())==1): + 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) + if onlySelf: + other_slice_sites = self.other_slice_sites(slice) + ids = [x for x in ids if x not in other_slice_sites] + elif name=="sliver_nodes": + for sp in slice.slivers.all(): + if sp.node.id not in ids: + ids.append(sp.node.id) + if onlySelf: + other_slice_nodes = self.other_slice_nodes(slice) + ids = [x for x in ids if x not in other_slice_nodes] + + return ids + + def inCommonIds(self, ids1, ids2): + count = 0 + for id in ids1: + if id in ids2: + count+=1 + return count + + def getCount(self, slice, name): + if (name in ["users", "networks", "sites", "sliver_nodes", "sliver_sites"]): + return len(self.getIds(slice,name,onlySelf=True)) + + def getInCommon(self, slice, otherSlice, name): + if (name in ["users", "networks", "sites", "sliver_nodes", "sliver_sites"]): + slice_ids = self.getIds(slice,name) + otherSlice_ids = self.getIds(otherSlice,name) + return self.inCommonIds(slice_ids, otherSlice_ids) + + def isEmpty(self, slice, name): + if (name in ["users", "networks", "sites", "sliver_nodes", "sliver_sites"]): + return (len(self.getIds(slice,name)) == 0) + diff --git a/planetstack/templates/admin/dashboard/slice_interactions.html b/planetstack/templates/admin/dashboard/slice_interactions.html index e52bdd7..6fafc5c 100644 --- a/planetstack/templates/admin/dashboard/slice_interactions.html +++ b/planetstack/templates/admin/dashboard/slice_interactions.html @@ -2,7 +2,6 @@ -

Involvement between Slices by User Engagement

+ +
+
+ +
+
+

Slice Interactions

+
+
+