From a4d28f295361cd738a34e8affba388d8a10127f5 Mon Sep 17 00:00:00 2001 From: Real-Gecko Date: Mon, 15 Jun 2020 17:52:05 +0600 Subject: [PATCH] Reworked some computes views and added more tests --- computes/models.py | 11 +- computes/templates/computes.html | 246 ---------------------- computes/templates/computes/list.html | 69 ++++++ computes/templates/create_comp_block.html | 2 +- computes/tests.py | 47 +++++ computes/urls.py | 52 ++--- computes/views.py | 107 +++++----- templates/search_block.html | 4 + 8 files changed, 205 insertions(+), 333 deletions(-) delete mode 100644 computes/templates/computes.html create mode 100644 computes/templates/computes/list.html create mode 100644 templates/search_block.html diff --git a/computes/models.py b/computes/models.py index 2b74de2..cfe0317 100644 --- a/computes/models.py +++ b/computes/models.py @@ -1,6 +1,9 @@ -from django.db.models import Model, CharField, IntegerField +from django.db.models import CharField, IntegerField, Model +from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ +from vrtManager.connection import connection_manager + class Compute(Model): name = CharField(_('name'), max_length=64, unique=True) @@ -10,5 +13,9 @@ class Compute(Model): details = CharField(_('details'), max_length=64, null=True, blank=True) type = IntegerField() + @cached_property + def status(self): + return connection_manager.host_is_up(self.type, self.hostname) + def __str__(self): - return self.hostname + return self.name diff --git a/computes/templates/computes.html b/computes/templates/computes.html deleted file mode 100644 index 3e7f98b..0000000 --- a/computes/templates/computes.html +++ /dev/null @@ -1,246 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} -{% block title %}{% trans "Computes" %}{% endblock %} -{% block content %} - -
-
- {% include 'create_comp_block.html' %} - -
-
- - - {% include 'errors_block.html' %} - -
- {% if computes_info %} - {% for compute in computes_info %} -
- {% if compute.status is True %} -
-
- {% else %} -
-
- {% endif %} -
- {% if compute.status is True %} - {{ compute.name }} - {% else %} - {{ compute.name }} - {% endif %} - - - -
-
-
-
-
{% trans "Status" %}
- {% if compute.status %} -
{% trans "Connected" %}
- {% else %} -
{% trans "Not Connected" %}
- {% endif %} -
{% trans "Details" %}
- {% if compute.details %} -
{% trans compute.details %}
- {% else %} -
{% trans "No details available" %}
- {% endif %} -
- - - -
-
-
- {% endfor %} - {% else %} -
-
- - {% trans "Warning" %}: {% trans "Hypervisor doesn't have any Computes" %} -
-
- {% endif %} -
-{% endblock %} diff --git a/computes/templates/computes/list.html b/computes/templates/computes/list.html new file mode 100644 index 0000000..18a2886 --- /dev/null +++ b/computes/templates/computes/list.html @@ -0,0 +1,69 @@ +{% extends "base.html" %} +{% load i18n %} +{% load static %} +{% load common_tags %} +{% load icons %} +{% block title %}{% trans "Computes" %}{% endblock %} +{% block content %} +
+
+ {% include 'create_comp_block.html' %} + {% include 'search_block.html' %} + +
+
+{% include 'errors_block.html' %} +
+ {% if not computes %} +
+
+ + {% icon 'exclamation-triangle '%} {% trans "Warning" %}: {% trans "You don't have any computes" %} +
+
+ {% else %} +
+ + + + + + + + + + + {% for compute in computes %} + + + + + + + {% endfor %} + +
{% trans "Name" %}{% trans "Status" %}{% trans "Details" %}{% trans "Actions" %}
+ {{ compute.name }} + + {% if compute.status is True %}{% trans "Connected" %}{% else %}{% trans "Not Connected" %}{% endif %} + + {{ compute.details|default:"" }} + +
+ {% if compute.status is True %} + {% icon 'eye' %} + {% else %} + {% icon 'eye' %} + {% endif %} + {% icon 'pencil' %} + {% icon 'times' %} +
+
+
+ {% endif %} +
+{% endblock content %} + +{% block script %} + +{% endblock script %} diff --git a/computes/templates/create_comp_block.html b/computes/templates/create_comp_block.html index 37f5d5a..478fea4 100644 --- a/computes/templates/create_comp_block.html +++ b/computes/templates/create_comp_block.html @@ -1,7 +1,7 @@ {% load i18n %} {% load bootstrap4 %} {% load icons %} -
+
{% trans "TCP" %} {% trans "SSH" %} {% trans "TLS" %} diff --git a/computes/tests.py b/computes/tests.py index ca4cb4c..391abd5 100644 --- a/computes/tests.py +++ b/computes/tests.py @@ -1,3 +1,4 @@ +from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import reverse from django.test import TestCase @@ -20,6 +21,52 @@ class ComputesTestCase(TestCase): response = self.client.get(reverse('computes')) self.assertEqual(response.status_code, 200) + def test_create_update_delete(self): + response = self.client.get(reverse('add_socket_host')) + self.assertEqual(response.status_code, 200) + + response = self.client.post( + reverse('add_socket_host'), + { + 'name': 'l1', + 'details': 'Created', + 'hostname': 'localhost', + 'type': 4, + }, + ) + self.assertRedirects(response, reverse('computes')) + + compute = Compute.objects.get(pk=2) + self.assertEqual(compute.name, 'l1') + self.assertEqual(compute.details, 'Created') + + response = self.client.get(reverse('compute_update', args=[2])) + self.assertEqual(response.status_code, 200) + + response = self.client.post( + reverse('compute_update', args=[2]), + { + 'name': 'l2', + 'details': 'Updated', + 'hostname': 'localhost', + 'type': 4, + }, + ) + self.assertRedirects(response, reverse('computes')) + + compute = Compute.objects.get(pk=2) + self.assertEqual(compute.name, 'l2') + self.assertEqual(compute.details, 'Updated') + + response = self.client.get(reverse('compute_delete', args=[2])) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse('compute_delete', args=[2])) + self.assertRedirects(response, reverse('computes')) + + with self.assertRaises(ObjectDoesNotExist): + Compute.objects.get(id=2) + def test_overview(self): response = self.client.get(reverse('overview', args=[1])) self.assertEqual(response.status_code, 200) diff --git a/computes/urls.py b/computes/urls.py index 54f67ff..81c37a5 100644 --- a/computes/urls.py +++ b/computes/urls.py @@ -12,28 +12,32 @@ from storages.views import get_volumes, storage, storages urlpatterns = [ path('', views.computes, name='computes'), - path('add_tcp_host/', views.add_host, {'FormClass': forms.TcpComputeForm}, name='add_tcp_host'), - path('add_ssh_host/', views.add_host, {'FormClass': forms.SshComputeForm}, name='add_ssh_host'), - path('add_tls_host/', views.add_host, {'FormClass': forms.TlsComputeForm}, name='add_tls_host'), - path('add_socket_host/', views.add_host, {'FormClass': forms.SocketComputeForm}, name='add_socket_host'), - path('/', include([ - path('', views.overview, name='overview'), - path('statistics', views.compute_graph, name='compute_graph'), - path('instances/', instances, name='instances'), - path('storages/', storages, name='storages'), - path('storage//volumes', get_volumes, name='volumes'), - path('storage//', storage, name='storage'), - path('networks/', networks, name='networks'), - path('network//', network, name='network'), - path('interfaces/', interfaces, name='interfaces'), - path('interface//', interface, name='interface'), - path('nwfilters/', nwfilters, name='nwfilters'), - path('nwfilter//', nwfilter, name='nwfilter'), - path('secrets/', secrets, name='secrets'), - path('create/', create_instance_select_type, name='create_instance_select_type'), - path('create/archs//machines//', create_instance, name='create_instance'), - path('archs//machines', views.get_compute_machine_types, name='machines'), - path('archs//machines//disks//buses', views.get_compute_disk_buses, name='buses'), - path('archs//machines//capabilities', views.get_dom_capabilities, name='domcaps'), - ])), + path('add_tcp_host/', views.compute_create, {'FormClass': forms.TcpComputeForm}, name='add_tcp_host'), + path('add_ssh_host/', views.compute_create, {'FormClass': forms.SshComputeForm}, name='add_ssh_host'), + path('add_tls_host/', views.compute_create, {'FormClass': forms.TlsComputeForm}, name='add_tls_host'), + path('add_socket_host/', views.compute_create, {'FormClass': forms.SocketComputeForm}, name='add_socket_host'), + path( + '/', + include([ + path('', views.overview, name='overview'), + path('update/', views.compute_update, name='compute_update'), + path('delete/', views.compute_delete, name='compute_delete'), + path('statistics', views.compute_graph, name='compute_graph'), + path('instances/', instances, name='instances'), + path('storages/', storages, name='storages'), + path('storage//volumes', get_volumes, name='volumes'), + path('storage//', storage, name='storage'), + path('networks/', networks, name='networks'), + path('network//', network, name='network'), + path('interfaces/', interfaces, name='interfaces'), + path('interface//', interface, name='interface'), + path('nwfilters/', nwfilters, name='nwfilters'), + path('nwfilter//', nwfilter, name='nwfilter'), + path('secrets/', secrets, name='secrets'), + path('create/', create_instance_select_type, name='create_instance_select_type'), + path('create/archs//machines//', create_instance, name='create_instance'), + path('archs//machines', views.get_compute_machine_types, name='machines'), + path('archs//machines//disks//buses', views.get_compute_disk_buses, name='buses'), + path('archs//machines//capabilities', views.get_dom_capabilities, name='domcaps'), + ])), ] diff --git a/computes/views.py b/computes/views.py index 2685760..7a947d7 100644 --- a/computes/views.py +++ b/computes/views.py @@ -22,58 +22,10 @@ def computes(request): :param request: :return: """ - def get_hosts_status(computes): - """ - Function return all hosts all vds on host - """ - compute_data = [] - for compute in computes: - compute_data.append({ - 'id': compute.id, - 'name': compute.name, - 'hostname': compute.hostname, - 'status': connection_manager.host_is_up(compute.type, compute.hostname), - 'type': compute.type, - 'login': compute.login, - 'password': compute.password, - 'details': compute.details - }) - return compute_data - error_messages = [] computes = Compute.objects.filter().order_by('name') - computes_info = get_hosts_status(computes) - if request.method == 'POST': - if 'host_del' in request.POST: - compute_id = request.POST.get('host_id', '') - try: - del_user_inst_on_host = UserInstance.objects.filter(instance__compute_id=compute_id) - del_user_inst_on_host.delete() - finally: - try: - del_inst_on_host = Instance.objects.filter(compute_id=compute_id) - del_inst_on_host.delete() - finally: - del_host = Compute.objects.get(id=compute_id) - del_host.delete() - return HttpResponseRedirect(request.get_full_path()) - if 'host_edit' in request.POST: - form = ComputeEditHostForm(request.POST) - if form.is_valid(): - data = form.cleaned_data - compute_edit = Compute.objects.get(id=data['host_id']) - compute_edit.name = data['name'] - compute_edit.hostname = data['hostname'] - compute_edit.login = data['login'] - compute_edit.password = data['password'] - compute_edit.details = data['details'] - compute_edit.save() - return HttpResponseRedirect(request.get_full_path()) - else: - for msg_err in form.errors.values(): - error_messages.append(msg_err.as_text()) - return render(request, 'computes.html', locals()) + return render(request, 'computes/list.html', {'computes': computes}) @superuser_only @@ -87,7 +39,7 @@ def overview(request, compute_id): error_messages = [] compute = get_object_or_404(Compute, pk=compute_id) status = 'true' if connection_manager.host_is_up(compute.type, compute.hostname) is True else 'false' - + try: conn = wvmHostDetails( compute.hostname, @@ -108,6 +60,51 @@ def overview(request, compute_id): return render(request, 'overview.html', locals()) +@superuser_only +def compute_create(request, FormClass): + form = FormClass(request.POST or None) + if form.is_valid(): + form.save() + return redirect(reverse('computes')) + + return render(request, 'computes/form.html', {'form': form}) + + +@superuser_only +def compute_update(request, compute_id): + compute = get_object_or_404(Compute, pk=compute_id) + + if compute.type == 1: + FormClass = TcpComputeForm + elif compute.type == 2: + FormClass = SshComputeForm + elif compute.type == 3: + FormClass = TlsComputeForm + elif compute.type == 4: + FormClass = SocketComputeForm + + form = FormClass(request.POST or None, instance=compute) + if form.is_valid(): + form.save() + return redirect(reverse('computes')) + + return render(request, 'computes/form.html', {'form': form}) + + +@superuser_only +def compute_delete(request, compute_id): + compute = get_object_or_404(Compute, pk=compute_id) + if request.method == 'POST': + compute.delete() + return redirect('computes') + + return render( + request, + 'common/confirm_delete.html', + {'object': compute}, + ) + + def compute_graph(request, compute_id): """ :param request: @@ -248,13 +245,3 @@ def get_dom_capabilities(request, compute_id, arch, machine): pass return HttpResponse(json.dumps(data)) - - -@superuser_only -def add_host(request, FormClass): - form = FormClass(request.POST or None) - if form.is_valid(): - form.save() - return redirect(reverse('computes')) - - return render(request, 'computes/form.html', {'form': form}) diff --git a/templates/search_block.html b/templates/search_block.html new file mode 100644 index 0000000..7f2b515 --- /dev/null +++ b/templates/search_block.html @@ -0,0 +1,4 @@ +{% load i18n %} +