Commit 338c3960 by Kálmán Viktor

Merge branch 'master' into issue-282

Conflicts:
	circle/network/views.py
parents 999a46e0 65fd2ea6
import autocomplete_light import autocomplete_light
from django.contrib.auth.models import User
from django.utils.html import escape
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from .views import AclUpdateView from .views import AclUpdateView
from .models import Profile
class AclUserAutocomplete(autocomplete_light.AutocompleteGenericBase): def highlight(field, q, none_wo_match=True):
"""
>>> highlight('<b>Akkount Krokodil', 'kro', False)
u'&lt;b&gt;Akkount <span class="autocomplete-hl">Kro</span>kodil'
"""
if not field:
return None
try:
match = field.lower().index(q.lower())
except ValueError:
match = None
if q and match is not None:
match_end = match + len(q)
return (escape(field[:match])
+ '<span class="autocomplete-hl">'
+ escape(field[match:match_end])
+ '</span>' + escape(field[match_end:]))
elif none_wo_match:
return None
else:
return escape(field)
class AclUserGroupAutocomplete(autocomplete_light.AutocompleteGenericBase):
search_fields = ( search_fields = (
('^first_name', 'last_name', 'username', '^email', 'profile__org_id'), ('first_name', 'last_name', 'username', 'email', 'profile__org_id'),
('^name', 'groupprofile__org_id'), ('name', 'groupprofile__org_id'),
) )
autocomplete_js_attributes = {'placeholder': _("Name of group or user")} choice_html_format = (u'<span data-value="%s"><span style="display:none"'
choice_html_format = u'<span data-value="%s"><span>%s</span> %s</span>' u'>%s</span>%s</span>')
def choice_html(self, choice): def choice_displayed_text(self, choice):
try: q = unicode(self.request.GET.get('q', ''))
name = choice.get_full_name() name = highlight(unicode(choice), q, False)
except AttributeError: if isinstance(choice, User):
name = _('group') extra_fields = [highlight(choice.get_full_name(), q, False),
if name: highlight(choice.email, q)]
name = u'(%s)' % name try:
extra_fields.append(highlight(choice.profile.org_id, q))
except Profile.DoesNotExist:
pass
return '%s (%s)' % (name, ', '.join(f for f in extra_fields
if f))
else:
return _('%s (group)') % name
def choice_html(self, choice):
return self.choice_html_format % ( return self.choice_html_format % (
self.choice_value(choice), self.choice_label(choice), name) self.choice_value(choice), self.choice_label(choice),
self.choice_displayed_text(choice))
def choices_for_request(self): def choices_for_request(self):
user = self.request.user user = self.request.user
self.choices = (AclUpdateView.get_allowed_users(user), self.choices = (AclUpdateView.get_allowed_users(user),
AclUpdateView.get_allowed_groups(user)) AclUpdateView.get_allowed_groups(user))
return super(AclUserAutocomplete, self).choices_for_request() return super(AclUserGroupAutocomplete, self).choices_for_request()
def autocomplete_html(self):
html = []
for choice in self.choices_for_request():
html.append(self.choice_html(choice))
if not html:
html = self.empty_html_format % _('no matches found').capitalize()
return self.autocomplete_html_format % ''.join(html)
class AclUserAutocomplete(AclUserGroupAutocomplete):
def choices_for_request(self):
user = self.request.user
self.choices = (AclUpdateView.get_allowed_users(user), )
return super(AclUserGroupAutocomplete, self).choices_for_request()
autocomplete_light.register(AclUserGroupAutocomplete)
autocomplete_light.register(AclUserAutocomplete) autocomplete_light.register(AclUserAutocomplete)
...@@ -1055,9 +1055,29 @@ class UserCreationForm(OrgUserCreationForm): ...@@ -1055,9 +1055,29 @@ class UserCreationForm(OrgUserCreationForm):
return user return user
class AclUserAddForm(forms.Form): class AclUserOrGroupAddForm(forms.Form):
name = forms.CharField(widget=autocomplete_light.TextWidget( name = forms.CharField(widget=autocomplete_light.TextWidget(
'AclUserAutocomplete', attrs={'class': 'form-control'})) 'AclUserGroupAutocomplete',
autocomplete_js_attributes={'placeholder': _("Name of group or user")},
attrs={'class': 'form-control'}))
class TransferOwnershipForm(forms.Form):
name = forms.CharField(
widget=autocomplete_light.TextWidget(
'AclUserAutocomplete',
autocomplete_js_attributes={"placeholder": _("Name of user")},
attrs={'class': 'form-control'}),
label=_("E-mail address or identifier of user"))
class AddGroupMemberForm(forms.Form):
new_member = forms.CharField(
widget=autocomplete_light.TextWidget(
'AclUserAutocomplete',
autocomplete_js_attributes={"placeholder": _("Name of user")},
attrs={'class': 'form-control'}),
label=_("E-mail address or identifier of user"))
class UserKeyForm(forms.ModelForm): class UserKeyForm(forms.ModelForm):
......
...@@ -591,11 +591,15 @@ footer a, footer a:hover, footer a:visited { ...@@ -591,11 +591,15 @@ footer a, footer a:hover, footer a:visited {
width: 100px; width: 100px;
} }
#group-detail-user-table tr:last-child td:nth-child(2) {
text-align: left;
}
#group-detail-perm-header { #group-detail-perm-header {
margin-top: 25px; margin-top: 25px;
} }
textarea[name="list-new-namelist"] { textarea[name="new_members"] {
max-width: 500px; max-width: 500px;
min-height: 80px; min-height: 80px;
margin-bottom: 10px; margin-bottom: 10px;
...@@ -960,3 +964,12 @@ textarea[name="list-new-namelist"] { ...@@ -960,3 +964,12 @@ textarea[name="list-new-namelist"] {
#vm-activity-state { #vm-activity-state {
margin-bottom: 15px; margin-bottom: 15px;
} }
.autocomplete-hl {
color: #b20000;
font-weight: bold;
}
.hilight .autocomplete-hl {
color: orange;
}
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
<div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog"> <div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
{% if box_title and ajax_title %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{{ box_title }}</h4>
</div>
{% endif %}
<div class="modal-body"> <div class="modal-body">
{% if template %} {% if template %}
{% include template %} {% include template %}
......
...@@ -89,13 +89,12 @@ ...@@ -89,13 +89,12 @@
<tr> <tr>
<td><i class="fa fa-plus"></i></td> <td><i class="fa fa-plus"></i></td>
<td colspan="2"> <td colspan="2">
<input type="text" class="form-control" name="list-new-name" {{addmemberform.new_member}}
placeholder="{% trans "Name of user" %}">
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<textarea name="list-new-namelist" class="form-control" <textarea name="new_members" class="form-control"
placeholder="{% trans "Add multiple users at once (one identifier per line)." %}"></textarea> placeholder="{% trans "Add multiple users at once (one identifier per line)." %}"></textarea>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="btn btn-success">{% trans "Save" %}</button> <button type="submit" class="btn btn-success">{% trans "Save" %}</button>
......
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
{% endblocktrans %} {% endblocktrans %}
{% endif %} {% endif %}
{% if user == instance.owner or user.is_superuser %} {% if user == instance.owner or user.is_superuser %}
<span class="operation-wrapper">
<a href="{% url "dashboard.views.vm-transfer-ownership" instance.pk %}" <a href="{% url "dashboard.views.vm-transfer-ownership" instance.pk %}"
class="btn btn-link">{% trans "Transfer ownership..." %}</a> class="btn btn-link operation">{% trans "Transfer ownership..." %}</a>
</span>
{% endif %} {% endif %}
</p> </p>
<h3>{% trans "Permissions"|capfirst %}</h3> <h3>{% trans "Permissions"|capfirst %}</h3>
......
{% extends "dashboard/base.html" %}
{% load i18n %} {% load i18n %}
{% block content %} <div class="pull-right">
<div class="body-content"> <form action="{% url "dashboard.views.vm-transfer-ownership" pk=instance.pk %}" method="POST" style="max-width: 400px;">
<div class="panel panel-default"> {% csrf_token %}
<div class="panel-heading"> <label>
<h3 class="no-margin"> {{ form.name.label }}
{% trans "Transfer ownership" %} </label>
</h3> <div class="input-group">
</div> {{form.name}}
<div class="panel-body"> <div class="input-group-btn">
<div class="pull-right"> <input type="submit" value="{% trans "Save" %}" class="btn btn-primary">
<form action="" method="POST">
{% csrf_token %}
<label>
{% trans "E-mail address or identifier of user" %}:
<input name="name">
</label>
<input type="submit">
</form>
</div> </div>
</div> </div>
</div> </form>
{% endblock %} </div>
...@@ -1134,7 +1134,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1134,7 +1134,7 @@ class GroupDetailTest(LoginMixin, TestCase):
c = Client() c = Client()
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', {'list-new-name': 'user3'}) str(self.g1.pk) + '/', {'new_member': 'user3'})
self.assertEqual(user_in_group, self.assertEqual(user_in_group,
self.g1.user_set.count()) self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1144,7 +1144,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1144,7 +1144,7 @@ class GroupDetailTest(LoginMixin, TestCase):
self.login(c, 'user3') self.login(c, 'user3')
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', {'list-new-name': 'user3'}) str(self.g1.pk) + '/', {'new_member': 'user3'})
self.assertEqual(user_in_group, self.g1.user_set.count()) self.assertEqual(user_in_group, self.g1.user_set.count())
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
...@@ -1153,7 +1153,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1153,7 +1153,7 @@ class GroupDetailTest(LoginMixin, TestCase):
self.login(c, 'superuser') self.login(c, 'superuser')
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', {'list-new-name': 'user3'}) str(self.g1.pk) + '/', {'new_member': 'user3'})
self.assertEqual(user_in_group + 1, self.g1.user_set.count()) self.assertEqual(user_in_group + 1, self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1162,7 +1162,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1162,7 +1162,7 @@ class GroupDetailTest(LoginMixin, TestCase):
self.login(c, 'user0') self.login(c, 'user0')
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', {'list-new-name': 'user3'}) str(self.g1.pk) + '/', {'new_member': 'user3'})
self.assertEqual(user_in_group + 1, self.g1.user_set.count()) self.assertEqual(user_in_group + 1, self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1172,7 +1172,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1172,7 +1172,7 @@ class GroupDetailTest(LoginMixin, TestCase):
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', str(self.g1.pk) + '/',
{'list-new-namelist': 'user1\r\nuser2'}) {'new_members': 'user1\r\nuser2'})
self.assertEqual(user_in_group + 2, self.g1.user_set.count()) self.assertEqual(user_in_group + 2, self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1182,7 +1182,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1182,7 +1182,7 @@ class GroupDetailTest(LoginMixin, TestCase):
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', str(self.g1.pk) + '/',
{'list-new-namelist': 'user1\r\nnoname\r\nuser2'}) {'new_members': 'user1\r\nnoname\r\nuser2'})
self.assertEqual(user_in_group + 2, self.g1.user_set.count()) self.assertEqual(user_in_group + 2, self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1192,7 +1192,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1192,7 +1192,7 @@ class GroupDetailTest(LoginMixin, TestCase):
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', str(self.g1.pk) + '/',
{'list-new-namelist': 'user1\r\nuser2'}) {'new_members': 'user1\r\nuser2'})
self.assertEqual(user_in_group, self.g1.user_set.count()) self.assertEqual(user_in_group, self.g1.user_set.count())
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
...@@ -1201,7 +1201,7 @@ class GroupDetailTest(LoginMixin, TestCase): ...@@ -1201,7 +1201,7 @@ class GroupDetailTest(LoginMixin, TestCase):
user_in_group = self.g1.user_set.count() user_in_group = self.g1.user_set.count()
response = c.post('/dashboard/group/' + response = c.post('/dashboard/group/' +
str(self.g1.pk) + '/', str(self.g1.pk) + '/',
{'list-new-namelist': 'user1\r\nuser2'}) {'new_members': 'user1\r\nuser2'})
self.assertEqual(user_in_group, self.g1.user_set.count()) self.assertEqual(user_in_group, self.g1.user_set.count())
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
...@@ -1471,8 +1471,8 @@ class TransferOwnershipViewTest(LoginMixin, TestCase): ...@@ -1471,8 +1471,8 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
c2 = self.u2.notification_set.count() c2 = self.u2.notification_set.count()
c = Client() c = Client()
self.login(c, 'user2') self.login(c, 'user2')
response = c.post('/dashboard/vm/1/tx/') response = c.post('/dashboard/vm/1/tx/', {'name': 'userx'})
assert response.status_code == 400 assert response.status_code == 403
self.assertEqual(self.u2.notification_set.count(), c2) self.assertEqual(self.u2.notification_set.count(), c2)
def test_owned_offer(self): def test_owned_offer(self):
......
...@@ -70,9 +70,10 @@ from .forms import ( ...@@ -70,9 +70,10 @@ from .forms import (
UserCreationForm, GroupProfileUpdateForm, UnsubscribeForm, UserCreationForm, GroupProfileUpdateForm, UnsubscribeForm,
VmSaveForm, UserKeyForm, VmRenewForm, VmStateChangeForm, VmSaveForm, UserKeyForm, VmRenewForm, VmStateChangeForm,
CirclePasswordChangeForm, VmCreateDiskForm, VmDownloadDiskForm, CirclePasswordChangeForm, VmCreateDiskForm, VmDownloadDiskForm,
TraitsForm, RawDataForm, GroupPermissionForm, AclUserAddForm, TraitsForm, RawDataForm, GroupPermissionForm, AclUserOrGroupAddForm,
VmResourcesForm, VmAddInterfaceForm, VmListSearchForm, VmResourcesForm, VmAddInterfaceForm, VmListSearchForm,
TemplateListSearchForm, ConnectCommandForm TemplateListSearchForm, ConnectCommandForm,
TransferOwnershipForm, AddGroupMemberForm
) )
from .tables import ( from .tables import (
...@@ -390,7 +391,7 @@ class VmDetailView(CheckedDetailView): ...@@ -390,7 +391,7 @@ class VmDetailView(CheckedDetailView):
).all() ).all()
context['acl'] = AclUpdateView.get_acl_data( context['acl'] = AclUpdateView.get_acl_data(
instance, self.request.user, 'dashboard.views.vm-acl') instance, self.request.user, 'dashboard.views.vm-acl')
context['aclform'] = AclUserAddForm() context['aclform'] = AclUserOrGroupAddForm()
context['os_type_icon'] = instance.os_type.replace("unknown", context['os_type_icon'] = instance.os_type.replace("unknown",
"question") "question")
# ipv6 infos # ipv6 infos
...@@ -1282,7 +1283,8 @@ class GroupDetailView(CheckedDetailView): ...@@ -1282,7 +1283,8 @@ class GroupDetailView(CheckedDetailView):
context['acl'] = AclUpdateView.get_acl_data( context['acl'] = AclUpdateView.get_acl_data(
self.object.profile, self.request.user, self.object.profile, self.request.user,
'dashboard.views.group-acl') 'dashboard.views.group-acl')
context['aclform'] = AclUserAddForm() context['aclform'] = AclUserOrGroupAddForm()
context['addmemberform'] = AddGroupMemberForm()
context['group_profile_form'] = GroupProfileUpdate.get_form_object( context['group_profile_form'] = GroupProfileUpdate.get_form_object(
self.request, self.object.profile) self.request, self.object.profile)
...@@ -1299,17 +1301,15 @@ class GroupDetailView(CheckedDetailView): ...@@ -1299,17 +1301,15 @@ class GroupDetailView(CheckedDetailView):
if request.POST.get('new_name'): if request.POST.get('new_name'):
return self.__set_name(request) return self.__set_name(request)
if request.POST.get('list-new-name'): if request.POST.get('new_member'):
return self.__add_user(request) return self.__add_user(request)
if request.POST.get('list-new-namelist'): if request.POST.get('new_members'):
return self.__add_list(request) return self.__add_list(request)
if (request.POST.get('list-new-name') is not None) and \ return redirect(reverse_lazy("dashboard.views.group-detail",
(request.POST.get('list-new-namelist') is not None): kwargs={'pk': self.get_object().pk}))
return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.get_object().pk}))
def __add_user(self, request): def __add_user(self, request):
name = request.POST['list-new-name'] name = request.POST['new_member']
self.__add_username(request, name) self.__add_username(request, name)
return redirect(reverse_lazy("dashboard.views.group-detail", return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.object.pk})) kwargs={'pk': self.object.pk}))
...@@ -1328,9 +1328,7 @@ class GroupDetailView(CheckedDetailView): ...@@ -1328,9 +1328,7 @@ class GroupDetailView(CheckedDetailView):
messages.warning(request, _('User "%s" not found.') % name) messages.warning(request, _('User "%s" not found.') % name)
def __add_list(self, request): def __add_list(self, request):
if not self.get_has_level()(request.user, 'operator'): userlist = request.POST.get('new_members').split('\r\n')
raise PermissionDenied()
userlist = request.POST.get('list-new-namelist').split('\r\n')
for line in userlist: for line in userlist:
self.__add_username(request, line) self.__add_username(request, line)
return redirect(reverse_lazy("dashboard.views.group-detail", return redirect(reverse_lazy("dashboard.views.group-detail",
...@@ -1717,7 +1715,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView): ...@@ -1717,7 +1715,7 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
obj, self.request.user, 'dashboard.views.template-acl') obj, self.request.user, 'dashboard.views.template-acl')
context['disks'] = obj.disks.all() context['disks'] = obj.disks.all()
context['is_owner'] = obj.has_level(self.request.user, 'owner') context['is_owner'] = obj.has_level(self.request.user, 'owner')
context['aclform'] = AclUserAddForm() context['aclform'] = AclUserOrGroupAddForm()
return context return context
def get_success_url(self): def get_success_url(self):
...@@ -2768,11 +2766,30 @@ class FavouriteView(TemplateView): ...@@ -2768,11 +2766,30 @@ class FavouriteView(TemplateView):
return HttpResponse("Added.") return HttpResponse("Added.")
class TransferOwnershipView(LoginRequiredMixin, DetailView): class TransferOwnershipView(CheckedDetailView, DetailView):
model = Instance model = Instance
template_name = 'dashboard/vm-detail/tx-owner.html'
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/_modal.html']
else:
return ['dashboard/nojs-wrapper.html']
def get_context_data(self, *args, **kwargs):
context = super(TransferOwnershipView, self).get_context_data(
*args, **kwargs)
context['form'] = TransferOwnershipForm()
context.update({
'box_title': _("Transfer ownership"),
'ajax_title': True,
'template': "dashboard/vm-detail/tx-owner.html",
})
return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
form = TransferOwnershipForm(request.POST)
if not form.is_valid():
return self.get(request)
try: try:
new_owner = search_user(request.POST['name']) new_owner = search_user(request.POST['name'])
except User.DoesNotExist: except User.DoesNotExist:
......
...@@ -7,73 +7,77 @@ ...@@ -7,73 +7,77 @@
{% block content %} {% block content %}
<div class="page-header"> <div class="page-header">
<a href="{% url "network.host_delete" pk=host_pk%}" class="btn btn-danger pull-right"><i class="fa fa-times-circle"></i> {% trans "Delete this host" %}</a> <a href="{% url "network.host_delete" pk=host_pk%}" class="btn btn-danger pull-right"><i class="fa fa-times-circle"></i> {% trans "Delete this host" %}</a>
<h2>{{ form.hostname.value }}</h2> <h2>{{ form.hostname.value }}</h2>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{% crispy form %} {% crispy form %}
</div>
<div class="col-md-6">
<div class="page-header">
<a href="{% url "network.rule_create" %}?host={{ host_pk }}" class="btn btn-success pull-right btn-xs"><i class="fa fa-plus-circle"></i> {% trans "Add new rule" %}</a>
<h3>{% trans "Rules" %}</h3>
</div> </div>
<div class="col-md-6"> {% if rule_list.data.data.count > 0 %}
<div class="page-header"> {% render_table rule_list %}
<a href="{% url "network.rule_create" %}?host={{ host_pk }}" class="btn btn-success pull-right btn-xs"><i class="fa fa-plus-circle"></i> {% trans "Add new rule" %}</a> {% else %}
<h3>{% trans "Rules" %}</h3> {% trans "No rules associated with this host." %}
</div> {% endif %}
{% if rule_list.data.data.count > 0 %}
{% render_table rule_list %}
{% else %}
{% trans "No rules associated with this host!" %}
{% endif %}
<div class="page-header"> <div class="page-header">
<h3>{% trans "Groups" %}</h3> <h3>{% trans "Groups" %}</h3>
</div>
{% if group_rule_list|length > 0 %}
{% for group in group_rule_list %}
<div>
<h4 id="{{ group.pk }}_group_pk">{{ group.name }}
<a href="{% url "network.remove_host_group" pk=host_pk group_pk=group.pk %}?from={{ request.path }}">
<i class="fa fa-times" style="vertical-align: middle;"></i></a>
<a href="{% url "network.group" group.pk %}">
<i class="fa fa-pencil" style="vertical-align: middle;"></i></a>
</h4>
</div> </div>
{% if group_rule_list|length > 0 %} {% endfor %}
{% for group in group_rule_list %} {% else %}
<div> {% trans "This host is not added to any host groups!" %}
<h4 id="{{ group.pk }}_group_pk">{{ group.name }} {% endif %}
<a href="{% url "network.remove_host_group" pk=host_pk group_pk=group.pk %}?from={{ request.path }}">
<i class="fa fa-times" style="vertical-align: middle;"></i></a>
<a href="{% url "network.group" group.pk %}">
<i class="fa fa-pencil" style="vertical-align: middle;"></i></a>
</h4>
</div>
{% endfor %}
{% else %}
{% trans "This host is not added to any host groups!" %}
{% endif %}
<div class="page-header"> <div class="page-header">
<h3>{% trans "Add host group" %}</h3> <h3>{% trans "Add host group" %}</h3>
</div> </div>
{% if not_used_groups|length == 0 %} {% if not_used_groups|length == 0 %}
No more groups to add! {% trans "No more groups to add" %}
{% else %} {% else %}
<form action="{% url "network.add_host_group" pk=host_pk %}" method="POST"> <form action="{% url "network.add_host_group" pk=host_pk %}" method="POST">
{% csrf_token %} {% csrf_token %}
<div class="input-group"> <div class="input-group">
<select name="group" id="add_group" class="form-control"> <select name="group" id="add_group" class="form-control">
{% for rest in not_used_groups %} {% for rest in not_used_groups %}
<option value="{{ rest.pk }}">{{ rest }}</option> <option value="{{ rest.pk }}">{{ rest }}</option>
{% endfor %} {% endfor %}
</select> </select>
<div class="input-group-btn"> <div class="input-group-btn">
<input type="submit" value="{% trans "Add group" %}" class="btn btn-default"></input> <input type="submit" value="{% trans "Add group" %}" class="btn btn-default"></input>
</div> </div>
</div><!-- input-group --> </div><!-- input-group -->
</form> </form>
{% endif %} {% endif %}
<div class="page-header"> <div class="page-header">
<a href="{% url "network.record_create" %}?host={{ host_pk }}"
class="btn btn-xs btn-success pull-right">
<i class="fa fa-plus-circle"></i>
{% trans "Add new CNAME record" %}
</a>
<h3>{% trans "Records" %}</h3> <h3>{% trans "Records" %}</h3>
</div> </div>
{% render_table records_table %} {% render_table records_table %}
</div><!-- col-sm-5 -->
</div><!-- col-sm-5 -->
</div><!-- row --> </div><!-- row -->
{% endblock %} {% endblock %}
{% block extra_etc %} {% block extra_etc %}
<script src="{% static "js/host.js" %}"></script> <script src="{% static "js/host.js" %}"></script>
{% endblock %} {% endblock %}
...@@ -43,7 +43,7 @@ from operator import itemgetter ...@@ -43,7 +43,7 @@ from operator import itemgetter
from itertools import chain from itertools import chain
import json import json
from dashboard.views import AclUpdateView from dashboard.views import AclUpdateView
from dashboard.forms import AclUserAddForm from dashboard.forms import AclUserOrGroupAddForm
class InitialOwnerMixin(FormMixin): class InitialOwnerMixin(FormMixin):
...@@ -495,8 +495,22 @@ class RecordCreate(LoginRequiredMixin, SuperuserRequiredMixin, ...@@ -495,8 +495,22 @@ class RecordCreate(LoginRequiredMixin, SuperuserRequiredMixin,
success_message = _(u'Successfully created record!') success_message = _(u'Successfully created record!')
def get_initial(self): def get_initial(self):
initial = super(RecordCreate, self).get_initial() host_pk = self.request.GET.get("host")
initial['domain'] = self.request.GET.get('domain') try:
host = Host.objects.get(pk=host_pk)
except (Host.DoesNotExist, ValueError):
host = None
initial = {'owner': self.request.user}
if host:
initial.update({
'type': "CNAME",
'host': host,
'address': host.get_fqdn(),
})
else:
initial['domain'] = self.request.GET.get('domain')
return initial return initial
...@@ -650,7 +664,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin, ...@@ -650,7 +664,7 @@ class VlanDetail(LoginRequiredMixin, SuperuserRequiredMixin,
context['vlan_vid'] = self.kwargs.get('vid') context['vlan_vid'] = self.kwargs.get('vid')
context['acl'] = AclUpdateView.get_acl_data( context['acl'] = AclUpdateView.get_acl_data(
self.object, self.request.user, 'network.vlan-acl') self.object, self.request.user, 'network.vlan-acl')
context['aclform'] = AclUserAddForm() context['aclform'] = AclUserOrGroupAddForm()
return context return context
success_url = reverse_lazy('network.vlan_list') success_url = reverse_lazy('network.vlan_list')
......
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