Commit cc728f9b by Kálmán Viktor

dashboard: list unused/rarely used templates

parent cfae5fec
{% for t in templates %}
<a href="{{ t.get_absolute_url }}">
{{ t.name }}</a>{% if not forloop.last %},{% endif %}
{% empty %}
-
{% endfor %}
...@@ -63,18 +63,36 @@ ...@@ -63,18 +63,36 @@
</div> </div>
</div> </div>
{% comment %}
<div class="col-md-6"> <div class="col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="no-margin"><i class="fa fa-desktop"></i> Placeholder</h3> <h3 class="no-margin">
<i class="fa fa-puzzle-piece"></i>
{% trans "Rarely used templates" %}
</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
??? <dl>
<dt>{% trans "Never instantiated" %}</dd>
<dd>
{% include "dashboard/_list-templates.html" with templates=unused_templates.never_instantiated %}
</dd>
<dt>{% trans "Templates without running instances" %}</dd>
<dd>
{% include "dashboard/_list-templates.html" with templates=unused_templates.templates_wo_instances %}
</dd>
<dt>{% trans "Templates without instances, last instance created more than 90 days ago" %}</dd>
<dd>
{% include "dashboard/_list-templates.html" with templates=unused_templates.templates_wo_instances_90 %}
</dd>
<dt>{% trans "Templates without instances, last instance created more than 180 days ago" %}</dd>
<dd>
{% include "dashboard/_list-templates.html" with templates=unused_templates.templates_wo_instances_180 %}
</dd>
</dl>
</div> </div>
</div> </div>
</div> </div>
{% endcomment %}
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>. # with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from datetime import timedelta
import json import json
import logging import logging
...@@ -24,8 +25,10 @@ from django.contrib.auth.models import User ...@@ -24,8 +25,10 @@ from django.contrib.auth.models import User
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.core.exceptions import PermissionDenied, SuspiciousOperation from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.db.models import Count
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, get_object_or_404 from django.shortcuts import redirect, get_object_or_404
from django.utils import timezone
from django.utils.translation import ugettext as _, ugettext_noop from django.utils.translation import ugettext as _, ugettext_noop
from django.views.generic import ( from django.views.generic import (
TemplateView, CreateView, UpdateView, TemplateView, CreateView, UpdateView,
...@@ -36,7 +39,9 @@ from braces.views import ( ...@@ -36,7 +39,9 @@ from braces.views import (
) )
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from vm.models import InstanceTemplate, InterfaceTemplate, Instance, Lease from vm.models import (
InstanceTemplate, InterfaceTemplate, Instance, Lease, InstanceActivity
)
from storage.models import Disk from storage.models import Disk
from ..forms import ( from ..forms import (
...@@ -203,6 +208,41 @@ class TemplateList(LoginRequiredMixin, FilterMixin, SingleTableView): ...@@ -203,6 +208,41 @@ class TemplateList(LoginRequiredMixin, FilterMixin, SingleTableView):
context['search_form'] = self.search_form context['search_form'] = self.search_form
# templates without any instances
# [t for t in InstanceTemplate.objects.all()
# if t.instance_set.count() < 1]
never_instantiated = context['object_list'].annotate(
instance_count=Count("instance_set")).filter(instance_count__lt=1)
# templates without active virtual machines
active_statuses = Instance.STATUS._db_values - set(["DESTROYED"])
templates_wo_instances = context['object_list'].exclude(
pk__in=InstanceTemplate.objects.filter(
instance_set__status__in=active_statuses)
).exclude(pk__in=never_instantiated)
def get_create_acts_younger_than(days):
return InstanceActivity.objects.filter(
activity_code="vm.Instance.create",
finished__gt=timezone.now() - timedelta(days=days))
# templates without active virtual machines
# last machine started later than 90 days
templates_wo_i_90 = templates_wo_instances.exclude(
instance_set__activity_log__in=get_create_acts_younger_than(90))
# templates without active virtual machines
# last machine started later than 180 days
templates_wo_i_180 = templates_wo_instances.exclude(
instance_set__activity_log__in=get_create_acts_younger_than(180))
context['unused_templates'] = {
'never_instantiated': never_instantiated,
'templates_wo_instances': templates_wo_instances,
'templates_wo_instances_90': templates_wo_i_90,
'templates_wo_instances_180': templates_wo_i_180,
}
return context return context
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
......
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