blob: a4713e562736440dd76e76eaeb75487d7a9f4abc [file] [log] [blame]
Scott Bakerc7325a42014-05-30 16:06:46 -07001from view_common import *
Scott Baker09066122015-02-02 16:12:47 -08002from planetstack_analytics import DoPlanetStackAnalytics, PlanetStackAnalytics, RED_LOAD, BLUE_LOAD
3
4def getCDNContentProviderData():
5 cps = []
6 for dm_cp in ContentProvider.objects.all():
7 cp = {"name": dm_cp.name,
8 "account": dm_cp.account}
9 cps.append(cp)
10
11 return cps
12
13def getCDNOperatorData(randomizeData = False, wait=True):
14 HPC_SLICE_NAME = "HyperCache"
15
16 bq = PlanetStackAnalytics()
17
18 rows = bq.get_cached_query_results(bq.compose_cached_query(), wait)
19
20 # wait=False on the first time the Dashboard is opened. This means we might
21 # not have any rows yet. The dashboard code polls every 30 seconds, so it
22 # will eventually pick them up.
23
24 if rows:
25 rows = bq.postprocess_results(rows, filter={"event": "hpc_heartbeat"}, maxi=["cpu"], count=["hostname"], computed=["bytes_sent/elapsed"], groupBy=["Time","site"], maxDeltaTime=80)
26
27 # dictionaryize the statistics rows by site name
28 stats_rows = {}
29 for row in rows:
30 stats_rows[row["site"]] = row
31 else:
32 stats_rows = {}
33
34 slice = Slice.objects.filter(name=HPC_SLICE_NAME)
35 if slice:
36 slice_slivers = list(slice[0].slivers.all())
37 else:
38 slice_slivers = []
39
40 new_rows = {}
41 for site in Site.objects.all():
42 # compute number of slivers allocated in the data model
43 allocated_slivers = 0
44 for sliver in slice_slivers:
45 if sliver.node.site == site:
46 allocated_slivers = allocated_slivers + 1
47
48 stats_row = stats_rows.get(site.name,{})
49
50 max_cpu = stats_row.get("max_avg_cpu", stats_row.get("max_cpu",0))
51 cpu=float(max_cpu)/100.0
52 hotness = max(0.0, ((cpu*RED_LOAD) - BLUE_LOAD)/(RED_LOAD-BLUE_LOAD))
53
54 try:
55 lat=float(site.location.latitude)
56 long=float(site.location.longitude)
57 except:
58 lat=0
59 long=0
60
61 # format it to what that CDN Operations View is expecting
62 new_row = {"lat": lat,
63 "long": long,
64 "health": 0,
65 #"numNodes": int(site.nodes.count()),
66 "activeHPCSlivers": int(stats_row.get("count_hostname", 0)), # measured number of slivers, from bigquery statistics
67 "numHPCSlivers": allocated_slivers, # allocated number of slivers, from data model
68 "siteUrl": str(site.site_url),
69 "bandwidth": stats_row.get("sum_computed_bytes_sent_div_elapsed",0),
70 "load": max_cpu,
71 "hot": float(hotness)}
72 new_rows[str(site.name)] = new_row
73
74 # get rid of sites with 0 slivers that overlap other sites with >0 slivers
75 for (k,v) in new_rows.items():
76 bad=False
77 if v["numHPCSlivers"]==0:
78 for v2 in new_rows.values():
79 if (v!=v2) and (v2["numHPCSlivers"]>=0):
80 d = haversine(v["lat"],v["long"],v2["lat"],v2["long"])
81 if d<100:
82 bad=True
83 if bad:
84 del new_rows[k]
85
86 return new_rows
Scott Bakerc7325a42014-05-30 16:06:46 -070087
88class DashboardSummaryAjaxView(View):
89 def get(self, request, **kwargs):
90 def avg(x):
91 if len(x)==0:
92 return 0
93 return float(sum(x))/len(x)
94
95 sites = getCDNOperatorData().values()
96
97 sites = [site for site in sites if site["numHPCSlivers"]>0]
98
99 total_slivers = sum( [site["numHPCSlivers"] for site in sites] )
100 total_bandwidth = sum( [site["bandwidth"] for site in sites] )
101 average_cpu = int(avg( [site["load"] for site in sites] ))
102
103 result= {"total_slivers": total_slivers,
104 "total_bandwidth": total_bandwidth,
105 "average_cpu": average_cpu}
106
Scott Baker823b7212014-06-16 10:25:39 -0700107 return HttpResponse(json.dumps(result), content_type='application/javascript')
Scott Bakerc7325a42014-05-30 16:06:46 -0700108
109class DashboardAddOrRemoveSliverView(View):
110 # TODO: deprecate this view in favor of using TenantAddOrRemoveSliverView
111
112 def post(self, request, *args, **kwargs):
113 siteName = request.POST.get("site", None)
114 actionToDo = request.POST.get("actionToDo", "0")
115
116 siteList = [Site.objects.get(name=siteName)]
117 slice = Slice.objects.get(name="HyperCache")
118
119 if request.user.isReadOnlyUser():
120 return HttpResponseForbidden("User is in read-only mode")
121
122 if (actionToDo == "add"):
123 user_ip = request.GET.get("ip", get_ip(request))
Scott Baker866c5b32014-08-29 11:34:00 -0700124 slice_increase_slivers(request.user, user_ip, siteList, slice, image.objects.all()[0], 1)
Scott Bakerc7325a42014-05-30 16:06:46 -0700125 elif (actionToDo == "rem"):
126 slice_decrease_slivers(request.user, siteList, slice, 1)
127
128 print '*' * 50
129 print 'Ask for site: ' + siteName + ' to ' + actionToDo + ' another HPC Sliver'
Scott Baker823b7212014-06-16 10:25:39 -0700130 return HttpResponse(json.dumps("Success"), content_type='application/javascript')
Scott Bakerc7325a42014-05-30 16:06:46 -0700131
132class DashboardAjaxView(View):
133 def get(self, request, **kwargs):
Scott Baker823b7212014-06-16 10:25:39 -0700134 return HttpResponse(json.dumps(getCDNOperatorData(True)), content_type='application/javascript')