Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/3383.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Catch and show no read-write profile error in arnold
12 changes: 9 additions & 3 deletions python/nav/arnold.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ def disable(candidate, justification, username, comment="", autoenablestep=0):
if not candidate.interface.netbox.get_preferred_snmp_management_profile(
require_write=True
):
raise NoReadWriteManagementProfileError(candidate.interface.netbox)
raise NoReadWriteManagementProfileError(
"%s has no read-write management profile" % candidate.interface.netbox
)
identity = check_identity(candidate)
change_port_status('disable', identity)
identity.status = 'disabled'
Expand All @@ -317,7 +319,9 @@ def quarantine(candidate, qvlan, justification, username, comment="", autoenable
if not candidate.interface.netbox.get_preferred_snmp_management_profile(
require_write=True
):
raise NoReadWriteManagementProfileError(candidate.interface.netbox)
raise NoReadWriteManagementProfileError(
"%s has no read-write management profile" % candidate.interface.netbox
)
identity = check_identity(candidate)
identity.fromvlan = change_port_vlan(identity, qvlan.vlan)
identity.tovlan = qvlan
Expand Down Expand Up @@ -461,7 +465,9 @@ def change_port_status(
profile = netbox.get_preferred_snmp_management_profile(require_write=True)

if not profile:
raise NoReadWriteManagementProfileError
raise NoReadWriteManagementProfileError(
"%s has no read-write management profile" % netbox
)

agent = agent_getter(profile)(host=netbox.ip)

Expand Down
4 changes: 2 additions & 2 deletions python/nav/web/arnold/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def process_manual_detention_form(form, account):
disable(
identity, justification, username, comment=comment, autoenablestep=days
)
except GeneralException as error:
except Exception as error: # noqa
return error
elif form.cleaned_data['method'] == 'quarantine':
qvlan = QuarantineVlan.objects.get(pk=form.cleaned_data['qvlan'])
Expand All @@ -335,7 +335,7 @@ def process_manual_detention_form(form, account):
comment=comment,
autoenablestep=days,
)
except GeneralException as error:
except Exception as error: # noqa
return error


Expand Down
152 changes: 125 additions & 27 deletions tests/integration/web/arnold_test.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,138 @@
import pytest
from django.urls import reverse
from django.utils.encoding import smart_str

from nav.models.arnold import QuarantineVlan
from nav.models.arnold import Justification, QuarantineVlan
from nav.models.fields import INFINITY
from nav.models.manage import Cam, Device, Interface, Module, Netbox


def test_arnold_manualdetention_should_not_crash(client):
url = reverse('arnold-manual-detention')
class TestManualDetention:
def test_should_not_crash(self, client):
url = reverse('arnold-manual-detention')

response = client.post(
url,
follow=True,
data={
'submit': 'Find',
'target': '10.0.0.1',
}, # any address will do
)
response = client.post(
url,
follow=True,
data={
'submit': 'Find',
'target': '10.0.0.1',
}, # any address will do
)

assert response.status_code == 200

def test_given_netbox_without_read_write_profile_blocking_should_show_error(
self, client, cam_entry
):
qvlan = QuarantineVlan.objects.create(vlan=1, description='')
justification = Justification.objects.create(name='justification')

url = reverse("arnold-manual-detention-step-two", args=(cam_entry.mac,))

response = client.post(
url,
follow=True,
data={
"camtuple": str(cam_entry.pk),
"target": cam_entry.mac,
"method": "disable",
"qvlan": str(qvlan.pk),
"justification": str(justification.pk),
"submit": "Detain",
},
)

assert response.status_code == 200
assert (
str(response.context.get("error"))
== "example-sw.example.org has no read-write management profile"
)

def test_given_netbox_without_read_write_profile_quarantining_should_show_error(
self, client, cam_entry
):
qvlan = QuarantineVlan.objects.create(vlan=1, description='')
justification = Justification.objects.create(name='justification')

url = reverse("arnold-manual-detention-step-two", args=(cam_entry.mac,))

response = client.post(
url,
follow=True,
data={
"camtuple": str(cam_entry.pk),
"target": cam_entry.mac,
"method": "quarantine",
"qvlan": str(qvlan.pk),
"justification": str(justification.pk),
"submit": "Detain",
},
)

assert response.status_code == 200
assert response.status_code == 200
assert (
str(response.context.get("error"))
== "example-sw.example.org has no read-write management profile"
)


def test_arnold_quarantine_vlan_twice_should_show_error_message(client):
url = reverse('arnold-quarantinevlans')
class TestQuarantineVlan:
def test_quarantine_vlan_twice_should_show_error_message(self, client):
url = reverse('arnold-quarantinevlans')

vlan_id = 1
QuarantineVlan.objects.create(vlan=vlan_id, description='')
vlan_id = 1
QuarantineVlan.objects.create(vlan=vlan_id, description='')

response = client.post(
url,
follow=True,
data={
'vlan': vlan_id,
'description': '',
'qid': '',
'submit': 'Add+vlan',
},
response = client.post(
url,
follow=True,
data={
'vlan': vlan_id,
'description': '',
'qid': '',
'submit': 'Add+vlan',
},
)

assert response.status_code == 200
assert "This vlan is already quarantined." in smart_str(response.content)


@pytest.fixture()
def cam_entry(db):
box = Netbox(
ip='10.254.254.254',
sysname='example-sw.example.org',
organization_id='myorg',
room_id='myroom',
category_id='SW',
)
box.save()

device = Device(serial="1234test")
device.save()
module = Module(device=device, netbox=box, name='Module 1', model='')
module.save()

interface = Interface(
netbox=box,
module=module,
ifindex=1,
)
interface.save()

cam = Cam.objects.create(
netbox_id=box.id,
mac='aa:aa:aa:aa:aa:aa',
ifindex=interface.ifindex,
end_time=INFINITY,
)

yield cam

assert response.status_code == 200
assert "This vlan is already quarantined." in smart_str(response.content)
cam.delete()
interface.delete()
module.delete()
device.delete()
box.delete()
Loading