Add info to the resource view 85/20885/1
authormaxbr <maxbr@mi.fu-berlin.de>
Mon, 12 Sep 2016 09:18:10 +0000 (11:18 +0200)
committermaxbr <maxbr@mi.fu-berlin.de>
Mon, 12 Sep 2016 09:18:10 +0000 (11:18 +0200)
JIRA: PHAROS-266

This adds a panel containing lab owner contact information, jenkins
utilization timerange options and a table containing vpn users of a pod
to the resource view.

Change-Id: If991c74d3c93cd08f622771acc048ab998e16c48
Signed-off-by: maxbr <maxbr@mi.fu-berlin.de>
tools/pharos-dashboard/booking/models.py
tools/pharos-dashboard/booking/urls.py
tools/pharos-dashboard/booking/views.py
tools/pharos-dashboard/dashboard/views.py
tools/pharos-dashboard/templates/dashboard/resource_detail.html

index 4be8cca..e772fb5 100644 (file)
@@ -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):
         """
index f6429da..bdcd52d 100644 (file)
@@ -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'),
 ]
index fde8d81..d0b2aef 100644 (file)
@@ -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
index c34a7a5..0eddc13 100644 (file)
@@ -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
@@ -104,3 +106,28 @@ class BookingUtilizationJSON(View):
             },
         ]
         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})
index 904fecd..6067e1e 100644 (file)
@@ -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>
         </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