summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgan <jack.morgan@intel.com>2016-09-21 15:48:38 +0000
committerGerrit Code Review <gerrit@172.30.200.206>2016-09-21 15:48:38 +0000
commitdcc6fa43043c685b7443cbc27da12ad9bf2225c4 (patch)
tree7927874aa51afd638e69f46d773e1c0b09d40f6b
parent47f2f0a3224b8c990d5b9ab6c9628f9d7cf231b8 (diff)
parent3c8baae57206988fbdfc2d858ddc3f134e552f07 (diff)
Merge changes from topic 'pharos-dashboard'
* changes: Add a REST API for the dashboard Send notifications for booking start and end
-rw-r--r--tools/pharos-dashboard/api/__init__.py0
-rw-r--r--tools/pharos-dashboard/api/serializers.py22
-rw-r--r--tools/pharos-dashboard/api/urls.py28
-rw-r--r--tools/pharos-dashboard/api/views.py23
-rw-r--r--tools/pharos-dashboard/booking/models.py1
-rw-r--r--tools/pharos-dashboard/dashboard/tasks.py13
-rw-r--r--tools/pharos-dashboard/dashboard/urls.py1
-rw-r--r--tools/pharos-dashboard/notification/__init__.py1
-rw-r--r--tools/pharos-dashboard/notification/admin.py7
-rw-r--r--tools/pharos-dashboard/notification/apps.py8
-rw-r--r--tools/pharos-dashboard/notification/models.py22
-rw-r--r--tools/pharos-dashboard/notification/signals.py15
-rw-r--r--tools/pharos-dashboard/notification/tasks.py23
-rw-r--r--tools/pharos-dashboard/pharos_dashboard/urls.py4
-rw-r--r--tools/pharos-dashboard/templates/base.html5
-rw-r--r--tools/pharos-dashboard/templates/rest_framework/api.html9
16 files changed, 181 insertions, 1 deletions
diff --git a/tools/pharos-dashboard/api/__init__.py b/tools/pharos-dashboard/api/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tools/pharos-dashboard/api/__init__.py
diff --git a/tools/pharos-dashboard/api/serializers.py b/tools/pharos-dashboard/api/serializers.py
new file mode 100644
index 00000000..c3875cca
--- /dev/null
+++ b/tools/pharos-dashboard/api/serializers.py
@@ -0,0 +1,22 @@
+from rest_framework import serializers
+
+from booking.models import Booking
+from dashboard.models import Server, Resource
+
+
+class BookingSerializer(serializers.HyperlinkedModelSerializer):
+ class Meta:
+ model = Booking
+ fields = ('id', 'resource', 'start', 'end', 'purpose')
+
+
+class ServerSerializer(serializers.HyperlinkedModelSerializer):
+ class Meta:
+ model = Server
+ fields = ('id', 'resource', 'name', 'model', 'cpu', 'ram', 'storage')
+
+
+class ResourceSerializer(serializers.HyperlinkedModelSerializer):
+ class Meta:
+ model = Resource
+ fields = ('id', 'name', 'description', 'url', 'server_set')
diff --git a/tools/pharos-dashboard/api/urls.py b/tools/pharos-dashboard/api/urls.py
new file mode 100644
index 00000000..22f12eb6
--- /dev/null
+++ b/tools/pharos-dashboard/api/urls.py
@@ -0,0 +1,28 @@
+"""pharos_dashboard URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/1.10/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
+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.urls import url, include
+from rest_framework import routers
+
+from api.views import *
+
+router = routers.DefaultRouter()
+router.register(r'resources', ResourceViewSet)
+router.register(r'servers', ServerViewSet)
+router.register(r'bookings', BookingViewSet)
+
+urlpatterns = [
+ url(r'^', include(router.urls)),
+] \ No newline at end of file
diff --git a/tools/pharos-dashboard/api/views.py b/tools/pharos-dashboard/api/views.py
new file mode 100644
index 00000000..78d7b8a9
--- /dev/null
+++ b/tools/pharos-dashboard/api/views.py
@@ -0,0 +1,23 @@
+from rest_framework import viewsets
+
+from api.serializers import ResourceSerializer, ServerSerializer, BookingSerializer
+from booking.models import Booking
+from dashboard.models import Resource, Server
+
+
+class BookingViewSet(viewsets.ModelViewSet):
+ queryset = Booking.objects.all()
+ serializer_class = BookingSerializer
+ filter_fields = ('resource', 'user')
+
+
+class ServerViewSet(viewsets.ModelViewSet):
+ queryset = Server.objects.all()
+ serializer_class = ServerSerializer
+ filter_fields = ('resource', 'name')
+
+
+class ResourceViewSet(viewsets.ModelViewSet):
+ queryset = Resource.objects.all()
+ serializer_class = ResourceSerializer
+ filter_fields = ('name',) \ No newline at end of file
diff --git a/tools/pharos-dashboard/booking/models.py b/tools/pharos-dashboard/booking/models.py
index e772fb5b..fed35e3f 100644
--- a/tools/pharos-dashboard/booking/models.py
+++ b/tools/pharos-dashboard/booking/models.py
@@ -6,6 +6,7 @@ from jira import JIRAError
from dashboard.models import Resource
from django.conf import settings
+
class Booking(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, models.CASCADE) # delete if user is deleted
diff --git a/tools/pharos-dashboard/dashboard/tasks.py b/tools/pharos-dashboard/dashboard/tasks.py
new file mode 100644
index 00000000..3df4bfba
--- /dev/null
+++ b/tools/pharos-dashboard/dashboard/tasks.py
@@ -0,0 +1,13 @@
+from celery import shared_task
+from datetime import timedelta
+from django.utils import timezone
+
+from jenkins.models import JenkinsStatistic
+from notification.models import BookingNotification
+
+
+@shared_task
+def database_cleanup():
+ now = timezone.now()
+ JenkinsStatistic.objects.filter(timestamp__lt=now - timedelta(weeks=4)).delete()
+ BookingNotification.objects.filter(submit_time__lt=now - timedelta(weeks=4)).delete() \ No newline at end of file
diff --git a/tools/pharos-dashboard/dashboard/urls.py b/tools/pharos-dashboard/dashboard/urls.py
index baa2d633..35c64636 100644
--- a/tools/pharos-dashboard/dashboard/urls.py
+++ b/tools/pharos-dashboard/dashboard/urls.py
@@ -14,7 +14,6 @@ Including another URLconf
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
-
from dashboard.views import *
urlpatterns = [
diff --git a/tools/pharos-dashboard/notification/__init__.py b/tools/pharos-dashboard/notification/__init__.py
new file mode 100644
index 00000000..926c6e80
--- /dev/null
+++ b/tools/pharos-dashboard/notification/__init__.py
@@ -0,0 +1 @@
+default_app_config = 'notification.apps.NotificationConfig' \ No newline at end of file
diff --git a/tools/pharos-dashboard/notification/admin.py b/tools/pharos-dashboard/notification/admin.py
new file mode 100644
index 00000000..1fb5921f
--- /dev/null
+++ b/tools/pharos-dashboard/notification/admin.py
@@ -0,0 +1,7 @@
+from django.conf import settings
+from django.contrib import admin
+
+from notification.models import BookingNotification
+
+if settings.DEBUG:
+ admin.site.register(BookingNotification) \ No newline at end of file
diff --git a/tools/pharos-dashboard/notification/apps.py b/tools/pharos-dashboard/notification/apps.py
new file mode 100644
index 00000000..6039c7bd
--- /dev/null
+++ b/tools/pharos-dashboard/notification/apps.py
@@ -0,0 +1,8 @@
+from django.apps import AppConfig
+
+
+class NotificationConfig(AppConfig):
+ name = 'notification'
+
+ def ready(self):
+ import notification.signals #noqa \ No newline at end of file
diff --git a/tools/pharos-dashboard/notification/models.py b/tools/pharos-dashboard/notification/models.py
new file mode 100644
index 00000000..80f65df4
--- /dev/null
+++ b/tools/pharos-dashboard/notification/models.py
@@ -0,0 +1,22 @@
+from django.db import models
+
+class BookingNotification(models.Model):
+ id = models.AutoField(primary_key=True)
+ type = models.CharField(max_length=100)
+ booking = models.ForeignKey('booking.Booking', on_delete=models.CASCADE)
+ submit_time = models.DateTimeField()
+ submitted = models.BooleanField(default=False)
+
+ def get_content(self):
+ return {
+ 'start': self.booking.start.isoformat(),
+ 'end': self.booking.end.isoformat(),
+ 'user': self.booking.user.username,
+ 'purpose': self.booking.purpose
+ }
+
+ def save(self, *args, **kwargs):
+ notifications = self.booking.bookingnotification_set.filter(type=self.type)
+ if notifications.count() > 1:
+ raise ValueError('Doubled Notification')
+ return super(BookingNotification, self).save(*args, **kwargs) \ No newline at end of file
diff --git a/tools/pharos-dashboard/notification/signals.py b/tools/pharos-dashboard/notification/signals.py
new file mode 100644
index 00000000..c1f33ac0
--- /dev/null
+++ b/tools/pharos-dashboard/notification/signals.py
@@ -0,0 +1,15 @@
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+
+from booking.models import Booking
+from notification.models import BookingNotification
+
+
+@receiver(post_save, sender=Booking)
+def booking_notification_handler(sender, instance, **kwargs):
+ BookingNotification.objects.update_or_create(
+ booking=instance, type='booking_start', defaults={'submit_time': instance.start}
+ )
+ BookingNotification.objects.update_or_create(
+ booking=instance, type='booking_end', defaults={'submit_time': instance.end}
+ ) \ No newline at end of file
diff --git a/tools/pharos-dashboard/notification/tasks.py b/tools/pharos-dashboard/notification/tasks.py
new file mode 100644
index 00000000..ab3bddc7
--- /dev/null
+++ b/tools/pharos-dashboard/notification/tasks.py
@@ -0,0 +1,23 @@
+from celery import shared_task
+from datetime import timedelta
+
+from django.conf import settings
+from django.utils import timezone
+
+from notification.models import BookingNotification
+from notification_framework.notification import Notification
+
+
+@shared_task
+def send_booking_notifications():
+ messaging = Notification(dashboard_url=settings.RABBITMQ_URL)
+
+ now = timezone.now()
+ notifications = BookingNotification.objects.filter(submitted=False,
+ submit_time__gt=now,
+ submit_time__lt=now + timedelta(minutes=5))
+ for notification in notifications:
+ messaging.send(notification.type, notification.booking.resource.name,
+ notification.get_content())
+ notification.submitted = True
+ notification.save()
diff --git a/tools/pharos-dashboard/pharos_dashboard/urls.py b/tools/pharos-dashboard/pharos_dashboard/urls.py
index d8bf5608..4a9d9149 100644
--- a/tools/pharos-dashboard/pharos_dashboard/urls.py
+++ b/tools/pharos-dashboard/pharos_dashboard/urls.py
@@ -18,12 +18,16 @@ 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'^accounts/', include('account.urls', namespace='account')),
url(r'^admin/', admin.site.urls),
+ url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
+
+ url(r'^api/', include('api.urls'))
]
if settings.DEBUG is True:
diff --git a/tools/pharos-dashboard/templates/base.html b/tools/pharos-dashboard/templates/base.html
index 42156e3b..c5da483d 100644
--- a/tools/pharos-dashboard/templates/base.html
+++ b/tools/pharos-dashboard/templates/base.html
@@ -76,6 +76,11 @@
class="fa fa-fw"></i>Users
</a>
</li>
+ <li>
+ <a href="{% url 'api-root' %}"><i
+ class="fa fa-fw"></i>API
+ </a>
+ </li>
</ul>
</div>
<!-- /.sidebar-collapse -->
diff --git a/tools/pharos-dashboard/templates/rest_framework/api.html b/tools/pharos-dashboard/templates/rest_framework/api.html
new file mode 100644
index 00000000..9c6c4f7d
--- /dev/null
+++ b/tools/pharos-dashboard/templates/rest_framework/api.html
@@ -0,0 +1,9 @@
+{% extends "rest_framework/base.html" %}
+
+{% block title %}Pharos Dashboard API{% endblock %}
+
+{% block branding %}
+ <a class='navbar-brand' rel="nofollow" href=#>
+ Pharos Dashboard API
+ </a>
+{% endblock %} \ No newline at end of file