Commit 1f7f49bb by Kálmán Viktor

Merge branch 'issue-420' into 'master'

Graph for templates

Display graph in template edit page, which shows how many instances are running

See merge request !350
parents 31ac3bc2 f5c4fc6b
...@@ -166,6 +166,28 @@ ...@@ -166,6 +166,28 @@
</ul> </ul>
</div> </div>
</div> </div>
{% if show_graph %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin"><i class="fa fa-area-chart"></i> {% trans "Graphs" %}</h3>
</div>
<div class="text-center panel-body">
<div class="graph-buttons">
{% include "dashboard/_graph-time-buttons.html" %}
</div>
<div class="text-center graph-images">
<img src="{% url "dashboard.views.template-graph" object.pk "instances" graph_time %}"/>
</div>
{% if request.user.is_superuser %}
<a href="{% url "dashboard.views.vm-list" %}?s=template:{{object.pk}}&stype=all">
{% trans "List all template instances" %}
</a>
{% endif %}
</div>
</div>
{% endif %}
</div><!-- .col-md-4 --> </div><!-- .col-md-4 -->
</div><!-- .row --> </div><!-- .row -->
......
...@@ -47,7 +47,7 @@ from .views import ( ...@@ -47,7 +47,7 @@ from .views import (
LeaseAclUpdateView, LeaseAclUpdateView,
toggle_template_tutorial, toggle_template_tutorial,
ClientCheck, TokenLogin, ClientCheck, TokenLogin,
VmGraphView, NodeGraphView, NodeListGraphView, VmGraphView, NodeGraphView, NodeListGraphView, TemplateGraphView,
TransferInstanceOwnershipView, TransferInstanceOwnershipConfirmView, TransferInstanceOwnershipView, TransferInstanceOwnershipConfirmView,
TransferTemplateOwnershipView, TransferTemplateOwnershipConfirmView, TransferTemplateOwnershipView, TransferTemplateOwnershipConfirmView,
OpenSearchDescriptionView, OpenSearchDescriptionView,
...@@ -152,6 +152,10 @@ urlpatterns = patterns( ...@@ -152,6 +152,10 @@ urlpatterns = patterns(
r'(?P<time>[0-9]{1,2}[hdwy])$'), r'(?P<time>[0-9]{1,2}[hdwy])$'),
NodeListGraphView.as_view(), NodeListGraphView.as_view(),
name='dashboard.views.node-list-graph'), name='dashboard.views.node-list-graph'),
url((r'^template/(?P<pk>\d+)/graph/(?P<metric>[a-z]+)/'
r'(?P<time>[0-9]{1,2}[hdwy])$'),
TemplateGraphView.as_view(),
name='dashboard.views.template-graph'),
url(r'^group/(?P<pk>\d+)/$', GroupDetailView.as_view(), url(r'^group/(?P<pk>\d+)/$', GroupDetailView.as_view(),
name='dashboard.views.group-detail'), name='dashboard.views.group-detail'),
url(r'^group/(?P<pk>\d+)/update/$', GroupProfileUpdate.as_view(), url(r'^group/(?P<pk>\d+)/update/$', GroupProfileUpdate.as_view(),
......
...@@ -28,7 +28,7 @@ from django.views.generic import View ...@@ -28,7 +28,7 @@ from django.views.generic import View
from braces.views import LoginRequiredMixin from braces.views import LoginRequiredMixin
from vm.models import Instance, Node from vm.models import Instance, Node, InstanceTemplate
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -152,6 +152,28 @@ class NodeGraphView(GraphViewBase): ...@@ -152,6 +152,28 @@ class NodeGraphView(GraphViewBase):
return self.model.objects.get(id=pk) return self.model.objects.get(id=pk)
class TemplateGraphView(GraphViewBase):
model = InstanceTemplate
base = Metric
def get_object(self, request, pk):
instance = super(TemplateGraphView, self).get_object(request, pk)
if not instance.has_level(request.user, 'operator'):
raise PermissionDenied()
return instance
class TemplateVms(object):
metric_name = "instances.running"
title = _("Instance count")
label = _("instance count")
def get_minmax(self):
return (0, None)
register_graph(TemplateVms, 'instances', TemplateGraphView)
class NodeListGraphView(GraphViewBase): class NodeListGraphView(GraphViewBase):
model = Node model = Node
base = Metric base = Metric
......
...@@ -47,7 +47,8 @@ from ..tables import TemplateListTable, LeaseListTable ...@@ -47,7 +47,8 @@ from ..tables import TemplateListTable, LeaseListTable
from .util import ( from .util import (
AclUpdateView, FilterMixin, AclUpdateView, FilterMixin,
TransferOwnershipConfirmView, TransferOwnershipView, TransferOwnershipConfirmView, TransferOwnershipView,
DeleteViewBase DeleteViewBase,
GraphMixin
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -258,7 +259,8 @@ class TemplateDelete(DeleteViewBase): ...@@ -258,7 +259,8 @@ class TemplateDelete(DeleteViewBase):
object.delete() object.delete()
class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView): class TemplateDetail(LoginRequiredMixin, GraphMixin,
SuccessMessageMixin, UpdateView):
model = InstanceTemplate model = InstanceTemplate
template_name = "dashboard/template-edit.html" template_name = "dashboard/template-edit.html"
form_class = TemplateForm form_class = TemplateForm
...@@ -300,6 +302,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView): ...@@ -300,6 +302,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
context['is_owner'] = obj.has_level(self.request.user, 'owner') context['is_owner'] = obj.has_level(self.request.user, 'owner')
context['aclform'] = AclUserOrGroupAddForm() context['aclform'] = AclUserOrGroupAddForm()
context['parent'] = obj.parent context['parent'] = obj.parent
context['show_graph'] = obj.has_level(self.request.user, 'operator')
return context return context
def get_success_url(self): def get_success_url(self):
......
...@@ -200,6 +200,10 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -200,6 +200,10 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
def get_running_instances(self): def get_running_instances(self):
return Instance.active.filter(template=self, status="RUNNING") return Instance.active.filter(template=self, status="RUNNING")
@property
def metric_prefix(self):
return 'template.%d' % self.pk
class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin, class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
TimeStampedModel): TimeStampedModel):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment