diff --git a/circle/dashboard/forms.py b/circle/dashboard/forms.py index 6d37ab6..cf742c5 100644 --- a/circle/dashboard/forms.py +++ b/circle/dashboard/forms.py @@ -54,7 +54,7 @@ from firewall.models import Vlan, Host from vm.models import ( InstanceTemplate, Lease, InterfaceTemplate, Node, Trait, Instance ) -from storage.models import DataStore +from storage.models import DataStore, Disk from django.contrib.admin.widgets import FilteredSelectMultiple from django.contrib.auth.models import Permission from .models import Profile, GroupProfile @@ -1523,3 +1523,14 @@ class DataStoreForm(ModelForm): class Meta: model = DataStore + + +class DiskForm(ModelForm): + def __init__(self, *args, **kwargs): + super(DiskForm, self).__init__(*args, **kwargs) + + for k, v in self.fields.iteritems(): + v.widget.attrs['readonly'] = True + + class Meta: + model = Disk diff --git a/circle/dashboard/tables.py b/circle/dashboard/tables.py index f56b542..f92066a 100644 --- a/circle/dashboard/tables.py +++ b/circle/dashboard/tables.py @@ -22,7 +22,6 @@ from django_tables2 import Table, A from django_tables2.columns import (TemplateColumn, Column, LinkColumn, BooleanColumn) from django.utils.safestring import mark_safe -from django.utils.html import escape from vm.models import Node, InstanceTemplate, Lease from storage.models import Disk @@ -55,6 +54,7 @@ class ApplianceColumn(TemplateColumn): title, text = ugettext("Virtual machine"), ugettext("[VM]") return mark_safe("%s %s" % (abbr % (title, text), value)) + class NodeListTable(Table): pk = Column( @@ -322,7 +322,11 @@ class ConnectCommandListTable(Table): class DiskListTable(Table): - + pk = LinkColumn( + 'dashboard.views.disk-detail', + args=[A('pk')], + verbose_name=_("ID"), + ) size = FileSizeColumn() appliance = ApplianceColumn( template_name="dashboard/storage/column-appliance.html", diff --git a/circle/dashboard/templates/dashboard/base.html b/circle/dashboard/templates/dashboard/base.html index 4e57af7..611d267 100644 --- a/circle/dashboard/templates/dashboard/base.html +++ b/circle/dashboard/templates/dashboard/base.html @@ -24,6 +24,11 @@ <a href="/admin/"><i class="fa fa-cogs"></i> {% trans "Admin" %}</a> </li> <li> + <a href="{% url "dashboard.views.storage" %}"><i class="fa fa-database"></i> + {% trans "Storage" %} + </a> + </li> + <li> <a href="/network/"><i class="fa fa-globe"></i> {% trans "Network" %}</a> </li> {% endif %} diff --git a/circle/dashboard/templates/dashboard/storage/disk.html b/circle/dashboard/templates/dashboard/storage/disk.html new file mode 100644 index 0000000..ce659ae --- /dev/null +++ b/circle/dashboard/templates/dashboard/storage/disk.html @@ -0,0 +1,33 @@ +{% extends "dashboard/base.html" %} +{% load staticfiles %} +{% load i18n %} +{% load render_table from django_tables2 %} +{% load crispy_forms_tags %} + +{% block title-page %}{% trans "Disk" %} | {% trans "Storage" %}{% endblock %} + +{% block content %} + +<div class="row"> + <div class="col-md-12"> + <div class="panel panel-default"> + <div class="panel-heading"> + <div class="pull-right"> + {% with app=object.get_appliance %} + {% if app %} + {% trans "Appliance" %}: <a href="{{ app.get_absolute_url }}">{{ app.name }}</a> + {% else %} + This disk is not attached to anything. + {% endif %} + {% endwith %} + </div> + <h3 class="no-margin"><i class="fa fa-file"></i> {% trans "Disk" %}</h3> + </div> + <div class="panel-body"> + {% crispy form %} + </div><!-- .panel-body --> + </div> + </div> +</div> + +{% endblock %} diff --git a/circle/dashboard/urls.py b/circle/dashboard/urls.py index dd326c7..4fc9d59 100644 --- a/circle/dashboard/urls.py +++ b/circle/dashboard/urls.py @@ -52,7 +52,7 @@ from .views import ( TransferTemplateOwnershipView, TransferTemplateOwnershipConfirmView, OpenSearchDescriptionView, NodeActivityView, - StorageDetail, + StorageDetail, DiskDetail, ) from .views.vm import vm_ops, vm_mass_ops from .views.node import node_ops @@ -228,6 +228,8 @@ urlpatterns = patterns( url(r'^storage/$', StorageDetail.as_view(), name="dashboard.views.storage"), + url(r'^disk/(?P<pk>\d+)/$', DiskDetail.as_view(), + name="dashboard.views.disk-detail"), ) urlpatterns += patterns( diff --git a/circle/dashboard/views/storage.py b/circle/dashboard/views/storage.py index 17068b2..1088f6c 100644 --- a/circle/dashboard/views/storage.py +++ b/circle/dashboard/views/storage.py @@ -17,19 +17,18 @@ from __future__ import unicode_literals, absolute_import -from django.views.generic import ( - UpdateView -) +from django.views.generic import UpdateView from django.core.urlresolvers import reverse from sizefield.utils import filesizeformat +from braces.views import SuperuserRequiredMixin from storage.models import DataStore, Disk from ..tables import DiskListTable -from ..forms import DataStoreForm +from ..forms import DataStoreForm, DiskForm -class StorageDetail(UpdateView): +class StorageDetail(SuperuserRequiredMixin, UpdateView): model = DataStore form_class = DataStoreForm template_name = "dashboard/storage/detail.html" @@ -67,3 +66,9 @@ class StorageDetail(UpdateView): def get_success_url(self): return reverse("dashboard.views.storage") + + +class DiskDetail(SuperuserRequiredMixin, UpdateView): + model = Disk + form_class = DiskForm + template_name = "dashboard/storage/disk.html"