diff --git a/computes/templates/computes/list.html b/computes/templates/computes/list.html index 3a5f1718..d5850d9c 100644 --- a/computes/templates/computes/list.html +++ b/computes/templates/computes/list.html @@ -37,7 +37,9 @@ {{ compute.name }} - {% if compute.status is True %}{% trans "Connected" %}{% else %}{% trans "Not Connected" %}{% endif %} + {% if compute.status is True %}{% trans "Connected" %}{% else %}{% trans "Not Connected" %} +
{{ compute.connection_error }} + {% endif %} {{ compute.details|default:"" }} diff --git a/computes/test_overview_status.py b/computes/test_overview_status.py new file mode 100644 index 00000000..54074c20 --- /dev/null +++ b/computes/test_overview_status.py @@ -0,0 +1,37 @@ +from unittest.mock import PropertyMock, patch + +from django.contrib.auth import get_user_model +from django.test import TestCase +from django.urls import reverse + +from computes.models import Compute + +ERROR = "Connection Failed: Host key verification failed." + + +class OverviewStatusTests(TestCase): + def setUp(self): + self.client.force_login( + get_user_model().objects.create_superuser(username="ov-admin", password="pwd", email="ov@example.com") + ) + # an ssh_config alias: not a name a TCP probe can reach + self.compute = Compute.objects.create(name="ov-alias", hostname="wvc-alias", login="root", password="", type=2) + + @patch("vrtManager.connection.connection_manager.host_is_up", return_value=False) + @patch("computes.views.wvmHostDetails") + def test_overview_state_comes_from_the_connection(self, host_details, host_is_up): + conn = host_details.return_value + conn.get_node_info.return_value = ("host", "x86_64", 1024, 2, "cpu", "qemu+ssh://root@wvc-alias/system") + conn.get_memory_usage.return_value = {"total": 1024, "usage": 512, "percent": 50} + with patch.object(Compute, "status", new_callable=PropertyMock, return_value=True): + response = self.client.get(reverse("overview", args=[self.compute.id])) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["status"], "true") + + def test_compute_list_shows_why_a_host_is_not_connected(self): + with patch.object(Compute, "status", new_callable=PropertyMock, return_value=False), patch.object( + Compute, "connection_error", new_callable=PropertyMock, return_value=ERROR + ): + response = self.client.get(reverse("computes")) + self.assertContains(response, "Not Connected") + self.assertContains(response, ERROR) diff --git a/computes/views.py b/computes/views.py index 4195bf20..4bd6801f 100644 --- a/computes/views.py +++ b/computes/views.py @@ -7,10 +7,7 @@ from django.urls import reverse from django.utils import timezone from instances.models import Instance from libvirt import libvirtError -from vrtManager.connection import ( - connection_manager, - wvmConnect, -) +from vrtManager.connection import wvmConnect from vrtManager.hostdetails import wvmHostDetails from computes.forms import ( @@ -39,11 +36,9 @@ def computes(request): @superuser_only def overview(request, compute_id): 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" - ) + # the connection itself, not a TCP probe: ssh aliases and ProxyJump hosts + # are not reachable by name and port from here + status = "true" if compute.status else "false" conn = wvmHostDetails( compute.hostname,