Commit 2c453601 by Szabolcs Gelencser

Implement network operations base, delete network operation

parent 27b5943c
......@@ -384,3 +384,10 @@ class VxlanForm(forms.Form):
isAdvancedConfig = forms.BooleanField(required=False, label="Advanced")
#TODO: validate
class NetworkDeleteForm(forms.Form):
@property
def helper(self):
helper = super(NetworkDeleteForm, self).helper
helper.layout = Layout()
return helper
......@@ -30,7 +30,7 @@ from django.contrib.contenttypes.models import ContentType
from firewall.models import Vlan
from firewall.fields import val_alfanum
from openstack_auth.user import User
from network import operations
class EditorElement(models.Model):
x = models.IntegerField()
......
import openstack_api
from common.models import humanize_exception
from common.operations import Operation, register_operation
from django.core.exceptions import PermissionDenied
from django.utils.translation import ugettext_noop
from openstack_api.neutron import Network
from django.utils.translation import ugettext_lazy as _
class NetworkOperation(Operation):
host_cls = Network
os_policy_actions = None
def __init__(self, instance):
super(NetworkOperation, self).__init__(subject=instance)
self.instance = instance
def check_precond(self):
pass
def check_auth(self, user, request):
if self.os_policy_actions:
from django.utils.module_loading import import_string
check = import_string("openstack_auth.policy.check")
has_rights = check(self.os_policy_actions, request,
{'project_id': self.instance.tenant_id})
if not has_rights:
raise humanize_exception(ugettext_noop(
"operation not permitted"),
PermissionDenied())
super(NetworkOperation, self).check_auth(user=user)
def is_preferred(self):
"""If this is the recommended op in the current state of the instance.
"""
return False
@register_operation
class DeleteNetworkOperation(NetworkOperation):
id = 'delete_network'
name = _("delete network")
description = _("Delete network and all associated resources.")
os_policy_actions = (
("network", "network:delete"),
)
#TODO: remove attached interfaces, delete ports and assigned floating ips
def _operation(self, request):
ports = openstack_api.neutron.port_list(request, network=self.instance.id)
network_ports = [p for p in ports if p.network_id == self.instance.id]
for p in network_ports:
if p.device_owner == "network:router_interface":
openstack_api.neutron.router_remove_interface(request, p.device_id, port_id=p.id)
if p.device_owner == "compute:nova":
openstack_api.neutron.port_delete(request, p.id)
# openstack_api.neutron.port_delete(request, p.id)
openstack_api.neutron.network_delete(request, self.instance.id)
......@@ -28,8 +28,15 @@
<div class="page-header">
<a href="{% url "network.vxlan-delete" pk=network.id %}" class="btn btn-danger pull-right"><i class="fa fa-times-circle"></i> {% trans "Delete this network" %}</a>
<h2>{{ form.name.value }}</h2>
{% with op=op.delete_network %}{% if op %}
<span class="operation-wrapper pull-right">
<a href="{% url "network.vxlan-delete" pk=network.id %}"
class="btn btn-{{ op.effect }} operation"
{% if op.disabled %}disabled{% endif %}>{% trans "Delete this network" %}
</a>
</span>
{% endif %}{% endwith %}
<h2>{{ form.name.value }}</h2>
</div>
<div class="row">
......@@ -41,6 +48,7 @@
</div>
<div class="col-sm-6">
<h3 class="pull-right"><small>{% trans "connected virtual machines" %}</small></h3>
</div>
</div>
{% endblock %}
......@@ -24,7 +24,7 @@ from operator import itemgetter
import openstack_api
from braces.views import LoginRequiredMixin, SuperuserRequiredMixin
from dashboard.forms import AclUserOrGroupAddForm
from dashboard.views import AclUpdateView, FormView
from dashboard.views import AclUpdateView, FormView, OperationView, PermissionDenied
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import (
......@@ -47,12 +47,13 @@ from firewall.models import (
)
from netaddr import IPNetwork
from network.models import Vxlan, EditorElement, SubnetPool
from openstack_api.neutron import Network
from openstack_api.utils.lazy_encoder import LazyTranslationEncoder
from vm.models import Interface, Instance
from .forms import (
HostForm, VlanForm, DomainForm, GroupForm, RecordForm, BlacklistItemForm,
RuleForm, VlanGroupForm, SwitchPortForm, FirewallForm, VxlanForm)
RuleForm, VlanGroupForm, SwitchPortForm, FirewallForm, VxlanForm, NetworkDeleteForm)
from .tables import (
HostTable, VlanTable, SmallHostTable, DomainTable, GroupTable,
RecordTable, BlacklistItemTable, RuleTable, VlanGroupTable,
......@@ -89,6 +90,47 @@ class MagicMixin(object):
else:
return super(MagicMixin, self).get(*args, **kwargs)
class VxlanDelete(LoginRequiredMixin, OperationView): #TODO: check user
model = Network
op = 'delete_network'
effect = 'danger'
# form_class = NetworkDeleteForm
def get_success_url(self):
next = self.request.POST.get('next')
if next:
return next
else:
return reverse_lazy('network.vxlan-list')
def get_object(self, queryset=None):
return openstack_api.neutron.network_get(self.request, self.kwargs['pk'], expand_subnet=True)
def delete(self, request, *args, **kwargs):
response = super(VxlanDelete, self).delete(request, *args, **kwargs)
messages.success(request, _(u"Vxlan successfully deleted."))
return response
network_ops = OrderedDict([
('network_delete', VxlanDelete),
])
def get_operations(instance, user, request):
ops = []
for k, v in network_ops.iteritems():
try:
op = v.get_op_by_object(instance)
op.check_auth(user, request)
op.check_precond()
except PermissionDenied as e:
logger.debug('Not showing operation %s for %s: %s',
k, instance, unicode(e))
except Exception as e:
ops.append(v.bind_to_object(instance, disabled=True))
else:
ops.append(v.bind_to_object(instance))
return ops
class IndexView(LoginRequiredMixin, SuperuserRequiredMixin, TemplateView):
template_name = "network/index.html"
......@@ -978,6 +1020,7 @@ class VxlanDetail(LoginRequiredMixin, SuccessMessageMixin, DetailView): #TODO: c
def get_context_data(self, **kwargs):
context = super(VxlanDetail, self).get_context_data(**kwargs)
ops = get_operations(self.object, self.request.user, self.request)
subnet = self.object.subnets[0] if len(self.object.subnets) > 0 else None
......@@ -991,6 +1034,7 @@ class VxlanDetail(LoginRequiredMixin, SuccessMessageMixin, DetailView): #TODO: c
context['isSubnetMissing'] = len(self.object.subnets) < 1
context['vm_list'] = () #SmallVmTable(self.object.vm_interface.all())
context['form'] = form
context['op'] = {i.op: i for i in ops}
return context
class VxlanCreate(LoginRequiredMixin, FormView):
......@@ -1023,44 +1067,6 @@ class VxlanCreate(LoginRequiredMixin, FormView):
return redirect(reverse_lazy('network.vxlan', kwargs={'pk': network_created.id}))
class VxlanDelete(LoginRequiredMixin, DeleteView): #TODO: check user
model = Vlan
read_level = 'owner'
def get_template_names(self):
if self.request.user.is_superuser:
return ["network/confirm/base_delete.html"]
else:
return ["dashboard/confirm/base-delete.html"]
def get_success_url(self):
next = self.request.POST.get('next')
if next:
return next
else:
return reverse_lazy('network.vxlan-list')
def get_object(self, queryset=None):
""" we identify vlans by vid and not pk """
return Vxlan.objects.get(vni=self.kwargs['vni'])
def delete(self, request, *args, **kwargs):
if self.request.user.is_superuser:
self.object = self.get_object()
if unicode(self.object) != request.POST.get('confirm'):
messages.error(request, _(u"Object name does not match."))
return self.get(request, *args, **kwargs)
response = super(VxlanDelete, self).delete(request, *args, **kwargs)
messages.success(request, _(u"Vxlan successfully deleted."))
return response
def get_context_data(self, **kwargs):
context = super(VxlanDelete, self).get_context_data(**kwargs)
if self.request.user.is_superuser:
context['confirmation'] = True
return context
class TopologyBaseTab():
def get_context_data(request, context=None):
"""Returns common context data for network topology views."""
......
......@@ -105,6 +105,9 @@ class Agent(NeutronAPIDictWrapper):
class Network(NeutronAPIDictWrapper):
"""Wrapper for neutron Networks."""
def __repr__(self):
return self.name
class Subnet(NeutronAPIDictWrapper):
"""Wrapper for neutron subnets."""
......
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