Commit 4ba6d1d8 by Bach Dániel Committed by cloud

dashboard: vlan acl support for vmcreate

parent 6d44647b
...@@ -1404,5 +1404,71 @@ ...@@ -1404,5 +1404,71 @@
"network_type": "public", "network_type": "public",
"description": "" "description": ""
} }
},
{
"pk": 1,
"model": "firewall.vlan",
"fields": {
"comment": "",
"domain": 1,
"dhcp_pool": "",
"managed": true,
"name": "pub",
"vid": 1066,
"created_at": "2014-01-23T16:51:58.125Z",
"modified_at": "2014-01-23T16:51:58.125Z",
"owner": null,
"snat_ip": null,
"snat_to": [],
"network6": null,
"network4": "152.66.254.61/30",
"reverse_domain": "%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa",
"network_type": "public",
"description": ""
}
},
{
"pk": 1,
"model": "vm.lease",
"fields": {
"suspend_interval_seconds": 36000,
"name": "alap",
"delete_interval_seconds": 360000
}
},
{
"pk": 2,
"model": "vm.interfacetemplate",
"fields": {
"vlan": 1,
"managed": true,
"template": 1
}
},
{
"pk": 1,
"model": "vm.instancetemplate",
"fields": {
"req_traits": [],
"disks": [
1
],
"name": "ubuntu",
"parent": null,
"created": "2014-01-23T18:03:52.319Z",
"num_cores": 2,
"description": "",
"boot_menu": false,
"ram_size": 1024,
"modified": "2014-01-24T00:58:19.654Z",
"system": "",
"priority": 20,
"state": "READY",
"access_method": "ssh",
"raw_data": "",
"arch": "x86_64",
"max_ram_size": 1024,
"lease": 1
}
} }
] ]
...@@ -32,9 +32,7 @@ class VmCreateForm(forms.Form): ...@@ -32,9 +32,7 @@ class VmCreateForm(forms.Form):
required=False required=False
) )
managed_networks = forms.ModelMultipleChoiceField( networks = forms.ModelMultipleChoiceField(
queryset=VLANS, required=False)
unmanaged_networks = forms.ModelMultipleChoiceField(
queryset=VLANS, required=False) queryset=VLANS, required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -208,24 +206,11 @@ class VmCreateForm(forms.Form): ...@@ -208,24 +206,11 @@ class VmCreateForm(forms.Form):
), ),
Div( Div(
Div( # js-hidden Div( # js-hidden
AnyTag(
"h4",
HTML(_("Managed networks")),
),
Field( Field(
"managed_networks", "networks",
css_class="form-control", css_class="form-control",
id="vm-create-network-add-managed", id="vm-create-network-add-managed",
), ),
AnyTag(
"h4",
HTML(_("Unmanaged networks")),
),
Field(
"unmanaged_networks",
css_class="form-control",
id="vm-create-network-add-unmanaged",
),
css_class="js-hidden", css_class="js-hidden",
style="padding-top: 15px; max-width: 450px;", style="padding-top: 15px; max-width: 450px;",
), ),
...@@ -243,24 +228,6 @@ class VmCreateForm(forms.Form): ...@@ -243,24 +228,6 @@ class VmCreateForm(forms.Form):
css_class="form-control", css_class="form-control",
css_id="vm-create-network-add-select", css_id="vm-create-network-add-select",
), ),
AnyTag(
"span",
WorkingBaseInput(
"",
"",
css_id=(
"vm-create-network-add"
"-checkbox-managed"
),
input_type="checkbox",
title="",
data_original_title=(
_("Managed network?")
),
checked="checked",
),
css_class="input-group-addon",
),
Div( Div(
AnyTag( AnyTag(
"a", "a",
...@@ -455,9 +422,7 @@ class NodeForm(forms.ModelForm): ...@@ -455,9 +422,7 @@ class NodeForm(forms.ModelForm):
class TemplateForm(forms.ModelForm): class TemplateForm(forms.ModelForm):
managed_networks = forms.ModelMultipleChoiceField( networks = forms.ModelMultipleChoiceField(
queryset=VLANS, required=False)
unmanaged_networks = forms.ModelMultipleChoiceField(
queryset=VLANS, required=False) queryset=VLANS, required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -482,12 +447,8 @@ class TemplateForm(forms.ModelForm): ...@@ -482,12 +447,8 @@ class TemplateForm(forms.ModelForm):
self.for_networks = self.instance self.for_networks = self.instance
if self.instance.pk or parent is not None: if self.instance.pk or parent is not None:
mn = self.for_networks.interface_set.filter( n = self.for_networks.interface_set.values_list("vlan", flat=True)
managed=True).values_list("vlan", flat=True) self.initial['networks'] = n
un = self.for_networks.interface_set.filter(
managed=False).values_list("vlan", flat=True)
self.initial['managed_networks'] = mn
self.initial['unmanaged_networks'] = un
if not self.instance.pk and len(self.errors) < 1: if not self.instance.pk and len(self.errors) < 1:
self.instance.priority = 20 self.instance.priority = 20
...@@ -505,27 +466,16 @@ class TemplateForm(forms.ModelForm): ...@@ -505,27 +466,16 @@ class TemplateForm(forms.ModelForm):
self.instance.disks = data['disks'] # TODO why do I need this self.instance.disks = data['disks'] # TODO why do I need this
# create and/or delete InterfaceTemplates # create and/or delete InterfaceTemplates
managed = InterfaceTemplate.objects.filter( networks = InterfaceTemplate.objects.filter(
managed=True, template=self.instance).values_list("vlan", template=self.instance).values_list("vlan", flat=True)
flat=True) for m in data['networks']:
unmanaged = InterfaceTemplate.objects.filter( if m.pk not in networks:
managed=False, template=self.instance).values_list("vlan", InterfaceTemplate(vlan=m, managed=m.managed,
flat=True)
for m in data['managed_networks']:
if m.pk not in managed:
InterfaceTemplate(vlan=m, managed=True,
template=self.instance).save() template=self.instance).save()
InterfaceTemplate.objects.filter( InterfaceTemplate.objects.filter(
managed=True, template=self.instance).exclude( template=self.instance).exclude(
vlan__in=data['managed_networks']).delete() vlan__in=data['networks']).delete()
for u in data['unmanaged_networks']:
if u.pk not in unmanaged:
InterfaceTemplate(vlan=u, managed=False,
template=self.instance).save()
InterfaceTemplate.objects.filter(
managed=False, template=self.instance).exclude(
vlan__in=data['unmanaged_networks']).delete()
return instance return instance
@property @property
...@@ -591,8 +541,7 @@ class TemplateForm(forms.ModelForm): ...@@ -591,8 +541,7 @@ class TemplateForm(forms.ModelForm):
Fieldset( Fieldset(
_("Exeternal"), _("Exeternal"),
Field("disks"), Field("disks"),
Field("managed_networks"), Field("networks"),
Field("unmanaged_networks"),
Field("lease"), Field("lease"),
Field("tags"), Field("tags"),
), ),
......
...@@ -125,9 +125,6 @@ ...@@ -125,9 +125,6 @@
<option value="{{ v.pk }}">{{ v.name }}</option> <option value="{{ v.pk }}">{{ v.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
<span class="input-group-addon">
<input type="checkbox" name="new_network_managed" checked="checked" title="{% trans "Managed network?" %}">
</span>
<div class="input-group-btn"> <div class="input-group-btn">
<button type="submit" class="btn btn-success"><i class="icon-plus-sign"></i></button> <button type="submit" class="btn btn-success"><i class="icon-plus-sign"></i></button>
</div> </div>
......
...@@ -132,3 +132,12 @@ class VmDetailTest(TestCase): ...@@ -132,3 +132,12 @@ class VmDetailTest(TestCase):
{'new_network_vlan': 1, 'managed': 'on'}) {'new_network_vlan': 1, 'managed': 'on'})
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(inst.interface_set.count(), interface_count + 1) self.assertEqual(inst.interface_set.count(), interface_count + 1)
def test_create_vm_w_unpermitted_network(self):
c = Client()
self.login(c, 'user1')
response = c.post('/dashboard/vm/create/',
{'template': 1,
'cpu_priority': 1, 'cpu_count': 1,
'ram_size': 1000})
self.assertEqual(response.status_code, 403)
...@@ -141,7 +141,8 @@ class VmDetailView(CheckedDetailView): ...@@ -141,7 +141,8 @@ class VmDetailView(CheckedDetailView):
).order_by('-started').select_related() ).order_by('-started').select_related()
context['activity'] = ia context['activity'] = ia
context['vlans'] = Vlan.objects.all() # TODO acl context['vlans'] = Vlan.get_objects_with_level(
'user', self.request.user).all()
context['acl'] = get_acl_data(instance) context['acl'] = get_acl_data(instance)
return context return context
...@@ -297,11 +298,11 @@ class VmDetailView(CheckedDetailView): ...@@ -297,11 +298,11 @@ class VmDetailView(CheckedDetailView):
raise PermissionDenied() raise PermissionDenied()
vlan = Vlan.objects.get(pk=request.POST.get("new_network_vlan")) vlan = Vlan.objects.get(pk=request.POST.get("new_network_vlan"))
managed = request.POST.get("new_network_managed") if not vlan.has_level(request.user, 'user'):
managed = False if managed is None else True raise PermissionDenied()
try: try:
Interface.create(vlan=vlan, instance=self.object, Interface.create(vlan=vlan, instance=self.object,
managed=managed, owner=request.user) managed=vlan.managed, owner=request.user)
messages.success(request, _("Successfully added new interface!")) messages.success(request, _("Successfully added new interface!"))
except Exception, e: except Exception, e:
error = u' '.join(e.messages) error = u' '.join(e.messages)
...@@ -544,13 +545,13 @@ class VmCreate(LoginRequiredMixin, TemplateView): ...@@ -544,13 +545,13 @@ class VmCreate(LoginRequiredMixin, TemplateView):
def get(self, request, form=None, *args, **kwargs): def get(self, request, form=None, *args, **kwargs):
if form is None: if form is None:
form = self.form_class() form = self.form_class()
form.fields['disks'].queryset = Disk.objects.all()
form.fields['networks'].queryset = Vlan.get_objects_with_level(
'user', request.user)
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
context.update({ context.update({
'template': 'dashboard/vm-create.html', 'template': 'dashboard/vm-create.html',
'box_title': 'Create a VM', 'box_title': 'Create a VM',
'templates': InstanceTemplate.objects.all(),
'vlans': Vlan.objects.all(),
'disks': Disk.objects.exclude(type="qcow2-snap"),
'vm_create_form': form, 'vm_create_form': form,
}) })
return self.render_to_response(context) return self.render_to_response(context)
...@@ -578,12 +579,8 @@ class VmCreate(LoginRequiredMixin, TemplateView): ...@@ -578,12 +579,8 @@ class VmCreate(LoginRequiredMixin, TemplateView):
'ram_size': post['ram_size'], 'ram_size': post['ram_size'],
'priority': post['cpu_priority'], 'priority': post['cpu_priority'],
} }
networks = [InterfaceTemplate(vlan=l, managed=l.managed)
networks = ( for l in post['networks']]
[InterfaceTemplate(vlan=l, managed=True)
for l in post['managed_networks']] +
[InterfaceTemplate(vlan=l, managed=False)
for l in post['unmanaged_networks']])
disks = post['disks'] disks = post['disks']
inst = Instance.create_from_template( inst = Instance.create_from_template(
template=template, owner=user, networks=networks, template=template, owner=user, networks=networks,
......
...@@ -24,6 +24,7 @@ from .activity import instance_activity ...@@ -24,6 +24,7 @@ from .activity import instance_activity
from .common import BaseResourceConfigModel, Lease from .common import BaseResourceConfigModel, Lease
from .network import Interface from .network import Interface
from .node import Node, Trait from .node import Node, Trait
from django.core.exceptions import PermissionDenied
logger = getLogger(__name__) logger = getLogger(__name__)
pre_state_changed = Signal(providing_args=["new_state"]) pre_state_changed = Signal(providing_args=["new_state"])
...@@ -260,6 +261,10 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -260,6 +261,10 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
networks = (template.interface_set.all() if networks is None networks = (template.interface_set.all() if networks is None
else networks) else networks)
for network in networks:
if not network.vlan.has_level(owner, 'user'):
raise PermissionDenied()
req_traits = (template.req_traits.all() if req_traits is None req_traits = (template.req_traits.all() if req_traits is None
else req_traits) else req_traits)
......
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