Skip to content

Commit

Permalink
[connections] Removed DeviceIp (not used right now)
Browse files Browse the repository at this point in the history
management_ip is enough for the moment, let's keep things simple
  • Loading branch information
nemesifier committed Apr 22, 2019
1 parent 8b18302 commit b31a6ed
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 144 deletions.
4 changes: 0 additions & 4 deletions openwisp_controller/config/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ class TestAdmin(CreateConfigTemplateMixin, TestAdminMixin,
'deviceconnection_set-INITIAL_FORMS': 0,
'deviceconnection_set-MIN_NUM_FORMS': 0,
'deviceconnection_set-MAX_NUM_FORMS': 1000,
'deviceip_set-TOTAL_FORMS': 0,
'deviceip_set-INITIAL_FORMS': 0,
'deviceip_set-MIN_NUM_FORMS': 0,
'deviceip_set-MAX_NUM_FORMS': 1000,
}
# WARNING - WATCHOUT
# this class attribute is changed dinamically
Expand Down
14 changes: 2 additions & 12 deletions openwisp_controller/connection/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from ..admin import MultitenantAdminMixin
from ..config.admin import DeviceAdmin
from .models import Credentials, DeviceConnection, DeviceIp
from .models import Credentials, DeviceConnection


@admin.register(Credentials)
Expand All @@ -21,16 +21,6 @@ class CredentialsAdmin(MultitenantAdminMixin, TimeReadonlyAdminMixin, admin.Mode
list_select_related = ('organization',)


class DeviceIpInline(admin.TabularInline):
model = DeviceIp
exclude = ('created', 'modified')
extra = 0

def get_queryset(self, request):
qs = super(DeviceIpInline, self).get_queryset(request)
return qs.order_by('priority')


class DeviceConnectionInline(MultitenantAdminMixin, admin.StackedInline):
model = DeviceConnection
exclude = ['params', 'created', 'modified']
Expand All @@ -46,4 +36,4 @@ def get_queryset(self, request):
return super(admin.StackedInline, self).get_queryset(request)


DeviceAdmin.inlines += [DeviceConnectionInline, DeviceIpInline]
DeviceAdmin.inlines += [DeviceConnectionInline]
5 changes: 4 additions & 1 deletion openwisp_controller/connection/connectors/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ def params(self):
def connect(self):
success = False
exception = None
for address in self.addresses:
addresses = self.addresses
if not addresses:
raise ValueError('No valid IP addresses to initiate connections found')
for address in addresses:
try:
self.shell.connect(address,
timeout=SSH_CONNECTION_TIMEOUT,
Expand Down
17 changes: 1 addition & 16 deletions openwisp_controller/connection/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,5 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Device connections',
'verbose_name': 'Device connection',
},
),
migrations.CreateModel(
name='DeviceIp',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('address', models.GenericIPAddressField(verbose_name='IP address')),
('priority', models.PositiveSmallIntegerField()),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='config.Device')),
],
options={
'verbose_name_plural': 'Device IP addresses',
'verbose_name': 'Device IP',
},
),
)
]
29 changes: 1 addition & 28 deletions openwisp_controller/connection/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import collections
import ipaddress
import logging

from django.core.exceptions import ValidationError
Expand All @@ -18,7 +17,6 @@

from ..config.models import Device
from . import settings as app_settings
from .utils import get_interfaces

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -188,21 +186,10 @@ def clean(self):

def get_addresses(self):
"""
returns a list of ip addresses for the related device
returns a list of ip addresses that can be used to connect to the device
(used to pass a list of ip addresses to a DeviceConnection instance)
"""
deviceip_set = list(self.device.deviceip_set.all()
.only('address')
.order_by('priority'))
address_list = []
for deviceip in deviceip_set:
address = deviceip.address
ip = ipaddress.ip_address(address)
if not ip.is_link_local:
address_list.append(address)
else:
for interface in get_interfaces():
address_list.append('{0}%{1}'.format(address, interface))
if self.device.management_ip:
address_list.append(self.device.management_ip)
if self.device.last_ip:
Expand Down Expand Up @@ -240,17 +227,3 @@ def update_config(self):
else:
self.device.config.set_status_applied()
self.disconnect()


@python_2_unicode_compatible
class DeviceIp(TimeStampedEditableModel):
device = models.ForeignKey('config.Device', on_delete=models.CASCADE)
address = models.GenericIPAddressField(_('IP address'))
priority = models.PositiveSmallIntegerField()

class Meta:
verbose_name = _('Device IP')
verbose_name_plural = _('Device IP addresses')

def __str__(self):
return self.address
14 changes: 1 addition & 13 deletions openwisp_controller/connection/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from openwisp_users.tests.utils import TestOrganizationMixin

from .. import settings as app_settings
from ..models import Credentials, DeviceConnection, DeviceIp
from ..models import Credentials, DeviceConnection


class CreateConnectionsMixin(CreateConfigTemplateMixin, TestOrganizationMixin):
Expand Down Expand Up @@ -55,18 +55,6 @@ def _create_device_connection(self, **kwargs):
dc.save()
return dc

def _create_device_ip(self, **kwargs):
opts = dict(address='10.40.0.1',
priority=1)
opts.update(kwargs)
if 'device' not in opts:
dc = self._create_device_connection()
opts['device'] = dc.device
ip = DeviceIp(**opts)
ip.full_clean()
ip.save()
return ip


class SshServer(BaseSshServer):
is_teardown = False
Expand Down
6 changes: 2 additions & 4 deletions openwisp_controller/connection/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@
from ...config.models import Template
from ...config.tests.test_admin import TestAdmin as TestConfigAdmin
from ...tests.utils import TestAdminMixin
from ..models import Credentials, DeviceConnection, DeviceIp
from ..models import Credentials, DeviceConnection
from .base import CreateConnectionsMixin, SshServerMixin


class TestAdmin(TestAdminMixin, CreateConnectionsMixin,
SshServerMixin, TestCase):
template_model = Template
credentials_model = Credentials
deviceip_model = DeviceIp
connection_model = DeviceConnection
operator_permission_filters = [
{'codename__endswith': 'config'},
{'codename__endswith': 'device'},
{'codename__endswith': 'template'},
{'codename__endswith': 'connection'},
{'codename__endswith': 'credentials'},
{'codename__endswith': 'device_connection'},
{'codename__endswith': 'device_ip'},
{'codename__endswith': 'device_connection'}
]
_device_params = TestConfigAdmin._device_params.copy()

Expand Down
60 changes: 21 additions & 39 deletions openwisp_controller/connection/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@
from openwisp_users.models import Organization

from .. import settings as app_settings
from ..models import Credentials, DeviceIp
from ..utils import get_interfaces
from ..models import Credentials
from .base import CreateConnectionsMixin, SshServerMixin


class TestModels(SshServerMixin, CreateConnectionsMixin, TestCase):
def _create_device(self, *args, **kwargs):
if 'last_ip' not in kwargs and 'management_ip' not in kwargs:
kwargs.update({
'last_ip': self.ssh_server.host,
'management_ip': self.ssh_server.host,
})
return super(TestModels, self)._create_device(*args, **kwargs)

def test_connection_str(self):
c = Credentials(name='Dev Key', connector=app_settings.CONNECTORS[0][0])
self.assertIn(c.name, str(c))
self.assertIn(c.get_connector_display(), str(c))

def test_deviceip_str(self):
di = DeviceIp(address='10.40.0.1')
self.assertIn(di.address, str(di))

def test_device_connection_get_params(self):
dc = self._create_device_connection()
self.assertEqual(dc.get_params(), dc.credentials.params)
Expand Down Expand Up @@ -76,8 +79,6 @@ def test_device_connection_ssh_key_param(self):
def test_ssh_connect(self):
ckey = self._create_credentials_with_key(port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
self._create_device_ip(address=self.ssh_server.host,
device=dc.device)
dc.connect()
self.assertTrue(dc.is_working)
self.assertIsNotNone(dc.last_attempt)
Expand All @@ -91,8 +92,6 @@ def test_ssh_connect_failure(self):
ckey = self._create_credentials_with_key(username='wrong',
port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
self._create_device_ip(address=self.ssh_server.host,
device=dc.device)
dc.connect()
self.assertEqual(dc.is_working, False)
self.assertIsNotNone(dc.last_attempt)
Expand Down Expand Up @@ -134,48 +133,30 @@ def test_device_connection_schema(self):
else:
self.fail('ValidationError not raised')

def _prepare_address_list_test(self, addresses,
last_ip=None,
def _prepare_address_list_test(self, last_ip=None,
management_ip=None):
update_strategy = app_settings.UPDATE_STRATEGIES[0][0]
device = self._create_device(organization=self._create_org(),
last_ip=last_ip,
management_ip=management_ip)
dc = self._create_device_connection(device=device,
update_strategy=update_strategy)
for index, address in enumerate(addresses):
self._create_device_ip(device=device,
address=address,
priority=index + 1)
return dc

def test_address_list(self):
dc = self._prepare_address_list_test(['10.40.0.1', '192.168.40.1'])
self.assertEqual(dc.get_addresses(), [
'10.40.0.1',
'192.168.40.1'
])
dc = self._prepare_address_list_test()
self.assertEqual(dc.get_addresses(), [])

def test_address_list_with_device_ip(self):
dc = self._prepare_address_list_test(
['192.168.40.1'],
management_ip='10.0.0.2',
last_ip='84.32.46.153',
)
self.assertEqual(dc.get_addresses(), [
'192.168.40.1',
'10.0.0.2',
'84.32.46.153'
])

def test_address_list_link_local_ip(self):
ipv6_linklocal = 'fe80::2dae:a0d4:94da:7f61'
dc = self._prepare_address_list_test([ipv6_linklocal])
address_list = dc.get_addresses()
interfaces = get_interfaces()
self.assertEqual(len(address_list), len(interfaces))
self.assertIn(ipv6_linklocal, address_list[0])

def test_device_connection_credential_org_validation(self):
dc = self._create_device_connection()
shared = self._create_credentials(name='cred-shared',
Expand Down Expand Up @@ -274,8 +255,6 @@ def test_device_config_update(self):
self._create_device_connection(device=device,
credentials=cred,
update_strategy=update_strategy)
self._create_device_ip(device=device,
address=self.ssh_server.host)
c.config = {
'interfaces': [
{
Expand All @@ -302,8 +281,6 @@ def test_device_config_update(self):
def test_ssh_exec_exit_code(self):
ckey = self._create_credentials_with_key(port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
self._create_device_ip(address=self.ssh_server.host,
device=dc.device)
dc.connector_instance.connect()
with mock.patch(self._exec_command_path) as mocked:
mocked.return_value = self._exec_command_return_value(exit_code=1)
Expand All @@ -315,8 +292,6 @@ def test_ssh_exec_exit_code(self):
def test_ssh_exec_timeout(self):
ckey = self._create_credentials_with_key(port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
self._create_device_ip(address=self.ssh_server.host,
device=dc.device)
dc.connector_instance.connect()
with mock.patch(self._exec_command_path) as mocked:
mocked.side_effect = socket.timeout()
Expand All @@ -328,12 +303,19 @@ def test_ssh_exec_timeout(self):
def test_ssh_exec_exception(self):
ckey = self._create_credentials_with_key(port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
self._create_device_ip(address=self.ssh_server.host,
device=dc.device)
dc.connector_instance.connect()
with mock.patch(self._exec_command_path) as mocked:
mocked.side_effect = RuntimeError('test')
with self.assertRaises(RuntimeError):
dc.connector_instance.exec_command('trigger_exception')
dc.connector_instance.disconnect()
mocked.assert_called_once()

def test_connect_no_addresses(self):
ckey = self._create_credentials_with_key(port=self.ssh_server.port)
dc = self._create_device_connection(credentials=ckey)
dc.device.last_ip = None
dc.device.management_ip = None
dc.save()
with self.assertRaises(ValueError):
dc.connector_instance.connect()
27 changes: 0 additions & 27 deletions openwisp_controller/connection/utils.py

This file was deleted.

0 comments on commit b31a6ed

Please sign in to comment.