Commit c8b6d787 by Kálmán Viktor

dashboard: disk resize messages

parent 11c3e46a
...@@ -65,7 +65,8 @@ urlpatterns = patterns( ...@@ -65,7 +65,8 @@ urlpatterns = patterns(
url(r'^info/support/$', url(r'^info/support/$',
TemplateView.as_view(template_name="info/support.html"), TemplateView.as_view(template_name="info/support.html"),
name="info.support"), name="info.support"),
url(r'^info/resize-how-to/$', ResizeHelpView.as_view(), name="info.resize"), url(r'^info/resize-how-to/$', ResizeHelpView.as_view(),
name="info.resize"),
) )
......
...@@ -35,8 +35,10 @@ import requests ...@@ -35,8 +35,10 @@ import requests
from sizefield.models import FileSizeField from sizefield.models import FileSizeField
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
from model_utils import Choices from model_utils import Choices
from sizefield.utils import filesizeformat
from vm.models import Instance, InstanceTemplate, Lease from vm.models import Instance, InstanceTemplate, Lease
from vm.operations import ResourcesOperation, ResizeDiskOperation
from storage.models import Disk from storage.models import Disk
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -51,6 +53,9 @@ class RequestAction(Model): ...@@ -51,6 +53,9 @@ class RequestAction(Model):
def accept_msg(self): def accept_msg(self):
raise NotImplementedError raise NotImplementedError
def is_acceptable(self):
return True
class Meta: class Meta:
abstract = True abstract = True
...@@ -147,6 +152,10 @@ class Request(TimeStampedModel): ...@@ -147,6 +152,10 @@ class Request(TimeStampedModel):
decline_msg, url=self.get_absolute_url(), reason=self.reason, decline_msg, url=self.get_absolute_url(), reason=self.reason,
) )
@property
def is_acceptable(self):
return self.action.is_acceptable()
class LeaseType(RequestType): class LeaseType(RequestType):
lease = ForeignKey(Lease, verbose_name=_("Lease")) lease = ForeignKey(Lease, verbose_name=_("Lease"))
...@@ -204,6 +213,9 @@ class ResourceChangeAction(RequestAction): ...@@ -204,6 +213,9 @@ class ResourceChangeAction(RequestAction):
'priority': self.priority, 'priority': self.priority,
} }
def is_acceptable(self):
return self.instance.status in ResourcesOperation.accept_states
class ExtendLeaseAction(RequestAction): class ExtendLeaseAction(RequestAction):
instance = ForeignKey(Instance) instance = ForeignKey(Instance)
...@@ -255,19 +267,23 @@ class DiskResizeAction(RequestAction): ...@@ -255,19 +267,23 @@ class DiskResizeAction(RequestAction):
disk = ForeignKey(Disk) disk = ForeignKey(Disk)
size = FileSizeField(null=True, default=None) size = FileSizeField(null=True, default=None)
def get_readable_level(self):
return self.LEVELS[self.level]
def accept(self, user): def accept(self, user):
pass self.instance.resize_disk(disk=self.disk, size=self.size, user=user)
@property @property
def accept_msg(self): def accept_msg(self):
return ungettext( return _(
"You got access to the following template: %s", 'The disk <em class="text-muted">%(disk_name)s (#%(id)d)</em> of '
"You got access to the following templates: %s", '<a href="%(url)s">%(vm_name)s</a> got resized. '
self.template_type.templates.count() 'The new size is: %(bytes)d bytes (%(size)s).'
) % ", ".join([x.name for x in self.template_type.templates.all()]) ) % {'disk_name': self.disk.name, 'id': self.disk.id,
'url': self.instance.get_absolute_url(),
'vm_name': self.instance.name,
'bytes': self.size, 'size': filesizeformat(self.size),
}
def is_acceptable(self):
return self.instance.status in ResizeDiskOperation.accept_states
def send_notifications(sender, instance, created, **kwargs): def send_notifications(sender, instance, created, **kwargs):
......
...@@ -66,6 +66,15 @@ ...@@ -66,6 +66,15 @@
<dd>{{ action.get_readable_level }}</dd> <dd>{{ action.get_readable_level }}</dd>
</dl> </dl>
{% elif object.type == "resource" %} {% elif object.type == "resource" %}
{% if not is_acceptable %}
<div class="alert alert-warning">
{% blocktrans %}
To change the resources the virtual machine must be in one of the following states:
STOPPED, PENDING, RUNNING. If the virtual machine is running it will be
automatically stopped when accepting the request.
{% endblocktrans %}
</div>
{% endif %}
<dl> <dl>
<dt>{% trans "VM name" %}</dt> <dt>{% trans "VM name" %}</dt>
<dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd> <dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd>
...@@ -75,7 +84,7 @@ ...@@ -75,7 +84,7 @@
{{ action.instance.get_status_display|upper }} {{ action.instance.get_status_display|upper }}
</dd> </dd>
<dt>{% trans "VM description" %}</dt> <dt>{% trans "VM description" %}</dt>
<dd>{{ action.instance.description }}</dd> <dd>{{ action.instance.description|default:"-" }}</dd>
<dt> <dt>
{% trans "Priority" %} {% trans "Priority" %}
<span class="text-muted" style="font-weight: normal;">{% trans "(old values in parentheses)" %}</span> <span class="text-muted" style="font-weight: normal;">{% trans "(old values in parentheses)" %}</span>
...@@ -87,9 +96,19 @@ ...@@ -87,9 +96,19 @@
<dd>{{ action.ram_size }} ({{ action.instance.ram_size }}) MiB</dd> <dd>{{ action.ram_size }} ({{ action.instance.ram_size }}) MiB</dd>
</dl> </dl>
{% elif object.type == "resize" %} {% elif object.type == "resize" %}
{% if not is_acceptable %}
<div class="alert alert-warning">
{% trans "To resize the disk the virtual machine must be in RUNNING state." %}
</div>
{% endif %}
<dl> <dl>
<dt>{% trans "VM name" %}</dt> <dt>{% trans "VM name" %}</dt>
<dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd> <dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd>
<dt>{% trans "Status" %}</dt>
<dd>
<i class="fa {{ action.instance.get_status_icon }}"></i>
{{ action.instance.get_status_display|upper }}
</dd>
<dt>{% trans "VM description" %}</dt> <dt>{% trans "VM description" %}</dt>
<dd>{{ action.instance.description|default:"-" }}</dd> <dd>{{ action.instance.description|default:"-" }}</dd>
<dt>{% trans "Disk" %}</dt> <dt>{% trans "Disk" %}</dt>
...@@ -125,7 +144,7 @@ ...@@ -125,7 +144,7 @@
{% trans "Decline" %} {% trans "Decline" %}
</button> </button>
</form> </form>
{% if object.type == "resource" and action.instance.status not in accept_states %} {% if not is_acceptable %}
{% trans "You can't accept this request because of the VM's state." %} {% trans "You can't accept this request because of the VM's state." %}
{% else %} {% else %}
<form method="POST"> <form method="POST">
......
...@@ -19,11 +19,13 @@ from __future__ import unicode_literals, absolute_import ...@@ -19,11 +19,13 @@ from __future__ import unicode_literals, absolute_import
from django.views.generic import ( from django.views.generic import (
UpdateView, TemplateView, DetailView, CreateView, FormView, DeleteView, UpdateView, TemplateView, DetailView, CreateView, FormView, DeleteView,
) )
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import redirect, get_object_or_404 from django.shortcuts import redirect, get_object_or_404
from django.core.exceptions import PermissionDenied, SuspiciousOperation from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.http import JsonResponse
from braces.views import SuperuserRequiredMixin, LoginRequiredMixin from braces.views import SuperuserRequiredMixin, LoginRequiredMixin
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
...@@ -34,7 +36,6 @@ from request.models import ( ...@@ -34,7 +36,6 @@ from request.models import (
) )
from storage.models import Disk from storage.models import Disk
from vm.models import Instance from vm.models import Instance
from vm.operations import ResourcesOperation
from request.tables import ( from request.tables import (
RequestTable, TemplateAccessTypeTable, LeaseTypeTable, RequestTable, TemplateAccessTypeTable, LeaseTypeTable,
) )
...@@ -94,7 +95,7 @@ class RequestDetail(LoginRequiredMixin, DetailView): ...@@ -94,7 +95,7 @@ class RequestDetail(LoginRequiredMixin, DetailView):
context = super(RequestDetail, self).get_context_data(**kwargs) context = super(RequestDetail, self).get_context_data(**kwargs)
context['action'] = request.action context['action'] = request.action
context['accept_states'] = ResourcesOperation.accept_states context['is_acceptable'] = request.is_acceptable
# workaround for http://git.io/vIIYi # workaround for http://git.io/vIIYi
context['request'] = self.request context['request'] = self.request
...@@ -168,6 +169,7 @@ class RequestTypeList(LoginRequiredMixin, SuperuserRequiredMixin, ...@@ -168,6 +169,7 @@ class RequestTypeList(LoginRequiredMixin, SuperuserRequiredMixin,
class TemplateRequestView(LoginRequiredMixin, FormView): class TemplateRequestView(LoginRequiredMixin, FormView):
form_class = TemplateRequestForm form_class = TemplateRequestForm
template_name = "request/request-template.html" template_name = "request/request-template.html"
success_message = _("Request successfully sent.")
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super(TemplateRequestView, self).get_form_kwargs() kwargs = super(TemplateRequestView, self).get_form_kwargs()
...@@ -193,7 +195,8 @@ class TemplateRequestView(LoginRequiredMixin, FormView): ...@@ -193,7 +195,8 @@ class TemplateRequestView(LoginRequiredMixin, FormView):
) )
req.save() req.save()
return redirect("/") messages.success(self.request, self.success_message)
return redirect(reverse("dashboard.index"))
class VmRequestMixin(LoginRequiredMixin, object): class VmRequestMixin(LoginRequiredMixin, object):
...@@ -225,6 +228,7 @@ class LeaseRequestView(VmRequestMixin, FormView): ...@@ -225,6 +228,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
form_class = LeaseRequestForm form_class = LeaseRequestForm
template_name = "request/request-lease.html" template_name = "request/request-lease.html"
user_level = "operator" user_level = "operator"
success_message = _("Request successfully sent.")
def form_valid(self, form): def form_valid(self, form):
data = form.cleaned_data data = form.cleaned_data
...@@ -245,6 +249,7 @@ class LeaseRequestView(VmRequestMixin, FormView): ...@@ -245,6 +249,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
) )
req.save() req.save()
messages.success(self.request, self.success_message)
return redirect(vm.get_absolute_url()) return redirect(vm.get_absolute_url())
...@@ -252,6 +257,7 @@ class ResourceRequestView(VmRequestMixin, FormView): ...@@ -252,6 +257,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
form_class = ResourceRequestForm form_class = ResourceRequestForm
template_name = "request/request-resource.html" template_name = "request/request-resource.html"
user_level = "user" user_level = "user"
success_message = _("Request successfully sent.")
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super(ResourceRequestView, self).get_form_kwargs() kwargs = super(ResourceRequestView, self).get_form_kwargs()
...@@ -288,6 +294,7 @@ class ResourceRequestView(VmRequestMixin, FormView): ...@@ -288,6 +294,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
) )
req.save() req.save()
messages.success(self.request, self.success_message)
return redirect(vm.get_absolute_url()) return redirect(vm.get_absolute_url())
...@@ -295,6 +302,7 @@ class ResizeRequestView(VmRequestMixin, FormView): ...@@ -295,6 +302,7 @@ class ResizeRequestView(VmRequestMixin, FormView):
form_class = ResizeRequestForm form_class = ResizeRequestForm
template_name = "request/_request-resize-form.html" template_name = "request/_request-resize-form.html"
user_level = "owner" user_level = "owner"
success_message = _("Request successfully sent.")
def get_disk(self, *args, **kwargs): def get_disk(self, *args, **kwargs):
return get_object_or_404(Disk, pk=self.kwargs['disk_pk']) return get_object_or_404(Disk, pk=self.kwargs['disk_pk'])
...@@ -327,12 +335,13 @@ class ResizeRequestView(VmRequestMixin, FormView): ...@@ -327,12 +335,13 @@ class ResizeRequestView(VmRequestMixin, FormView):
dra = DiskResizeAction(instance=vm, disk=disk, size=data['size']) dra = DiskResizeAction(instance=vm, disk=disk, size=data['size'])
dra.save() dra.save()
req = Request( req = Request(user=user, message=data['message'], action=dra,
user=user, type=Request.TYPES.resize)
message=data['message'],
type=Request.TYPES.resize,
action=dra
)
req.save() req.save()
if self.request.is_ajax():
return JsonResponse({'success': True,
'messages': [self.success_message]})
else:
messages.success(self.request, self.success_message)
return redirect(vm.get_absolute_url()) return redirect(vm.get_absolute_url())
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