summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/pharos-dashboard/.gitignore1
-rw-r--r--tools/pharos-dashboard/account/jira_util.py2
-rw-r--r--tools/pharos-dashboard/account/urls.py3
-rw-r--r--tools/pharos-dashboard/account/views.py15
-rw-r--r--tools/pharos-dashboard/booking/models.py15
-rw-r--r--tools/pharos-dashboard/booking/urls.py1
-rw-r--r--tools/pharos-dashboard/booking/views.py12
-rw-r--r--tools/pharos-dashboard/dashboard/models.py38
-rw-r--r--tools/pharos-dashboard/dashboard/templatetags/jira_filters.py2
-rw-r--r--tools/pharos-dashboard/dashboard/urls.py5
-rw-r--r--tools/pharos-dashboard/dashboard/views.py61
-rw-r--r--tools/pharos-dashboard/pharos_dashboard/urls.py9
-rw-r--r--tools/pharos-dashboard/static/bower.json2
-rw-r--r--tools/pharos-dashboard/static/js/flot-pie-chart.js22
-rw-r--r--tools/pharos-dashboard/templates/account/user_list.html42
-rw-r--r--tools/pharos-dashboard/templates/base.html5
-rw-r--r--tools/pharos-dashboard/templates/dashboard/ci_pods.html2
-rw-r--r--tools/pharos-dashboard/templates/dashboard/dev_pods.html16
-rw-r--r--tools/pharos-dashboard/templates/dashboard/resource.html18
-rw-r--r--tools/pharos-dashboard/templates/dashboard/resource_all.html17
-rw-r--r--tools/pharos-dashboard/templates/dashboard/resource_detail.html158
-rw-r--r--tools/pharos-dashboard/templates/dashboard/server_table.html2
-rw-r--r--tools/pharos-dashboard/templates/layout.html4
23 files changed, 387 insertions, 65 deletions
diff --git a/tools/pharos-dashboard/.gitignore b/tools/pharos-dashboard/.gitignore
index 9eb1cfde..2b73909a 100644
--- a/tools/pharos-dashboard/.gitignore
+++ b/tools/pharos-dashboard/.gitignore
@@ -20,6 +20,7 @@ coverage.xml
*.log
*.pot
migrations/
+settings.py
# KDE:
.directory
diff --git a/tools/pharos-dashboard/account/jira_util.py b/tools/pharos-dashboard/account/jira_util.py
index bd07ff3b..c066a686 100644
--- a/tools/pharos-dashboard/account/jira_util.py
+++ b/tools/pharos-dashboard/account/jira_util.py
@@ -5,7 +5,7 @@ import oauth2 as oauth
from jira import JIRA
from tlslite.utils import keyfactory
-from pharos_dashboard import settings
+from django.conf import settings
class SignatureMethod_RSA_SHA1(oauth.SignatureMethod):
diff --git a/tools/pharos-dashboard/account/urls.py b/tools/pharos-dashboard/account/urls.py
index b837814a..7289da69 100644
--- a/tools/pharos-dashboard/account/urls.py
+++ b/tools/pharos-dashboard/account/urls.py
@@ -21,5 +21,6 @@ urlpatterns = [
url(r'^settings/', AccountSettingsView.as_view(), name='settings'),
url(r'^authenticated/$', JiraAuthenticatedView.as_view(), name='authenticated'),
url(r'^login/$', JiraLoginView.as_view(), name='login'),
- url(r'^logout/$', JiraLogoutView.as_view(), name='logout')
+ url(r'^logout/$', JiraLogoutView.as_view(), name='logout'),
+ url(r'^users/$', UserListView.as_view(), name='users'),
]
diff --git a/tools/pharos-dashboard/account/views.py b/tools/pharos-dashboard/account/views.py
index 7d2c9bd0..fd1762e5 100644
--- a/tools/pharos-dashboard/account/views.py
+++ b/tools/pharos-dashboard/account/views.py
@@ -10,13 +10,14 @@ from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.generic import RedirectView
+from django.views.generic import TemplateView
from django.views.generic import UpdateView
from jira import JIRA
from account.forms import AccountSettingsForm
from account.jira_util import SignatureMethod_RSA_SHA1
from account.models import UserProfile
-from pharos_dashboard import settings
+from django.conf import settings
consumer = oauth.Consumer(settings.OAUTH_CONSUMER_KEY, settings.OAUTH_CONSUMER_SECRET)
@@ -50,7 +51,8 @@ class JiraLoginView(RedirectView):
self.request.session['request_token'] = dict(urllib.parse.parse_qsl(content.decode()))
# Step 3. Redirect the user to the authentication URL.
url = settings.OAUTH_AUTHORIZE_URL + '?oauth_token=' + \
- self.request.session['request_token']['oauth_token']
+ self.request.session['request_token']['oauth_token'] + \
+ '&oauth_callback=' + settings.OAUTH_CALLBACK_URL
return url
@@ -109,3 +111,12 @@ class JiraAuthenticatedView(RedirectView):
login(self.request, user)
# redirect user to settings page to complete profile
return url
+
+class UserListView(TemplateView):
+ template_name = "account/user_list.html"
+
+ def get_context_data(self, **kwargs):
+ users = User.objects.all()
+ context = super(UserListView, self).get_context_data(**kwargs)
+ context.update({'title': "Dashboard Users", 'users': users})
+ return context
diff --git a/tools/pharos-dashboard/booking/models.py b/tools/pharos-dashboard/booking/models.py
index 4be8ccab..e772fb5b 100644
--- a/tools/pharos-dashboard/booking/models.py
+++ b/tools/pharos-dashboard/booking/models.py
@@ -1,10 +1,10 @@
from django.contrib.auth.models import User
from django.db import models
from jira import JIRA
+from jira import JIRAError
from dashboard.models import Resource
-from pharos_dashboard import settings
-
+from django.conf import settings
class Booking(models.Model):
id = models.AutoField(primary_key=True)
@@ -13,6 +13,7 @@ class Booking(models.Model):
start = models.DateTimeField()
end = models.DateTimeField()
jira_issue_id = models.IntegerField(null=True)
+ jira_issue_status = models.CharField(max_length=50)
purpose = models.CharField(max_length=300, blank=False)
@@ -20,9 +21,13 @@ class Booking(models.Model):
db_table = 'booking'
def get_jira_issue(self):
- jira = JIRA(server=settings.JIRA_URL, basic_auth=(settings.JIRA_USER_NAME, settings.JIRA_USER_PASSWORD))
- issue = jira.issue(self.jira_issue_id)
- return issue
+ try:
+ jira = JIRA(server=settings.JIRA_URL,
+ basic_auth=(settings.JIRA_USER_NAME, settings.JIRA_USER_PASSWORD))
+ issue = jira.issue(self.jira_issue_id)
+ return issue
+ except JIRAError:
+ return None
def authorization_test(self):
"""
diff --git a/tools/pharos-dashboard/booking/urls.py b/tools/pharos-dashboard/booking/urls.py
index f6429daa..bdcd52d4 100644
--- a/tools/pharos-dashboard/booking/urls.py
+++ b/tools/pharos-dashboard/booking/urls.py
@@ -21,6 +21,7 @@ urlpatterns = [
url(r'^(?P<resource_id>[0-9]+)/$', BookingFormView.as_view(), name='create'),
url(r'^(?P<resource_id>[0-9]+)/bookings_json/$', ResourceBookingsJSON.as_view(),
name='bookings_json'),
+
url(r'^detail/$', BookingView.as_view(), name='detail_prefix'),
url(r'^detail/(?P<booking_id>[0-9]+)/$', BookingView.as_view(), name='detail'),
]
diff --git a/tools/pharos-dashboard/booking/views.py b/tools/pharos-dashboard/booking/views.py
index fde8d816..d0b2aefe 100644
--- a/tools/pharos-dashboard/booking/views.py
+++ b/tools/pharos-dashboard/booking/views.py
@@ -1,9 +1,13 @@
+from datetime import timedelta
+
+from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
from django.urls import reverse
+from django.utils import timezone
from django.views import View
from django.views.generic import FormView
from django.views.generic import TemplateView
@@ -67,7 +71,8 @@ class BookingFormView(LoginRequiredMixin, FormView):
messages.add_message(self.request, messages.ERROR, err)
return super(BookingFormView, self).form_invalid(form)
try:
- create_jira_ticket(user, booking)
+ if settings.CREATE_JIRA_TICKET:
+ create_jira_ticket(user, booking)
except JIRAError:
messages.add_message(self.request, messages.ERROR, 'Failed to create Jira Ticket. '
'Please check your Jira '
@@ -93,5 +98,6 @@ class BookingView(TemplateView):
class ResourceBookingsJSON(View):
def get(self, request, *args, **kwargs):
resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
- bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose')
- return JsonResponse({'bookings': list(bookings)})
+ bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose',
+ 'jira_issue_status')
+ return JsonResponse({'bookings': list(bookings)}) \ No newline at end of file
diff --git a/tools/pharos-dashboard/dashboard/models.py b/tools/pharos-dashboard/dashboard/models.py
index d645cd55..734da386 100644
--- a/tools/pharos-dashboard/dashboard/models.py
+++ b/tools/pharos-dashboard/dashboard/models.py
@@ -1,3 +1,6 @@
+from datetime import timedelta
+
+from django.utils import timezone
from django.contrib.auth.models import User
from django.db import models
@@ -9,9 +12,42 @@ class Resource(models.Model):
name = models.CharField(max_length=100, unique=True)
description = models.CharField(max_length=300, blank=True, null=True)
url = models.CharField(max_length=100, blank=True, null=True)
- owner = models.ForeignKey(User)
+ owner = models.ForeignKey(User, related_name='user_lab_owner', null=True)
+ vpn_users = models.ManyToManyField(User, related_name='user_vpn_users')
slave = models.ForeignKey(JenkinsSlave, on_delete=models.DO_NOTHING, null=True)
+ def get_booking_utilization(self, weeks):
+ """
+ Return a dictionary containing the count of booked and free seconds for a resource in the
+ range [now,now + weeks] if weeks is positive,
+ or [now-weeks, now] if weeks is negative
+ """
+
+ length = timedelta(weeks=abs(weeks))
+ now = timezone.now()
+
+ start = now
+ end = now + length
+ if weeks < 0:
+ start = now - length
+ end = now
+
+ bookings = self.booking_set.filter(start__lt=start + length, end__gt=start)
+
+ booked_seconds = 0
+ for booking in bookings:
+ booking_start = booking.start
+ booking_end = booking.end
+ if booking_start < start:
+ booking_start = start
+ if booking_end > end:
+ booking_end = start + length
+ total = booking_end - booking_start
+ booked_seconds += total.total_seconds()
+
+ return {'booked_seconds': booked_seconds,
+ 'available_seconds': length.total_seconds() - booked_seconds}
+
class Meta:
db_table = 'resource'
diff --git a/tools/pharos-dashboard/dashboard/templatetags/jira_filters.py b/tools/pharos-dashboard/dashboard/templatetags/jira_filters.py
index d9c27612..1be0600b 100644
--- a/tools/pharos-dashboard/dashboard/templatetags/jira_filters.py
+++ b/tools/pharos-dashboard/dashboard/templatetags/jira_filters.py
@@ -1,6 +1,6 @@
from django.template.defaultfilters import register
-from pharos_dashboard import settings
+from django.conf import settings
@register.filter
diff --git a/tools/pharos-dashboard/dashboard/urls.py b/tools/pharos-dashboard/dashboard/urls.py
index 809204c1..baa2d633 100644
--- a/tools/pharos-dashboard/dashboard/urls.py
+++ b/tools/pharos-dashboard/dashboard/urls.py
@@ -23,6 +23,9 @@ urlpatterns = [
url(r'^jenkins_slaves/$', JenkinsSlavesView.as_view(), name='jenkins_slaves'),
url(r'^resource/all/$', LabOwnerView.as_view(), name='resources'),
url(r'^resource/(?P<resource_id>[0-9]+)/$', ResourceView.as_view(), name='resource'),
-
+ url(r'^resource/(?P<resource_id>[0-9]+)/booking_utilization/(?P<weeks>-?\d+)/$',
+ BookingUtilizationJSON.as_view(), name='booking_utilization'),
+ url(r'^resource/(?P<resource_id>[0-9]+)/jenkins_utilization/(?P<weeks>-?\d+)/$',
+ JenkinsUtilizationJSON.as_view(), name='jenkins_utilization'),
url(r'^$', DevelopmentPodsView.as_view(), name="index"),
]
diff --git a/tools/pharos-dashboard/dashboard/views.py b/tools/pharos-dashboard/dashboard/views.py
index ef1845c8..0eddc130 100644
--- a/tools/pharos-dashboard/dashboard/views.py
+++ b/tools/pharos-dashboard/dashboard/views.py
@@ -1,7 +1,9 @@
from datetime import timedelta
+from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.utils import timezone
+from django.views import View
from django.views.generic import TemplateView
from booking.models import Booking
@@ -40,10 +42,18 @@ class DevelopmentPodsView(TemplateView):
dev_pods = []
for resource in resources:
- dev_pod = (resource, None)
+ booking_utilization = resource.get_booking_utilization(weeks=4)
+ total = booking_utilization['booked_seconds'] + booking_utilization['available_seconds']
+ try:
+ utilization_percentage = "%d%%" % (float(booking_utilization['booked_seconds']) /
+ total * 100)
+ except (ValueError, ZeroDivisionError):
+ return ""
+
+ dev_pod = (resource, None, utilization_percentage)
for booking in bookings:
if booking.resource == resource:
- dev_pod = (resource, booking)
+ dev_pod = (resource, booking, utilization_percentage)
dev_pods.append(dev_pod)
context = super(DevelopmentPodsView, self).get_context_data(**kwargs)
@@ -59,7 +69,8 @@ class ResourceView(TemplateView):
utilization = resource.slave.get_utilization(timedelta(days=7))
bookings = Booking.objects.filter(resource=resource, end__gt=timezone.now())
context = super(ResourceView, self).get_context_data(**kwargs)
- context.update({'title': str(resource), 'resource': resource, 'utilization': utilization, 'bookings': bookings})
+ context.update({'title': str(resource), 'resource': resource, 'utilization': utilization,
+ 'bookings': bookings})
return context
@@ -76,3 +87,47 @@ class LabOwnerView(TemplateView):
context = super(LabOwnerView, self).get_context_data(**kwargs)
context.update({'title': "Overview", 'pods': pods})
return context
+
+
+class BookingUtilizationJSON(View):
+ def get(self, request, *args, **kwargs):
+ resource = get_object_or_404(Resource, id=kwargs['resource_id'])
+ utilization = resource.get_booking_utilization(int(kwargs['weeks']))
+ utilization = [
+ {
+ 'label': 'Booked',
+ 'data': utilization['booked_seconds'],
+ 'color': '#d9534f'
+ },
+ {
+ 'label': 'Available',
+ 'data': utilization['available_seconds'],
+ 'color': '#5cb85c'
+ },
+ ]
+ return JsonResponse({'data': utilization})
+
+
+class JenkinsUtilizationJSON(View):
+ def get(self, request, *args, **kwargs):
+ resource = get_object_or_404(Resource, id=kwargs['resource_id'])
+ weeks = int(kwargs['weeks'])
+ utilization = resource.slave.get_utilization(timedelta(weeks=weeks))
+ utilization = [
+ {
+ 'label': 'Offline',
+ 'data': utilization['offline'],
+ 'color': '#d9534f'
+ },
+ {
+ 'label': 'Online',
+ 'data': utilization['online'],
+ 'color': '#5cb85c'
+ },
+ {
+ 'label': 'Idle',
+ 'data': utilization['idle'],
+ 'color': '#5bc0de'
+ },
+ ]
+ return JsonResponse({'data': utilization})
diff --git a/tools/pharos-dashboard/pharos_dashboard/urls.py b/tools/pharos-dashboard/pharos_dashboard/urls.py
index 26ab3677..d8bf5608 100644
--- a/tools/pharos-dashboard/pharos_dashboard/urls.py
+++ b/tools/pharos-dashboard/pharos_dashboard/urls.py
@@ -13,13 +13,18 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
+from django.conf import settings
from django.conf.urls import url, include
+from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
url(r'^', include('dashboard.urls', namespace='dashboard')),
url(r'^booking/', include('booking.urls', namespace='booking')),
- url(r'^account/', include('account.urls', namespace='account')),
+ url(r'^accounts/', include('account.urls', namespace='account')),
url(r'^admin/', admin.site.urls),
-] \ No newline at end of file
+]
+
+if settings.DEBUG is True:
+ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file
diff --git a/tools/pharos-dashboard/static/bower.json b/tools/pharos-dashboard/static/bower.json
index 78406217..f473747f 100644
--- a/tools/pharos-dashboard/static/bower.json
+++ b/tools/pharos-dashboard/static/bower.json
@@ -19,6 +19,6 @@
"eonasdan-bootstrap-datetimepicker": "^4.17.37",
"fullcalendar": "^2.9.0",
"jquery-migrate": "^3.0.0",
- "startbootstrap-sb-admin-2": "^1.0.9"
+ "startbootstrap-sb-admin-2-blackrockdigital": "^3.3.7"
}
}
diff --git a/tools/pharos-dashboard/static/js/flot-pie-chart.js b/tools/pharos-dashboard/static/js/flot-pie-chart.js
new file mode 100644
index 00000000..98d174e4
--- /dev/null
+++ b/tools/pharos-dashboard/static/js/flot-pie-chart.js
@@ -0,0 +1,22 @@
+function loadChartData(chart_id, url) {
+ $.ajax({
+ url: url,
+ type: 'get',
+ success: function (data) {
+ var data = data['data'];
+ $(function () {
+ var plotObj = $.plot($("#" + chart_id), data, {
+ series: {
+ pie: {
+ show: true
+ }
+ }
+ });
+ });
+ },
+ failure: function (data) {
+ alert('Error loading data');
+ }
+ });
+
+} \ No newline at end of file
diff --git a/tools/pharos-dashboard/templates/account/user_list.html b/tools/pharos-dashboard/templates/account/user_list.html
new file mode 100644
index 00000000..7618dc95
--- /dev/null
+++ b/tools/pharos-dashboard/templates/account/user_list.html
@@ -0,0 +1,42 @@
+{% extends "dashboard/table.html" %}
+{% load staticfiles %}
+
+{% block table %}
+ <thead>
+ <tr>
+ <th>Username</th>
+ <th>Company</th>
+ <th>SSH Key</th>
+ <th>GPG Key</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for user in users %}
+ <tr>
+ <th>
+ {{ user.username }}
+ </th>
+ <th>
+ {{ user.userprofile.company }}
+ </th>
+ <th>
+ <a href={{ user.userprofile.ssh_public_key.url }}>Download</a>
+ </th>
+ <th>
+ <a href={{ user.userprofile.pgp_public_key.url }}>Download</a>
+ </th>
+ </tr>
+ {% endfor %}
+ </tbody>
+{% endblock table %}
+
+
+{% block tablejs %}
+ <script type="text/javascript">
+ $(document).ready(function () {
+ $('#table').DataTable({
+ "order": [[0, "asc"]]
+ });
+ });
+ </script>
+{% endblock tablejs %} \ No newline at end of file
diff --git a/tools/pharos-dashboard/templates/base.html b/tools/pharos-dashboard/templates/base.html
index 64174a1f..42156e3b 100644
--- a/tools/pharos-dashboard/templates/base.html
+++ b/tools/pharos-dashboard/templates/base.html
@@ -71,6 +71,11 @@
class="fa fa-fw"></i>Resources
</a>
</li>
+ <li>
+ <a href="{% url 'account:users' %}"><i
+ class="fa fa-fw"></i>Users
+ </a>
+ </li>
</ul>
</div>
<!-- /.sidebar-collapse -->
diff --git a/tools/pharos-dashboard/templates/dashboard/ci_pods.html b/tools/pharos-dashboard/templates/dashboard/ci_pods.html
index 2982a6ff..a754252c 100644
--- a/tools/pharos-dashboard/templates/dashboard/ci_pods.html
+++ b/tools/pharos-dashboard/templates/dashboard/ci_pods.html
@@ -41,7 +41,7 @@
href={{ pod.slave.last_job_url }}>{{ pod.slave.last_job_name }}</a>
</th>
</tr>
- {% endfor %}`
+ {% endfor %}
</tbody>
{% endblock table %}
diff --git a/tools/pharos-dashboard/templates/dashboard/dev_pods.html b/tools/pharos-dashboard/templates/dashboard/dev_pods.html
index 9c84bb91..c4cb1ba7 100644
--- a/tools/pharos-dashboard/templates/dashboard/dev_pods.html
+++ b/tools/pharos-dashboard/templates/dashboard/dev_pods.html
@@ -10,12 +10,14 @@
<th>Booked by</th>
<th>Booked until</th>
<th>Purpose</th>
+ <th>Utilization</th>
<th>Status</th>
<th></th>
+ <th></th>
</tr>
</thead>
<tbody>
- {% for pod, booking in dev_pods %}
+ {% for pod, booking, utilization in dev_pods %}
<tr>
<th>
<a href={% url 'dashboard:resource' resource_id=pod.id %}>{{ pod.name }}</a>
@@ -32,6 +34,9 @@
<th>
{{ booking.purpose }}
</th>
+ <th>
+ {{ utilization }}
+ </th>
<th style="background-color:{{ pod.slave.status | jenkins_status_color }}">
{{ pod.slave.status }}
</th>
@@ -40,6 +45,11 @@
Book
</a>
</th>
+ <th>
+ <a href="{% url 'dashboard:resource' resource_id=pod.id %}" class="btn btn-primary">
+ Info
+ </a>
+ </th>
</tr>
{% endfor %}
</tbody>
@@ -50,9 +60,9 @@
$(document).ready(function () {
$('#table').DataTable({
columnDefs: [
- {type: 'status', targets: 5}
+ {type: 'status', targets: 6}
],
- "order": [[5, "asc"]]
+ "order": [[6, "asc"]]
});
});
</script>
diff --git a/tools/pharos-dashboard/templates/dashboard/resource.html b/tools/pharos-dashboard/templates/dashboard/resource.html
index 92d02f66..c9e57354 100644
--- a/tools/pharos-dashboard/templates/dashboard/resource.html
+++ b/tools/pharos-dashboard/templates/dashboard/resource.html
@@ -38,21 +38,21 @@
<script src="{% static "bower_components/flot/jquery.flot.time.js" %}"></script>
<script src="{% static "bower_components/flot.tooltip/js/jquery.flot.tooltip.min.js" %}"></script>
+ <script src="{% static "js/flot-pie-chart.js" %}"></script>
+
<script type="text/javascript">
$(document).ready(function () {
$('#{{ resource.id }}_server_table').DataTable({});
$('#{{ resource.id }}_bookings_table').DataTable({});
+ $('#{{ resource.id }}_vpn_user_table').DataTable({});
- $(function () {
- var plotObj = $.plot($("#{{ resource.id }}_slave_utilization"), data_{{ resource.id }}, {
- series: {
- pie: {
- show: true
- }
- }
- });
+ var chart_id = "{{ resource.id }}_booking_utilization";
+ var utilization_url = "{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=4 %}";
+ loadChartData(chart_id, utilization_url);
- });
+ var chart_id = "{{ resource.id }}_jenkins_utilization";
+ var utilization_url = "{% url 'dashboard:jenkins_utilization' resource_id=resource.id weeks=1 %}";
+ loadChartData(chart_id, utilization_url);
});
</script>
{% endblock extrajs %} \ No newline at end of file
diff --git a/tools/pharos-dashboard/templates/dashboard/resource_all.html b/tools/pharos-dashboard/templates/dashboard/resource_all.html
index 2078475f..a770d4e8 100644
--- a/tools/pharos-dashboard/templates/dashboard/resource_all.html
+++ b/tools/pharos-dashboard/templates/dashboard/resource_all.html
@@ -50,6 +50,7 @@
<script src="{% static "bower_components/flot/jquery.flot.resize.js" %}"></script>
<script src="{% static "bower_components/flot/jquery.flot.time.js" %}"></script>
<script src="{% static "bower_components/flot.tooltip/js/jquery.flot.tooltip.min.js" %}"></script>
+ <script src="{% static "js/flot-pie-chart.js" %}"></script><
<script type="text/javascript">
$(document).ready(function () {
@@ -57,17 +58,15 @@
$('#{{ resource.id }}_server_table').DataTable({});
$('#{{ resource.id }}_bookings_table').DataTable({});
+ $('#{{ resource.id }}_vpn_user_table').DataTable({});
- $(function () {
- var plotObj = $.plot($("#{{ resource.id }}_slave_utilization"), data_{{ resource.id }}, {
- series: {
- pie: {
- show: true
- }
- }
- });
+ var chart_id = "{{ resource.id }}_booking_utilization";
+ var utilization_url = "{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=4 %}";
+ loadChartData(chart_id, utilization_url);
- });
+ var chart_id = "{{ resource.id }}_jenkins_utilization";
+ var utilization_url = "{% url 'dashboard:jenkins_utilization' resource_id=resource.id weeks=1 %}";
+ loadChartData(chart_id, utilization_url);
{% endfor %}
});
</script>
diff --git a/tools/pharos-dashboard/templates/dashboard/resource_detail.html b/tools/pharos-dashboard/templates/dashboard/resource_detail.html
index 4fba4766..6067e1ea 100644
--- a/tools/pharos-dashboard/templates/dashboard/resource_detail.html
+++ b/tools/pharos-dashboard/templates/dashboard/resource_detail.html
@@ -1,12 +1,27 @@
+{% load jenkins_filters %}
+
<div class="row">
<div class="col-lg-3">
<div class="panel panel-default">
<div class="panel-heading">
- Utilization
+ Jenkins Utilization
+ <div class="pull-right">
+ <div class="form-group">
+ <select onchange="loadChartData('{{ resource.id }}_jenkins_utilization', this.value);">
+ <option value="{% url 'dashboard:jenkins_utilization' resource_id=resource.id weeks=1 %}">
+ Last Week
+ </option>
+ <option value="{% url 'dashboard:jenkins_utilization' resource_id=resource.id weeks=4 %}">
+ Last Month
+ </option>
+ </select>
+ </div>
+ </div>
</div>
<div class="panel-body">
<div class="flot-chart">
- <div class="flot-chart-content" id="{{ resource.id }}_slave_utilization"></div>
+ <div class="flot-chart-content"
+ id="{{ resource.id }}_jenkins_utilization"></div>
</div>
</div>
</div>
@@ -29,7 +44,39 @@
</div>
</div>
<div class="row">
- <div class="col-lg-6">
+ <div class="col-lg-3">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ Booking Utilization
+ <div class="pull-right">
+ <div class="form-group">
+ <select onchange="loadChartData('{{ resource.id }}_booking_utilization', this.value);">
+ <option value="{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=-4 %}">
+ Last Month
+ </option>
+ <option value="{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=-1 %}">
+ Last Week
+ </option>
+ <option value="{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=1 %}">
+ Next Week
+ </option>
+ <option selected="selected"
+ value="{% url 'dashboard:booking_utilization' resource_id=resource.id weeks=4 %}">
+ Next Month
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="panel-body">
+ <div class="flot-chart">
+ <div class="flot-chart-content"
+ id="{{ resource.id }}_booking_utilization"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-heading">
Bookings
@@ -46,19 +93,92 @@
</div>
</div>
</div>
-
-<script type="text/javascript">
- var data_{{ resource.id }} = [{
- label: "Offline",
- data: {{ utilization.offline }},
- color: '#d9534f'
- }, {
- label: "Online",
- data: {{ utilization.online }},
- color: '#5cb85c'
- }, {
- label: "Idle",
- data: {{ utilization.idle }},
- color: '#5bc0de'
- }];
-</script> \ No newline at end of file
+<div class="row">
+ <div class="col-lg-3">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ Contact
+ </div>
+ <div class="panel-body">
+ <p>
+ <b>Lab Owner: </b>
+ {{ resource.owner.username }}
+ </p>
+ <p>
+ <b>Email: </b>
+ </p>
+ <p>
+ <a href="{% url 'booking:create' resource_id=resource.id %}" class="btn
+ btn-primary">
+ Booking
+ </a>
+ <a href="{{ resource.url }}" class="btn
+ btn-primary">
+ OPNFV Wiki
+ </a>
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-3">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ Jenkins Status
+ </div>
+ <div class="panel-body">
+ <p>
+ <b>Slave Name: </b>
+ <a target='_blank'
+ href={{ resource.slave.url }}>{{ resource.slave.name }}</a>
+ </p>
+ <p>
+ <b>Status: </b>
+ {{ resource.slave.status }}
+ </p>
+ <p>
+ <b>Last Job: </b>
+ <a href="{{ resource.slave.last_job_url }}">
+ {{ resource.slave.last_job_name }}
+ </a>
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ VPN Users
+ </div>
+ <div class="panel-body">
+ <div class="dataTables_wrapper">
+ <table class="table table-striped table-bordered table-hover"
+ id="{{ resource.id }}_vpn_user_table" cellspacing="0"
+ width="100%">
+ <thead>
+ <tr>
+ <th>User</th>
+ <th>Email</th>
+ <th>Company</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for user in resource.vpn_users.all %}
+ <tr>
+ <th>
+ {{ user.username }}
+ </th>
+ <th>
+ {{ user.email }}
+ </th>
+ <th>
+ {{ user.userprofile.company }}
+ </th>
+ </tr>
+ {% endfor %}
+ </table>
+ </tbody>
+ </div>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/tools/pharos-dashboard/templates/dashboard/server_table.html b/tools/pharos-dashboard/templates/dashboard/server_table.html
index d47e5204..fee7e8b1 100644
--- a/tools/pharos-dashboard/templates/dashboard/server_table.html
+++ b/tools/pharos-dashboard/templates/dashboard/server_table.html
@@ -26,5 +26,5 @@
{{ server.storage }}
</th>
</tr>
-{% endfor %}`
+{% endfor %}
</tbody> \ No newline at end of file
diff --git a/tools/pharos-dashboard/templates/layout.html b/tools/pharos-dashboard/templates/layout.html
index db9490f5..64fed4ae 100644
--- a/tools/pharos-dashboard/templates/layout.html
+++ b/tools/pharos-dashboard/templates/layout.html
@@ -20,7 +20,7 @@
<link href="{% static "bower_components/metisMenu/dist/metisMenu.min.css" %}" rel="stylesheet">
<!-- Custom CSS -->
- <link href="{% static "bower_components/startbootstrap-sb-admin-2/dist/css/sb-admin-2.css" %}"
+ <link href="{% static "bower_components/startbootstrap-sb-admin-2-blackrockdigital/dist/css/sb-admin-2.css" %}"
rel="stylesheet">
<link href="{% static "css/theme.css" %}" rel="stylesheet">
@@ -65,7 +65,7 @@
<script src="{% static "bower_components/metisMenu/dist/metisMenu.min.js" %}"></script>
<!-- Custom Theme JavaScript -->
-<script src="{% static "bower_components/startbootstrap-sb-admin-2/dist/js/sb-admin-2.js" %}"></script>
+<script src="{% static "bower_components/startbootstrap-sb-admin-2-blackrockdigital/dist/js/sb-admin-2.js" %}"></script>
{% block extrajs %}
{% endblock extrajs %}