Commit 21333f3b by Kálmán Viktor

dashboard: basic template and lease edit views

parent 739a1dec
from django import forms
from vm.models import InstanceTemplate
from vm.models import InstanceTemplate, Lease
from storage.models import Disk
from firewall.models import Vlan
# from django.core.urlresolvers import reverse_lazy
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (Layout, Div, BaseInput, # Submit
Field, HTML)
from crispy_forms.layout import (Layout, Div, BaseInput,
Field, HTML, Submit)
from crispy_forms.layout import TEMPLATE_PACK
from crispy_forms.utils import render_field
from django.template import Context
......@@ -290,6 +290,29 @@ class VmCreateForm(forms.Form):
)
class TemplateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(TemplateForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', 'Save changes'))
class Meta:
model = InstanceTemplate
class LeaseForm(forms.ModelForm):
@property
def helper(self):
helper = FormHelper()
helper.add_input(Submit("submit", "Save changes"))
return helper
class Meta:
model = Lease
class LinkButton(BaseInput):
"""
Used to create a link button descriptor for the {% crispy %} template tag::
......
from django_tables2 import Table
from django_tables2.columns import TemplateColumn, Column, BooleanColumn
from django_tables2 import Table, A
from django_tables2.columns import (TemplateColumn, Column, BooleanColumn,
LinkColumn)
from vm.models import Instance, Node
from vm.models import Instance, Node, InstanceTemplate, Lease
from django.utils.translation import ugettext_lazy as _
......@@ -135,3 +136,64 @@ class NodeVmListTable(Table):
attrs = {'class': ('table table-bordered table-striped table-hover '
'vm-list-table')}
fields = ('pk', 'name', 'state', 'time_of_suspend', 'time_of_delete', )
class TemplateListTable(Table):
pk = LinkColumn(
'dashboard.views.template-detail',
args=[A('pk')],
verbose_name=_("ID"),
)
num_cores = Column(
verbose_name=_("Cores"),
)
ram_size = TemplateColumn(
"{{ record.ram_size }} Mb",
)
priority = TemplateColumn(
"{{ record.priority }}/100 ",
verbose_name=_("CPU priority"),
)
lease = TemplateColumn(
"{{ record.lease.name }}",
verbose_name=_("Lease"),
)
actions = TemplateColumn(
verbose_name=_("Actions"),
template_name="dashboard/template-list/column-template-actions.html"
)
class Meta:
model = InstanceTemplate
attrs = {'class': ('table table-bordered table-striped table-hover'
' template-list-table')}
fields = ('pk', 'name', 'num_cores', 'ram_size', 'arch',
'priority', 'system', 'access_method', 'lease', 'state',
'actions', )
class LeaseListTable(Table):
pk = LinkColumn(
'dashboard.views.lease-detail',
args=[A('pk')],
verbose_name=_("ID"),
)
suspend_in = TemplateColumn(
"{{ record.get_readable_suspend_time }}"
)
delete_in = TemplateColumn(
"{{ record.get_readable_delete_time }}"
)
actions = TemplateColumn(
verbose_name=_("Actions"),
template_name="dashboard/template-list/column-lease-actions.html"
)
class Meta:
model = Lease
attrs = {'class': ('table table-bordered table-striped table-hover'
' lease-list-table')}
fields = ('pk', 'name', 'suspend_in', 'delete_in', )
......@@ -25,7 +25,7 @@
</a>
<div href="#" class="list-group-item list-group-footer text-right">
<p>
<a class="btn btn-primary btn-xs"><i class="icon-chevron-sign-right"></i> show more </a>
<a href="{% url "dashboard.views.template-list" %}" class="btn btn-primary btn-xs"><i class="icon-chevron-sign-right"></i> show all </a>
<a class="btn btn-success btn-xs"><i class="icon-upload-alt"></i> upload </a>
</p>
</div>
......
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.template-list" %}">Back</a>
<h3 class="no-margin"><i class="icon-desktop"></i> Edit lease</h3>
</div>
<div class="panel-body">
{% crispy form %}
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.template-list" %}">Back</a>
<h3 class="no-margin"><i class="icon-desktop"></i> Edit template</h3>
</div>
<div class="panel-body">
{% crispy form %}
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<a href="#" class="pull-right btn btn-success btn-xs">
<i class="icon-plus"></i> new template
</a>
<h3 class="no-margin"><i class="icon-desktop"></i> {% trans "Templates" %}</h3>
</div>
<div class="panel-body">
<div class="" style="max-width: 600px;">
{% render_table lease_table %}
</div>
{% render_table table %}
</div>
</div>
</div>
</div>
<style>
.template-list-table td, .template-list-table th,
.lease-list-table td, .lease-list-table th {
text-align: center;
}
.vm-list-table-thin {
width: 10px;
}
.vm-list-table-admin {
width: 130px;
}
</style>
{% endblock %}
{% load i18n %}
<a href="{% url "dashboard.views.lease-detail" pk=record.pk %}" id="template-list-edit-button" class="btn btn-default btn-xs" title data-original-title="{% trans "Edit" %}">
<i class="icon-edit"></i>
</a>
<a href="#" class="btn btn-danger btn-xs" title data-original-title="{% trans "Delete" %}">
<i class="icon-remove"></i>
</a>
{% load i18n %}
<a href="{% url "dashboard.views.template-detail" pk=record.pk%}" id="template-list-edit-button" class="btn btn-default btn-xs" title data-original-title="{% trans "Edit" %}">
<i class="icon-edit"></i>
</a>
<a href="#" class="btn btn-danger btn-xs" title data-original-title="{% trans "Delete" %}">
<i class="icon-remove"></i>
</a>
......@@ -5,13 +5,18 @@ from .views import (
IndexView, VmDetailView, VmList, VmCreate, TemplateDetail, AclUpdateView,
VmDelete, VmMassDelete, vm_activity, NodeList, NodeDetailView, PortDelete,
TransferOwnershipView, TransferOwnershipConfirmView, NodeDelete,
NodeCreate)
TemplateList, LeaseDetail, NodeCreate,
)
urlpatterns = patterns(
'',
url(r'^$', IndexView.as_view(), name="dashboard.index"),
url(r'^lease/(?P<pk>\d+)/$', LeaseDetail.as_view(),
name="dashboard.views.lease-detail"),
url(r'^template/(?P<pk>\d+)/$', TemplateDetail.as_view(),
name='dashboard.views.template-detail'),
url(r"^template/list/$", TemplateList.as_view(),
name="dashboard.views.template-list"),
url(r'^vm/(?P<pk>\d+)/remove_port/(?P<rule>\d+)/$', PortDelete.as_view(),
name='dashboard.views.remove-port'),
url(r'^vm/(?P<pk>\d+)/$', VmDetailView.as_view(),
......
......@@ -14,23 +14,43 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import redirect, render
from django.views.decorators.http import require_POST
from django.views.generic.detail import SingleObjectMixin
from django.views.generic import TemplateView, DetailView, View, DeleteView
from django.views.generic import (TemplateView, DetailView, View, DeleteView,
UpdateView)
from django.contrib import messages
from django.utils.translation import ugettext as _
from django_tables2 import SingleTableView
from braces.views import LoginRequiredMixin
from .forms import VmCreateForm
from .tables import (VmListTable, NodeListTable, NodeVmListTable)
from .forms import VmCreateForm, TemplateForm, LeaseForm
from .tables import (VmListTable, NodeListTable, NodeVmListTable,
TemplateListTable, LeaseListTable)
from vm.models import (Instance, InstanceTemplate, InterfaceTemplate,
InstanceActivity, Node, instance_activity)
InstanceActivity, Node, instance_activity, Lease)
from firewall.models import Vlan, Host, Rule
from storage.models import Disk
logger = logging.getLogger(__name__)
# github.com/django/django/blob/stable/1.6.x/django/contrib/messages/views.py
class SuccessMessageMixin(object):
"""
Adds a success message on successful form submission.
"""
success_message = ''
def form_valid(self, form):
response = super(SuccessMessageMixin, self).form_valid(form)
success_message = self.get_success_message(form.cleaned_data)
if success_message:
messages.success(self.request, success_message)
return response
def get_success_message(self, cleaned_data):
return self.success_message % cleaned_data
class IndexView(LoginRequiredMixin, TemplateView):
template_name = "dashboard/index.html"
......@@ -331,8 +351,11 @@ class AclUpdateView(View, SingleObjectMixin):
value, unicode(request.user))
class TemplateDetail(DetailView):
class TemplateDetail(SuccessMessageMixin, UpdateView):
model = InstanceTemplate
template_name = "dashboard/template-edit.html"
form_class = TemplateForm
success_message = _("Successfully modified template!")
def get(self, request, *args, **kwargs):
if request.is_ajax():
......@@ -357,8 +380,23 @@ class TemplateDetail(DetailView):
return HttpResponse(json.dumps(template),
content_type="application/json")
else:
# return super(TemplateDetail, self).get(request, *args, **kwargs)
return HttpResponse('soon')
return super(TemplateDetail, self).get(request, *args, **kwargs)
def get_success_url(self):
return reverse_lazy("dashboard.views.template-detail",
kwargs=self.kwargs)
class TemplateList(SingleTableView):
template_name = "dashboard/template-list.html"
model = InstanceTemplate
table_class = TemplateListTable
table_pagination = False
def get_context_data(self, *args, **kwargs):
context = super(TemplateList, self).get_context_data(*args, **kwargs)
context['lease_table'] = LeaseListTable(Lease.objects.all())
return context
class VmList(LoginRequiredMixin, SingleTableView):
......@@ -699,6 +737,16 @@ class VmMassDelete(View):
return redirect(next if next else reverse_lazy('dashboard.index'))
class LeaseDetail(SuccessMessageMixin, UpdateView):
model = Lease
form_class = LeaseForm
template_name = "dashboard/lease-edit.html"
success_message = _("Successfully modified lease!")
def get_success_url(self):
return reverse_lazy("dashboard.views.lease-detail", kwargs=self.kwargs)
@require_POST
def vm_activity(request, pk):
object = Instance.objects.get(pk=pk)
......
from __future__ import absolute_import, unicode_literals
from datetime import timedelta
from datetime import timedelta, datetime
from django.db.models import Model, CharField, IntegerField
from django.utils.translation import ugettext_lazy as _
from django.utils.timesince import timeuntil
from model_utils.models import TimeStampedModel
......@@ -81,8 +82,18 @@ class Lease(Model):
def delete_interval(self, value):
self.delete_interval_seconds = value.seconds
def get_readable_suspend_time(self):
return timeuntil(datetime.utcnow() + self.suspend_interval,
datetime.utcnow())
def get_readable_delete_time(self):
return timeuntil(datetime.utcnow() + self.delete_interval,
datetime.utcnow())
def __unicode__(self):
return self.name
return "%s (%s) - (%s)" % (self.name,
self.get_readable_suspend_time(),
self.get_readable_delete_time())
class Trait(Model):
......
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