From 3f1acf09ef3f29d8c0cfa565d0cd069d890cfa65 Mon Sep 17 00:00:00 2001 From: catborise Date: Fri, 21 Sep 2018 16:50:44 +0300 Subject: [PATCH 01/14] Add NWFilters --- computes/templates/overview.html | 3 + interfaces/templates/interface.html | 3 + interfaces/templates/interfaces.html | 3 + networks/templates/network.html | 3 + networks/templates/networks.html | 3 + nwfilters/__init__.py | 0 nwfilters/admin.py | 6 + nwfilters/apps.py | 8 + nwfilters/migrations/__init__.py | 0 nwfilters/models.py | 6 + .../templates/create_nwfilter_block.html | 32 +++ nwfilters/templates/nwfilter.html | 220 ++++++++++++++++++ nwfilters/templates/nwfilters.html | 168 +++++++++++++ nwfilters/tests.py | 6 + nwfilters/views.py | 183 +++++++++++++++ secrets/templates/secrets.html | 3 + storages/templates/storage.html | 3 + storages/templates/storages.html | 3 + vrtManager/connection.py | 10 +- vrtManager/instance.py | 3 +- vrtManager/nwfilters.py | 125 ++++++++++ webvirtcloud/urls.py | 4 + 22 files changed, 792 insertions(+), 3 deletions(-) create mode 100644 nwfilters/__init__.py create mode 100644 nwfilters/admin.py create mode 100644 nwfilters/apps.py create mode 100644 nwfilters/migrations/__init__.py create mode 100644 nwfilters/models.py create mode 100644 nwfilters/templates/create_nwfilter_block.html create mode 100644 nwfilters/templates/nwfilter.html create mode 100644 nwfilters/templates/nwfilters.html create mode 100644 nwfilters/tests.py create mode 100644 nwfilters/views.py create mode 100644 vrtManager/nwfilters.py diff --git a/computes/templates/overview.html b/computes/templates/overview.html index 34e68c5..89251cc 100644 --- a/computes/templates/overview.html +++ b/computes/templates/overview.html @@ -20,6 +20,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/interfaces/templates/interface.html b/interfaces/templates/interface.html index c55750d..014a44e 100644 --- a/interfaces/templates/interface.html +++ b/interfaces/templates/interface.html @@ -19,6 +19,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/interfaces/templates/interfaces.html b/interfaces/templates/interfaces.html index 42d4456..58d4978 100644 --- a/interfaces/templates/interfaces.html +++ b/interfaces/templates/interfaces.html @@ -21,6 +21,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/networks/templates/network.html b/networks/templates/network.html index 7d922b1..e3b0275 100644 --- a/networks/templates/network.html +++ b/networks/templates/network.html @@ -19,6 +19,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/networks/templates/networks.html b/networks/templates/networks.html index 36322e2..2acc1f3 100644 --- a/networks/templates/networks.html +++ b/networks/templates/networks.html @@ -20,6 +20,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/nwfilters/__init__.py b/nwfilters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nwfilters/admin.py b/nwfilters/admin.py new file mode 100644 index 0000000..13be29d --- /dev/null +++ b/nwfilters/admin.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib import admin + +# Register your models here. diff --git a/nwfilters/apps.py b/nwfilters/apps.py new file mode 100644 index 0000000..11475c5 --- /dev/null +++ b/nwfilters/apps.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class NwfiltersConfig(AppConfig): + name = 'nwfilters' diff --git a/nwfilters/migrations/__init__.py b/nwfilters/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nwfilters/models.py b/nwfilters/models.py new file mode 100644 index 0000000..1dfab76 --- /dev/null +++ b/nwfilters/models.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models + +# Create your models here. diff --git a/nwfilters/templates/create_nwfilter_block.html b/nwfilters/templates/create_nwfilter_block.html new file mode 100644 index 0000000..01056ab --- /dev/null +++ b/nwfilters/templates/create_nwfilter_block.html @@ -0,0 +1,32 @@ +{% load i18n %} +{% if request.user.is_superuser %} + + + + + + +{% endif %} diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html new file mode 100644 index 0000000..1f7c7b0 --- /dev/null +++ b/nwfilters/templates/nwfilter.html @@ -0,0 +1,220 @@ +{% extends "base.html" %} +{% load i18n %} +{% load staticfiles %} +{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %} +{% block content %} + +
    +
    + {% include 'create_nwfilter_block.html' %} +

    {% trans "NWFilter:" %} {{ name }}

    + +
    +
    + + + {% include 'errors_block.html' %} + {% include 'messages_block.html' %} + +
    +
    +

    {% trans "UUID:" %}

    +

    {% trans "Name:" %}

    +
    + +
    +

    {{ uuid }}

    +

    {{ name }}

    +
    + +
    +
    +

    {% trans "XML:" %}

    +
    {% csrf_token %} +
    + + +
    + +
    +
    +
    +

    {% trans "Filter References:" %}

    +
    {% csrf_token %} +
    + + + + +
    +
    + +
    +
    +
    + + + + + + + + + + {% for ref in refs %} + + + + + + {% endfor %} + +
    #{% trans "Reference" %}{% trans "Action" %}
    {{ forloop.counter }}{{ ref }} +
    {% csrf_token %} + + +
    +
    +
    +
    +
    +

    {% trans "Rules:" %}

    + + + + + + +
    +
    +
    + + + + + + + + + + + + + + {% for rule in rules %} + + + + + + + + + + {% endfor %} + +
    {% trans "Rule" %}{% trans "ActionType" %}{% trans "Direction" %}{% trans "Priority" %}{% trans "Statematch" %}{% trans "Directives" %}{% trans "Action" %}
    {{ forloop.counter }}{{ rule.action }}{{ rule.direction }}{{ rule.priority }}{{ rule.statematch }}{{ rule.directives }} +
    {% csrf_token %} + + + + +
    +
    +
    +
    + + +{% endblock %} + +{% block script %} + + + + + +{% endblock %} diff --git a/nwfilters/templates/nwfilters.html b/nwfilters/templates/nwfilters.html new file mode 100644 index 0000000..e237380 --- /dev/null +++ b/nwfilters/templates/nwfilters.html @@ -0,0 +1,168 @@ +{% extends "base.html" %} +{% load i18n %} +{% load staticfiles %} +{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %} +{% block content %} + +
    +
    + {% include 'create_nwfilter_block.html' %} +

    {{ compute.name }}

    + +
    +
    + + +{% include 'errors_block.html' %} +{% include 'messages_block.html' %} + +
    +
    +
    +
    + +
    + + +
    + {% if nwfilters %} +
    + + + + + + + + + + + {% for nwfilter in nwfilters %} + + + + + + + + + {% endfor %} + +
    #{% trans "UUID" %}{% trans "Name" %}{% trans "Action" %}
    {{ forloop.counter }}{{ nwfilter.uuid }}{{ nwfilter.name }} + + + + + + +
    {% csrf_token %} + + +
    +
    +
    + {% else %} +
    +
    + + {% trans "Warning:" %} {% trans "Hypervisor doesn't have any NWFilters" %} +
    +
    + {% endif %} +
    +
    +{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} diff --git a/nwfilters/tests.py b/nwfilters/tests.py new file mode 100644 index 0000000..5982e6b --- /dev/null +++ b/nwfilters/tests.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.test import TestCase + +# Create your tests here. diff --git a/nwfilters/views.py b/nwfilters/views.py new file mode 100644 index 0000000..5fa39f5 --- /dev/null +++ b/nwfilters/views.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.shortcuts import render +from django.http import HttpResponseRedirect +from django.shortcuts import render, get_object_or_404 +from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse +from django.contrib.auth.decorators import login_required +from computes.models import Compute +from vrtManager import util +from vrtManager.nwfilters import wvmNWFilters, wvmNWFilter +from libvirt import libvirtError + + +@login_required +def nwfilters(request, compute_id): + """ + :param request: + :return: + """ + + if not request.user.is_superuser: + return HttpResponseRedirect(reverse('index')) + + error_messages = [] + nwfilters_all = [] + compute = get_object_or_404(Compute, pk=compute_id) + + try: + conn = wvmNWFilters(compute.hostname, + compute.login, + compute.password, + compute.type) + + for nwf in conn.get_nwfilters(): + nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + + if request.method == 'POST': + if 'create_nwfilter' in request.POST: + xml = request.POST.get('nwfilter_xml', '') + if xml: + try: + util.etree.fromstring(xml) + name = util.get_xml_path(xml, '/filter/@name') + uuid = util.get_xml_path(xml, '/filter/uuid') + except util.etree.ParseError: + name = None + + for nwf in nwfilters: + if name == nwf.name(): + error_msg = _("A network filter with this name already exists") + raise Exception(error_msg) + if uuid == nwf.UUIDString(): + error_msg = _("A network filter with this uuid already exists") + raise Exception(error_msg) + else: + try: + conn.create_nwfilter(xml) + return HttpResponseRedirect(request.get_full_path()) + except libvirtError as lib_err: + error_messages.append(lib_err.message) + if 'del_nwfilter' in request.POST: + name = request.POST.get('nwfiltername','') + nwfilter = conn.get_nwfilter(name) + if nwfilter: + nwfilter.undefine() + return HttpResponseRedirect(request.get_full_path()) + + if 'cln_nwfilter' in request.POST: + name = request.POST.get('nwfiltername','') + cln_name = request.POST.get('cln_name', name + '-clone') + + conn.clone_nwfilter(name,cln_name) + return HttpResponseRedirect(request.get_full_path()) + + conn.close() + except libvirtError as lib_err: + error_messages.append(lib_err) + except Exception as err: + error_messages.append(err) + + return render(request, 'nwfilters.html', {'error_messages': error_messages, + 'nwfilters': nwfilters_all, + 'compute': compute}) + + +@login_required +def nwfilter(request, compute_id, nwfltr): + + error_messages = [] + nwfilters_all = [] + compute = get_object_or_404(Compute, pk=compute_id) + + try: + nwfilter = wvmNWFilter(compute.hostname, + compute.login, + compute.password, + compute.type, + nwfltr) + conn = wvmNWFilters(compute.hostname, + compute.login, + compute.password, + compute.type) + + for nwf in conn.get_nwfilters(): + nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + + uuid = nwfilter.get_uuid() + name = nwfilter.get_name() + xml = nwfilter.get_xml() + rules = nwfilter.get_rules() + refs = nwfilter.get_filter_refs() + + if request.method == 'POST': + + if 'edit_nwfilter' in request.POST: + new_xml = request.POST.get('edit_xml', '') + + if new_xml: + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'del_nwfilter_rule' in request.POST: + action = request.POST.get('action', '') + direction = request.POST.get('direction', '') + priority = request.POST.get('priority', '') + + new_xml = nwfilter.delete_rule(action, direction, priority) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'del_nwfilter_ref' in request.POST: + ref_name = request.POST.get('ref') + new_xml = nwfilter.delete_ref(ref_name) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'add_nwfilter_rule' in request.POST: + rule_xml = request.POST.get('nwfilterrule_xml', '') + if not rule_xml: + return HttpResponseRedirect(request.get_full_path()) + new_xml = nwfilter.add_rule(rule_xml) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'add_nwfilter_ref' in request.POST: + ref_name = request.POST.get('nwfilters_select', '') + if not ref_name: + return HttpResponseRedirect(request.get_full_path()) + new_xml = nwfilter.add_ref(ref_name) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + return HttpResponseRedirect(request.get_full_path()) + conn.close() + nwfilter.close() + except libvirtError as lib_err: + error_messages.append(lib_err) + except Exception as error_msg: + error_messages.append(error_msg) + + return render(request, 'nwfilter.html', locals()) \ No newline at end of file diff --git a/secrets/templates/secrets.html b/secrets/templates/secrets.html index 8286bfb..07b104a 100644 --- a/secrets/templates/secrets.html +++ b/secrets/templates/secrets.html @@ -24,6 +24,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/storages/templates/storage.html b/storages/templates/storage.html index ecc9adc..4d3c706 100644 --- a/storages/templates/storage.html +++ b/storages/templates/storage.html @@ -25,6 +25,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/storages/templates/storages.html b/storages/templates/storages.html index 21bca90..026fe13 100644 --- a/storages/templates/storages.html +++ b/storages/templates/storages.html @@ -20,6 +20,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 65c2915..96a4fbf 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -389,6 +389,12 @@ class wvmConnect(object): interface.append(inface) return interface + def get_nwfilters(self): + nwfilters = [] + for nwfilter in self.wvm.listAllNWFilters(): + nwfilters.append(nwfilter) + return nwfilters + def get_cache_modes(self): """Get cache available modes""" return { @@ -443,7 +449,6 @@ class wvmConnect(object): def get_video(self): """ Get available graphics video types """ - def get_video_list(ctx): result = [] for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'): @@ -470,6 +475,9 @@ class wvmConnect(object): def get_network(self, net): return self.wvm.networkLookupByName(net) + def get_nwfilter(self, name): + return self.wvm.nwfilterLookupByName(name) + def get_instance(self, name): return self.wvm.lookupByName(name) diff --git a/vrtManager/instance.py b/vrtManager/instance.py index b27baa0..d63d36c 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -487,8 +487,7 @@ class wvmInstance(wvmConnect): return self._defineXML(newxml) def get_console_socket(self): - socket = util.get_xml_path(self._XMLDesc(0), - "/domain/devices/graphics/@socket") + socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket") return socket def get_console_type(self): diff --git a/vrtManager/nwfilters.py b/vrtManager/nwfilters.py new file mode 100644 index 0000000..58784b9 --- /dev/null +++ b/vrtManager/nwfilters.py @@ -0,0 +1,125 @@ +from vrtManager.connection import wvmConnect +from xml.etree import ElementTree + + +class wvmNWFilters(wvmConnect): + def get_nwfilter_info(self, name): + nwfilter = self.get_nwfilter(name) + xml = nwfilter.XMLDesc(0) + uuid = nwfilter.UUIDString() + return {'name': name, 'uuid': uuid, 'xml': xml} + + def create_nwfilter(self, xml): + self.wvm.nwfilterDefineXML(xml) + + def clone_nwfilter(self,name, cln_name): + nwfilter = self.get_nwfilter(name) + if nwfilter: + tree = ElementTree.fromstring(nwfilter.XMLDesc(0)) + tree.set('name', cln_name) + uuid = tree.find('uuid') + tree.remove(uuid) + self.create_nwfilter(ElementTree.tostring(tree)) + + +class wvmNWFilter(wvmConnect): + def __init__(self, host, login, passwd, conn, nwfiltername): + wvmConnect.__init__(self, host, login, passwd, conn) + self.nwfilter = self.get_nwfilter(nwfiltername) + + def _XMLDesc(self, flags): + return self.nwfilter.XMLDesc(flags) + + def get_uuid(self): + return self.nwfilter.UUIDString() + + def get_name(self): + return self.nwfilter.name() + + def delete(self): + self.nwfilter.undefine() + + def get_xml(self): + tree = ElementTree.fromstring(self._XMLDesc(0)) + uuid = tree.find('uuid') + tree.remove(uuid) + return ElementTree.tostring(tree) + + def get_filter_refs(self): + refs = [] + tree = ElementTree.fromstring(self._XMLDesc(0)) + for ref in tree.findall("./filterref"): + refs.append(ref.get('filter')) + return refs + + def get_rules(self): + rules = [] + + tree = ElementTree.fromstring(self._XMLDesc(0)) + for r in tree.findall("./rule"): + rule_action = r.get('action') + rule_direction = r.get('direction') + rule_priority = r.get('priority') + rule_statematch = r.get('statematch') + + rule_directives = r.find("./") + if rule_directives is not None: + rule_directives = ElementTree.tostring(rule_directives) + + rule_info = { + "action": rule_action, + "direction": rule_direction, + "priority": rule_priority, + "statematch": rule_statematch, + "directives": rule_directives + } + + rules.append(rule_info) + + return rules + + def delete_ref(self, name): + tree = ElementTree.fromstring(self._XMLDesc(0)) + for ref in tree.findall("./filterref"): + if name == ref.get('filter'): + tree.remove(ref) + break + return ElementTree.tostring(tree) + + def delete_rule(self, action, direction, priority): + tree = ElementTree.fromstring(self._XMLDesc(0)) + + rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (action, direction, priority)) + if rule_tree: + tree.remove(rule_tree[0]) + + return ElementTree.tostring(tree) + + def add_ref(self, name): + tree = ElementTree.fromstring(self._XMLDesc(0)) + element = ElementTree.Element("filterref") + element.attrib['filter'] = name + tree.append(element) + return ElementTree.tostring(tree) + + def add_rule(self, xml): + tree = ElementTree.fromstring(self._XMLDesc(0)) + rule = ElementTree.fromstring(xml) + + rule_action = rule.get('action') + rule_direction = rule.get('direction') + rule_priority = rule.get('priority') + rule_directives = rule.find("./") + rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (rule_action, rule_direction, rule_priority)) + + if rule_tree: + rule_tree[0].append(rule_directives) + else: + element = ElementTree.Element("rule") + element.attrib['action'] = rule_action + element.attrib['direction'] = rule_direction + element.attrib['priority'] = rule_priority + element.append(rule_directives) + tree.append(element) + + return ElementTree.tostring(tree) diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py index d169386..79992af 100644 --- a/webvirtcloud/urls.py +++ b/webvirtcloud/urls.py @@ -7,6 +7,7 @@ from secrets.views import secrets from create.views import create_instance from interfaces.views import interfaces, interface from console.views import console +from nwfilters.views import nwfilters, nwfilter # from django.contrib import admin urlpatterns = [ @@ -25,9 +26,12 @@ urlpatterns = [ url(r'^compute/(?P[0-9]+)/network/(?P[\w\-\.]+)/$', network, name='network'), url(r'^compute/(?P[0-9]+)/interfaces/$', interfaces, name='interfaces'), url(r'^compute/(?P[0-9]+)/interface/(?P[\w\-\.\:]+)/$', interface, name='interface'), + url(r'^compute/(?P[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'), + url(r'^compute/(?P[0-9]+)/nwfilter/(?P[\w\-\.\:]+)/$', nwfilter, name='nwfilter'), url(r'^compute/(?P[0-9]+)/secrets/$', secrets, name='secrets'), url(r'^compute/(?P[0-9]+)/create/$', create_instance, name='create_instance'), + url(r'^console/$', console, name='console'), # (r'^admin/', include(admin.site.urls)), ] From 1802ad0413df2a009ba7bd23c78223fa726bcdd8 Mon Sep 17 00:00:00 2001 From: catborise Date: Fri, 21 Sep 2018 18:46:33 +0300 Subject: [PATCH 02/14] Check usage of filter refs from domains. --- nwfilters/templates/nwfilter.html | 2 +- nwfilters/views.py | 42 +++++++++++++++++++++++++------ vrtManager/instance.py | 13 ++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html index 1f7c7b0..0d2e2f1 100644 --- a/nwfilters/templates/nwfilter.html +++ b/nwfilters/templates/nwfilter.html @@ -65,7 +65,7 @@
    + +
    + + + + + + + +{% endif %} diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html new file mode 100644 index 0000000..1f7c7b0 --- /dev/null +++ b/nwfilters/templates/nwfilter.html @@ -0,0 +1,220 @@ +{% extends "base.html" %} +{% load i18n %} +{% load staticfiles %} +{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %} +{% block content %} + +
    +
    + {% include 'create_nwfilter_block.html' %} +

    {% trans "NWFilter:" %} {{ name }}

    + +
    +
    + + + {% include 'errors_block.html' %} + {% include 'messages_block.html' %} + +
    +
    +

    {% trans "UUID:" %}

    +

    {% trans "Name:" %}

    +
    + +
    +

    {{ uuid }}

    +

    {{ name }}

    +
    + +
    +
    +

    {% trans "XML:" %}

    +
    {% csrf_token %} +
    + + +
    + +
    +
    +
    +

    {% trans "Filter References:" %}

    +
    {% csrf_token %} +
    + + + + +
    +
    + +
    +
    +
    + + + + + + + + + + {% for ref in refs %} + + + + + + {% endfor %} + +
    #{% trans "Reference" %}{% trans "Action" %}
    {{ forloop.counter }}{{ ref }} +
    {% csrf_token %} + + +
    +
    +
    +
    +
    +

    {% trans "Rules:" %}

    + + + + + + +
    +
    +
    + + + + + + + + + + + + + + {% for rule in rules %} + + + + + + + + + + {% endfor %} + +
    {% trans "Rule" %}{% trans "ActionType" %}{% trans "Direction" %}{% trans "Priority" %}{% trans "Statematch" %}{% trans "Directives" %}{% trans "Action" %}
    {{ forloop.counter }}{{ rule.action }}{{ rule.direction }}{{ rule.priority }}{{ rule.statematch }}{{ rule.directives }} +
    {% csrf_token %} + + + + +
    +
    +
    +
    + + +{% endblock %} + +{% block script %} + + + + + +{% endblock %} diff --git a/nwfilters/templates/nwfilters.html b/nwfilters/templates/nwfilters.html new file mode 100644 index 0000000..e237380 --- /dev/null +++ b/nwfilters/templates/nwfilters.html @@ -0,0 +1,168 @@ +{% extends "base.html" %} +{% load i18n %} +{% load staticfiles %} +{% block title %}{% trans "NWFilters" %} - {{ compute.name }}{% endblock %} +{% block content %} + +
    +
    + {% include 'create_nwfilter_block.html' %} +

    {{ compute.name }}

    + +
    +
    + + +{% include 'errors_block.html' %} +{% include 'messages_block.html' %} + +
    +
    +
    +
    + +
    + + +
    + {% if nwfilters %} +
    + + + + + + + + + + + {% for nwfilter in nwfilters %} + + + + + + + + + {% endfor %} + +
    #{% trans "UUID" %}{% trans "Name" %}{% trans "Action" %}
    {{ forloop.counter }}{{ nwfilter.uuid }}{{ nwfilter.name }} + + + + + + +
    {% csrf_token %} + + +
    +
    +
    + {% else %} +
    +
    + + {% trans "Warning:" %} {% trans "Hypervisor doesn't have any NWFilters" %} +
    +
    + {% endif %} +
    +
    +{% endblock %} + +{% block script %} + + + + + + + +{% endblock %} diff --git a/nwfilters/tests.py b/nwfilters/tests.py new file mode 100644 index 0000000..5982e6b --- /dev/null +++ b/nwfilters/tests.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.test import TestCase + +# Create your tests here. diff --git a/nwfilters/views.py b/nwfilters/views.py new file mode 100644 index 0000000..5fa39f5 --- /dev/null +++ b/nwfilters/views.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.shortcuts import render +from django.http import HttpResponseRedirect +from django.shortcuts import render, get_object_or_404 +from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse +from django.contrib.auth.decorators import login_required +from computes.models import Compute +from vrtManager import util +from vrtManager.nwfilters import wvmNWFilters, wvmNWFilter +from libvirt import libvirtError + + +@login_required +def nwfilters(request, compute_id): + """ + :param request: + :return: + """ + + if not request.user.is_superuser: + return HttpResponseRedirect(reverse('index')) + + error_messages = [] + nwfilters_all = [] + compute = get_object_or_404(Compute, pk=compute_id) + + try: + conn = wvmNWFilters(compute.hostname, + compute.login, + compute.password, + compute.type) + + for nwf in conn.get_nwfilters(): + nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + + if request.method == 'POST': + if 'create_nwfilter' in request.POST: + xml = request.POST.get('nwfilter_xml', '') + if xml: + try: + util.etree.fromstring(xml) + name = util.get_xml_path(xml, '/filter/@name') + uuid = util.get_xml_path(xml, '/filter/uuid') + except util.etree.ParseError: + name = None + + for nwf in nwfilters: + if name == nwf.name(): + error_msg = _("A network filter with this name already exists") + raise Exception(error_msg) + if uuid == nwf.UUIDString(): + error_msg = _("A network filter with this uuid already exists") + raise Exception(error_msg) + else: + try: + conn.create_nwfilter(xml) + return HttpResponseRedirect(request.get_full_path()) + except libvirtError as lib_err: + error_messages.append(lib_err.message) + if 'del_nwfilter' in request.POST: + name = request.POST.get('nwfiltername','') + nwfilter = conn.get_nwfilter(name) + if nwfilter: + nwfilter.undefine() + return HttpResponseRedirect(request.get_full_path()) + + if 'cln_nwfilter' in request.POST: + name = request.POST.get('nwfiltername','') + cln_name = request.POST.get('cln_name', name + '-clone') + + conn.clone_nwfilter(name,cln_name) + return HttpResponseRedirect(request.get_full_path()) + + conn.close() + except libvirtError as lib_err: + error_messages.append(lib_err) + except Exception as err: + error_messages.append(err) + + return render(request, 'nwfilters.html', {'error_messages': error_messages, + 'nwfilters': nwfilters_all, + 'compute': compute}) + + +@login_required +def nwfilter(request, compute_id, nwfltr): + + error_messages = [] + nwfilters_all = [] + compute = get_object_or_404(Compute, pk=compute_id) + + try: + nwfilter = wvmNWFilter(compute.hostname, + compute.login, + compute.password, + compute.type, + nwfltr) + conn = wvmNWFilters(compute.hostname, + compute.login, + compute.password, + compute.type) + + for nwf in conn.get_nwfilters(): + nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + + uuid = nwfilter.get_uuid() + name = nwfilter.get_name() + xml = nwfilter.get_xml() + rules = nwfilter.get_rules() + refs = nwfilter.get_filter_refs() + + if request.method == 'POST': + + if 'edit_nwfilter' in request.POST: + new_xml = request.POST.get('edit_xml', '') + + if new_xml: + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'del_nwfilter_rule' in request.POST: + action = request.POST.get('action', '') + direction = request.POST.get('direction', '') + priority = request.POST.get('priority', '') + + new_xml = nwfilter.delete_rule(action, direction, priority) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'del_nwfilter_ref' in request.POST: + ref_name = request.POST.get('ref') + new_xml = nwfilter.delete_ref(ref_name) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'add_nwfilter_rule' in request.POST: + rule_xml = request.POST.get('nwfilterrule_xml', '') + if not rule_xml: + return HttpResponseRedirect(request.get_full_path()) + new_xml = nwfilter.add_rule(rule_xml) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + if 'add_nwfilter_ref' in request.POST: + ref_name = request.POST.get('nwfilters_select', '') + if not ref_name: + return HttpResponseRedirect(request.get_full_path()) + new_xml = nwfilter.add_ref(ref_name) + nwfilter.delete() + try: + conn.create_nwfilter(new_xml) + except libvirtError as lib_err: + conn.create_nwfilter(xml) + raise libvirtError(lib_err) + + return HttpResponseRedirect(request.get_full_path()) + conn.close() + nwfilter.close() + except libvirtError as lib_err: + error_messages.append(lib_err) + except Exception as error_msg: + error_messages.append(error_msg) + + return render(request, 'nwfilter.html', locals()) \ No newline at end of file diff --git a/secrets/templates/secrets.html b/secrets/templates/secrets.html index 8286bfb..07b104a 100644 --- a/secrets/templates/secrets.html +++ b/secrets/templates/secrets.html @@ -24,6 +24,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/storages/templates/storage.html b/storages/templates/storage.html index ecc9adc..4d3c706 100644 --- a/storages/templates/storage.html +++ b/storages/templates/storage.html @@ -25,6 +25,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/storages/templates/storages.html b/storages/templates/storages.html index 21bca90..026fe13 100644 --- a/storages/templates/storages.html +++ b/storages/templates/storages.html @@ -20,6 +20,9 @@
  • {% trans "Interfaces" %}
  • +
  • + {% trans "NWFilters" %} +
  • {% trans "Secrets" %}
  • diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 65c2915..96a4fbf 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -389,6 +389,12 @@ class wvmConnect(object): interface.append(inface) return interface + def get_nwfilters(self): + nwfilters = [] + for nwfilter in self.wvm.listAllNWFilters(): + nwfilters.append(nwfilter) + return nwfilters + def get_cache_modes(self): """Get cache available modes""" return { @@ -443,7 +449,6 @@ class wvmConnect(object): def get_video(self): """ Get available graphics video types """ - def get_video_list(ctx): result = [] for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'): @@ -470,6 +475,9 @@ class wvmConnect(object): def get_network(self, net): return self.wvm.networkLookupByName(net) + def get_nwfilter(self, name): + return self.wvm.nwfilterLookupByName(name) + def get_instance(self, name): return self.wvm.lookupByName(name) diff --git a/vrtManager/instance.py b/vrtManager/instance.py index b27baa0..d63d36c 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -487,8 +487,7 @@ class wvmInstance(wvmConnect): return self._defineXML(newxml) def get_console_socket(self): - socket = util.get_xml_path(self._XMLDesc(0), - "/domain/devices/graphics/@socket") + socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket") return socket def get_console_type(self): diff --git a/vrtManager/nwfilters.py b/vrtManager/nwfilters.py new file mode 100644 index 0000000..58784b9 --- /dev/null +++ b/vrtManager/nwfilters.py @@ -0,0 +1,125 @@ +from vrtManager.connection import wvmConnect +from xml.etree import ElementTree + + +class wvmNWFilters(wvmConnect): + def get_nwfilter_info(self, name): + nwfilter = self.get_nwfilter(name) + xml = nwfilter.XMLDesc(0) + uuid = nwfilter.UUIDString() + return {'name': name, 'uuid': uuid, 'xml': xml} + + def create_nwfilter(self, xml): + self.wvm.nwfilterDefineXML(xml) + + def clone_nwfilter(self,name, cln_name): + nwfilter = self.get_nwfilter(name) + if nwfilter: + tree = ElementTree.fromstring(nwfilter.XMLDesc(0)) + tree.set('name', cln_name) + uuid = tree.find('uuid') + tree.remove(uuid) + self.create_nwfilter(ElementTree.tostring(tree)) + + +class wvmNWFilter(wvmConnect): + def __init__(self, host, login, passwd, conn, nwfiltername): + wvmConnect.__init__(self, host, login, passwd, conn) + self.nwfilter = self.get_nwfilter(nwfiltername) + + def _XMLDesc(self, flags): + return self.nwfilter.XMLDesc(flags) + + def get_uuid(self): + return self.nwfilter.UUIDString() + + def get_name(self): + return self.nwfilter.name() + + def delete(self): + self.nwfilter.undefine() + + def get_xml(self): + tree = ElementTree.fromstring(self._XMLDesc(0)) + uuid = tree.find('uuid') + tree.remove(uuid) + return ElementTree.tostring(tree) + + def get_filter_refs(self): + refs = [] + tree = ElementTree.fromstring(self._XMLDesc(0)) + for ref in tree.findall("./filterref"): + refs.append(ref.get('filter')) + return refs + + def get_rules(self): + rules = [] + + tree = ElementTree.fromstring(self._XMLDesc(0)) + for r in tree.findall("./rule"): + rule_action = r.get('action') + rule_direction = r.get('direction') + rule_priority = r.get('priority') + rule_statematch = r.get('statematch') + + rule_directives = r.find("./") + if rule_directives is not None: + rule_directives = ElementTree.tostring(rule_directives) + + rule_info = { + "action": rule_action, + "direction": rule_direction, + "priority": rule_priority, + "statematch": rule_statematch, + "directives": rule_directives + } + + rules.append(rule_info) + + return rules + + def delete_ref(self, name): + tree = ElementTree.fromstring(self._XMLDesc(0)) + for ref in tree.findall("./filterref"): + if name == ref.get('filter'): + tree.remove(ref) + break + return ElementTree.tostring(tree) + + def delete_rule(self, action, direction, priority): + tree = ElementTree.fromstring(self._XMLDesc(0)) + + rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (action, direction, priority)) + if rule_tree: + tree.remove(rule_tree[0]) + + return ElementTree.tostring(tree) + + def add_ref(self, name): + tree = ElementTree.fromstring(self._XMLDesc(0)) + element = ElementTree.Element("filterref") + element.attrib['filter'] = name + tree.append(element) + return ElementTree.tostring(tree) + + def add_rule(self, xml): + tree = ElementTree.fromstring(self._XMLDesc(0)) + rule = ElementTree.fromstring(xml) + + rule_action = rule.get('action') + rule_direction = rule.get('direction') + rule_priority = rule.get('priority') + rule_directives = rule.find("./") + rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (rule_action, rule_direction, rule_priority)) + + if rule_tree: + rule_tree[0].append(rule_directives) + else: + element = ElementTree.Element("rule") + element.attrib['action'] = rule_action + element.attrib['direction'] = rule_direction + element.attrib['priority'] = rule_priority + element.append(rule_directives) + tree.append(element) + + return ElementTree.tostring(tree) diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py index d169386..79992af 100644 --- a/webvirtcloud/urls.py +++ b/webvirtcloud/urls.py @@ -7,6 +7,7 @@ from secrets.views import secrets from create.views import create_instance from interfaces.views import interfaces, interface from console.views import console +from nwfilters.views import nwfilters, nwfilter # from django.contrib import admin urlpatterns = [ @@ -25,9 +26,12 @@ urlpatterns = [ url(r'^compute/(?P[0-9]+)/network/(?P[\w\-\.]+)/$', network, name='network'), url(r'^compute/(?P[0-9]+)/interfaces/$', interfaces, name='interfaces'), url(r'^compute/(?P[0-9]+)/interface/(?P[\w\-\.\:]+)/$', interface, name='interface'), + url(r'^compute/(?P[0-9]+)/nwfilters/$', nwfilters, name='nwfilters'), + url(r'^compute/(?P[0-9]+)/nwfilter/(?P[\w\-\.\:]+)/$', nwfilter, name='nwfilter'), url(r'^compute/(?P[0-9]+)/secrets/$', secrets, name='secrets'), url(r'^compute/(?P[0-9]+)/create/$', create_instance, name='create_instance'), + url(r'^console/$', console, name='console'), # (r'^admin/', include(admin.site.urls)), ] From 7f2104c19d30f331214943fdbaf34a7237064837 Mon Sep 17 00:00:00 2001 From: catborise Date: Fri, 21 Sep 2018 18:46:33 +0300 Subject: [PATCH 04/14] Check usage of filter refs from domains. --- nwfilters/templates/nwfilter.html | 2 +- nwfilters/views.py | 42 +++++++++++++++++++++++++------ vrtManager/instance.py | 13 ++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html index 1f7c7b0..0d2e2f1 100644 --- a/nwfilters/templates/nwfilter.html +++ b/nwfilters/templates/nwfilter.html @@ -65,7 +65,7 @@
    + +
    + +
    + +
    @@ -226,6 +237,17 @@
    +
    + +
    + +
    +
    @@ -379,6 +401,17 @@
    +
    + +
    + +
    +
    diff --git a/create/views.py b/create/views.py index 0c39a1d..9fb846e 100644 --- a/create/views.py +++ b/create/views.py @@ -28,7 +28,6 @@ def create_instance(request, compute_id): storages = [] networks = [] meta_prealloc = False - #computes = Compute.objects.all() compute = get_object_or_404(Compute, pk=compute_id) flavors = Flavor.objects.filter().order_by('id') @@ -40,6 +39,7 @@ def create_instance(request, compute_id): storages = sorted(conn.get_storages(only_actives=True)) networks = sorted(conn.get_networks()) + nwfilters = conn.get_nwfilters() instances = conn.get_instances() videos = conn.get_video() cache_modes = sorted(conn.get_cache_modes().items()) @@ -139,7 +139,7 @@ def create_instance(request, compute_id): try: conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'], uuid, volumes, data['cache_mode'], data['networks'], data['virtio'], - data["listener_addr"], None, data["video"], data["console_pass"], + data["listener_addr"], data["nwfilter"], data["video"], data["console_pass"], data['mac']) create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid) create_instance.save() diff --git a/instances/templates/add_instance_network_block.html b/instances/templates/add_instance_network_block.html index 990c524..afb0ae5 100644 --- a/instances/templates/add_instance_network_block.html +++ b/instances/templates/add_instance_network_block.html @@ -33,12 +33,24 @@
    +
    + +
    + +
    + + diff --git a/instances/templates/instance.html b/instances/templates/instance.html index 9b34878..4dbfa6d 100644 --- a/instances/templates/instance.html +++ b/instances/templates/instance.html @@ -859,11 +859,8 @@ {% endfor %} - {% ifequal status 5 %} - - {% else %} - - {% endifequal %} + +
    diff --git a/instances/views.py b/instances/views.py index ec6adbc..0f4469f 100644 --- a/instances/views.py +++ b/instances/views.py @@ -364,6 +364,7 @@ def instance(request, compute_id, vname): else: media_iso = [] networks = conn.get_net_device() + nwfilters = conn.get_nwfilters() vcpu_range = conn.get_max_cpus() memory_range = [256, 512, 768, 1024, 2048, 4096, 6144, 8192, 16384] if memory not in memory_range: @@ -708,9 +709,10 @@ def instance(request, compute_id, vname): if 'add_network' in request.POST: mac = request.POST.get('add-net-mac') + nwfilter = request.POST.get('nwfilter') (source, source_type) = get_network_tuple(request.POST.get('add-net-network')) - conn.add_network(mac, source, source_type) + conn.add_network(mac, source, source_type, nwfilter=nwfilter) msg = _("Edit network") addlogmsg(request.user.username, instance.name, msg) msg = _("Network Devices are changed. Please reboot instance to activate.") diff --git a/nwfilters/templates/nwfilter.html b/nwfilters/templates/nwfilter.html index 0d2e2f1..9f97831 100644 --- a/nwfilters/templates/nwfilter.html +++ b/nwfilters/templates/nwfilter.html @@ -22,7 +22,7 @@ {% trans "Interfaces" %}
  • - {% trans "NWFilters" %} + {% trans "NWFilters" %}
  • {% trans "Secrets" %} diff --git a/nwfilters/views.py b/nwfilters/views.py index 99686ed..c0dd8d8 100644 --- a/nwfilters/views.py +++ b/nwfilters/views.py @@ -98,7 +98,7 @@ def nwfilters(request, compute_id): addlogmsg(request.user.username, compute.hostname, msg) for nwf in conn.get_nwfilters(): - nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + nwfilters_all.append(conn.get_nwfilter_info(nwf)) conn.close() except libvirtError as lib_err: @@ -132,7 +132,7 @@ def nwfilter(request, compute_id, nwfltr): compute.type) for nwf in conn.get_nwfilters(): - nwfilters_all.append(conn.get_nwfilter_info(nwf.name())) + nwfilters_all.append(conn.get_nwfilter_info(nwf)) uuid = nwfilter.get_uuid() name = nwfilter.get_name() diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 96a4fbf..1a16f4e 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -391,7 +391,7 @@ class wvmConnect(object): def get_nwfilters(self): nwfilters = [] - for nwfilter in self.wvm.listAllNWFilters(): + for nwfilter in self.wvm.listNWFilters(): nwfilters.append(nwfilter) return nwfilters diff --git a/vrtManager/instance.py b/vrtManager/instance.py index ca5568f..dd2db64 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -788,7 +788,7 @@ class wvmInstance(wvmConnect): bridge_name = net.bridgeName() return bridge_name - def add_network(self, mac_address, source, source_type='net', interface_type='bridge', model='virtio'): + def add_network(self, mac_address, source, source_type='net', interface_type='bridge', model='virtio', nwfilter=None): tree = ElementTree.fromstring(self._XMLDesc(0)) bridge_name = self.get_bridge_name(source, source_type) xml_interface = """ @@ -796,8 +796,13 @@ class wvmInstance(wvmConnect): - - """ % (interface_type, mac_address, bridge_name, model) + """ % (interface_type, mac_address, bridge_name, model) + if nwfilter: + xml_interface += """ + + """ % nwfilter + xml_interface += """""" + if self.get_status() == 5: devices = tree.find('devices') elm_interface = ElementTree.fromstring(xml_interface) From f7d2d24d0bca6bbe2fa649182f0cec0e47a75b8c Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 26 Sep 2018 16:19:32 +0300 Subject: [PATCH 07/14] message.success fix - (request was missing) --- storages/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storages/views.py b/storages/views.py index f18cad6..71bee86 100644 --- a/storages/views.py +++ b/storages/views.py @@ -155,7 +155,7 @@ def storage(request, compute_id, pool): meta_prealloc = True try: conn.create_volume(data['name'], data['size'], data['format'], meta_prealloc) - messages.success("Image file {} is created successfully".format(data['name']+".img")) + messages.success(request, "Image file {} is created successfully".format(data['name']+".img")) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err) From 5d4a6009082bd6218f6a582838118be63cc5c0f5 Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 26 Sep 2018 17:16:48 +0300 Subject: [PATCH 08/14] success message converted to translate ready --- create/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create/views.py b/create/views.py index 9fb846e..2cacdc4 100644 --- a/create/views.py +++ b/create/views.py @@ -143,7 +143,7 @@ def create_instance(request, compute_id): data['mac']) create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid) create_instance.save() - messages.success(request,"Instance is created.") + messages.success(request, _("Instance is created.")) return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']])) except libvirtError as lib_err: if data['hdd_size'] or volumes[clone_path]: From ba212971faec023950169d14e197e24ad226029f Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 26 Sep 2018 17:18:30 +0300 Subject: [PATCH 09/14] success message converted to translate ready --- storages/views.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/storages/views.py b/storages/views.py index 71bee86..d2214aa 100644 --- a/storages/views.py +++ b/storages/views.py @@ -155,7 +155,7 @@ def storage(request, compute_id, pool): meta_prealloc = True try: conn.create_volume(data['name'], data['size'], data['format'], meta_prealloc) - messages.success(request, "Image file {} is created successfully".format(data['name']+".img")) + messages.success(request, _("Image file {} is created successfully".format(data['name']+".img"))) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err) @@ -167,7 +167,7 @@ def storage(request, compute_id, pool): try: vol = conn.get_volume(volname) vol.delete(0) - messages.success(request,_('Volume: {} is deleted.'.format(volname))) + messages.success(request, _('Volume: {} is deleted.'.format(volname))) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err.message) @@ -197,8 +197,7 @@ def storage(request, compute_id, pool): format = None try: conn.clone_volume(data['image'], data['name'], format, meta_prealloc) - messages.success(request, _("{} image cloned as {} successfully".format(data['image'], - data['name'] + ".img"))) + messages.success(request, _("{} image cloned as {} successfully".format(data['image'], data['name'] + ".img"))) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err) From b916c9dcf916376209efdd66e971b465de94a286 Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 26 Sep 2018 17:20:46 +0300 Subject: [PATCH 10/14] instance network tab modified. Changing function modified. deleting function added. network info of nwfilters added. and some small fixes applied --- .../templates/add_instance_network_block.html | 4 +- instances/templates/instance.html | 75 ++++++++++++------- instances/views.py | 27 ++++--- vrtManager/instance.py | 27 ++++++- 4 files changed, 93 insertions(+), 40 deletions(-) diff --git a/instances/templates/add_instance_network_block.html b/instances/templates/add_instance_network_block.html index afb0ae5..9d65601 100644 --- a/instances/templates/add_instance_network_block.html +++ b/instances/templates/add_instance_network_block.html @@ -36,9 +36,9 @@
    - - {% for nwfilter in nwfilters %} + {% for nwfilter in compute_nwfilters %} {% endfor %} diff --git a/instances/templates/instance.html b/instances/templates/instance.html index 4dbfa6d..b61e73b 100644 --- a/instances/templates/instance.html +++ b/instances/templates/instance.html @@ -833,36 +833,63 @@ {% if request.user.is_superuser %}

    - {% trans "Assign network device to bridge" %} - {% include 'add_instance_network_block.html' %} + {% trans "Assign network device to bridge" %} + {% include 'add_instance_network_block.html' %}

    -
    {% csrf_token %} -

    {% trans "Network devices" %}

    +

    {% trans "Network devices" %}

    +
    + {% csrf_token %} {% for network in networks %} -
    - -
    - +
    +
    +
    -
    - +
    +
    + + + + +
    +
    + + + + +
    +
    + + + + +
    -
    - + +
    {% endfor %} - - + + + +
    +
    {% endif %} {% if request.user.is_superuser or request.user.userattributes.can_clone_instances %} @@ -1367,12 +1394,6 @@ }); }); - + + + +{% if request.user.is_superuser %} + +{% endif %} +{% endblock %} diff --git a/instances/templates/instances_grouped.html b/instances/templates/instances_grouped.html index 2e129c2..0d16056 100644 --- a/instances/templates/instances_grouped.html +++ b/instances/templates/instances_grouped.html @@ -15,6 +15,7 @@ {% for host, inst in all_host_vms.items %} + {{ inst.items|length }} {{ host.1 }} diff --git a/instances/views.py b/instances/views.py index 70fb9bf..19db3fb 100644 --- a/instances/views.py +++ b/instances/views.py @@ -38,7 +38,7 @@ def index(request): @login_required -def instances(request): +def instances(request, compute_id=None): """ :param request: :return: @@ -47,7 +47,11 @@ def instances(request): error_messages = [] all_host_vms = {} all_user_vms = {} - computes = Compute.objects.all().order_by("name") + + if not compute_id: + computes = Compute.objects.all().order_by("name") + else: + computes = [Compute.objects.get(id=compute_id),] def get_userinstances_info(instance): info = {} @@ -195,8 +199,11 @@ def instances(request): view_style = settings.VIEW_INSTANCES_LIST_STYLE - return render(request, 'instances.html', locals()) + if compute_id: + compute = computes[0] + return render(request, 'compute_instances.html', locals()) + return render(request, 'instances.html', locals()) @login_required def instance(request, compute_id, vname): diff --git a/interfaces/templates/interfaces.html b/interfaces/templates/interfaces.html index 58d4978..c121595 100644 --- a/interfaces/templates/interfaces.html +++ b/interfaces/templates/interfaces.html @@ -12,6 +12,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • @@ -94,4 +97,4 @@ }).change(); }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/networks/templates/networks.html b/networks/templates/networks.html index 2acc1f3..5e843ae 100644 --- a/networks/templates/networks.html +++ b/networks/templates/networks.html @@ -11,6 +11,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • @@ -80,4 +83,4 @@ }).change(); }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/nwfilters/templates/nwfilters.html b/nwfilters/templates/nwfilters.html index e237380..9fd228f 100644 --- a/nwfilters/templates/nwfilters.html +++ b/nwfilters/templates/nwfilters.html @@ -12,6 +12,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • diff --git a/secrets/templates/secrets.html b/secrets/templates/secrets.html index 07b104a..28d8dbd 100644 --- a/secrets/templates/secrets.html +++ b/secrets/templates/secrets.html @@ -10,11 +10,14 @@
    {% include 'create_secret_block.html' %} -

    {% trans "Secrets" %}

    +

    {{ compute.name }}

    diff --git a/storages/templates/storages.html b/storages/templates/storages.html index 026fe13..20f147c 100644 --- a/storages/templates/storages.html +++ b/storages/templates/storages.html @@ -11,6 +11,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • @@ -67,4 +70,4 @@ {% endfor %} {% endif %}
    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py index 79992af..2aa2c58 100644 --- a/webvirtcloud/urls.py +++ b/webvirtcloud/urls.py @@ -8,6 +8,7 @@ from create.views import create_instance from interfaces.views import interfaces, interface from console.views import console from nwfilters.views import nwfilters, nwfilter +from computes.views import computes # from django.contrib import admin urlpatterns = [ @@ -15,8 +16,13 @@ urlpatterns = [ url(r'^instances/$', instances, name='instances'), url(r'^instance/', include('instances.urls')), + url(r'^instances/$', instances, name='instances'), + url(r'^accounts/', include('accounts.urls')), + url(r'^computes/', include('computes.urls')), + url(r'^computes/', computes, name='computes'), + url(r'^logs/', include('logs.urls')), url(r'^datasource/', include('datasource.urls')), From 1492e690977f436a736f911636da19962e83f521 Mon Sep 17 00:00:00 2001 From: Bandic007 Date: Thu, 27 Sep 2018 12:21:46 +0300 Subject: [PATCH 13/14] addded settins parameteres for proxying --- webvirtcloud/settings.py.template | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template index 8f20dd8..7c78005 100644 --- a/webvirtcloud/settings.py.template +++ b/webvirtcloud/settings.py.template @@ -106,6 +106,13 @@ WS_HOST = '0.0.0.0' # Websock public port WS_PUBLIC_HOST = None +# Websock public port - default is 80 - uncomment 443 and comment 80 if you want to use vnc over https +WS_PUBLIC_PORT = 80 +#WS_PUBLIC_PORT = 443 + +# Websock pubic path +WS_PUBLIC_PATH = '/novncd/' + # Websock SSL connection WS_CERT = None @@ -153,4 +160,4 @@ INSTANCE_VOLUME_DEFAULT_FORMAT = 'qcow2' INSTANCE_VOLUME_DEFAULT_BUS = 'virtio' INSTANCE_VOLUME_DEFAULT_CACHE = 'directsync' # up to os, 0=root, 107=qemu or libvirt-bin(for ubuntu) -INSTANCE_VOLUME_DEFAULT_OWNER = 0 \ No newline at end of file +INSTANCE_VOLUME_DEFAULT_OWNER = 0 From 4da783da3287769f25d6fb242394de66854b6e3e Mon Sep 17 00:00:00 2001 From: Bandic007 Date: Thu, 27 Sep 2018 12:39:40 +0300 Subject: [PATCH 14/14] added compute instances page link to storage/network and interface.html --- interfaces/templates/interface.html | 5 ++++- networks/templates/network.html | 5 ++++- storages/templates/storage.html | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/interfaces/templates/interface.html b/interfaces/templates/interface.html index 014a44e..3a04016 100644 --- a/interfaces/templates/interface.html +++ b/interfaces/templates/interface.html @@ -10,6 +10,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • @@ -67,4 +70,4 @@

    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/networks/templates/network.html b/networks/templates/network.html index e3b0275..085b35b 100644 --- a/networks/templates/network.html +++ b/networks/templates/network.html @@ -10,6 +10,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}
  • @@ -187,4 +190,4 @@ }); }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/storages/templates/storage.html b/storages/templates/storage.html index 77e45e0..09137f6 100644 --- a/storages/templates/storage.html +++ b/storages/templates/storage.html @@ -16,6 +16,9 @@
  • {% trans "Overview" %}
  • +
  • + {% trans "Instances" %} +
  • {% trans "Storages" %}