Skip to content

Commit

Permalink
[models] Swapper for openwisp-controller & openwisp-users #83
Browse files Browse the repository at this point in the history
Closes #83
  • Loading branch information
atb00ker authored Jul 7, 2020
1 parent bbb8e46 commit 87e7135
Show file tree
Hide file tree
Showing 26 changed files with 105 additions and 83 deletions.
12 changes: 6 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ coverage.xml
# Django stuff:
*.log

# celery
tests/celerybeat*

# Sphinx documentation
docs/_build/

Expand All @@ -55,6 +58,7 @@ target/

# editors
*.komodoproject
.vscode

# other
*.DS_Store*
Expand All @@ -63,9 +67,5 @@ target/
local_settings.py
*.db
*.tar.gz

# celery
tests/celerybeat*

# editor
.vscode
Pipfile
Pipfile.lock
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ before_install:

install:
- pip install -e .
# temporary: remove when openwisp-notifications is released
# TODO: removed when openwisp-controller 0.8.0 is released
- pip install -U https://github.com/openwisp/openwisp-controller/tarball/master
# TODO: removed when openwisp-users 0.3.0 is released
- pip install -U https://github.com/openwisp/openwisp-users/tarball/master
# TODO: remove when openwisp-notifications 0.1 is released
- pip install -U https://github.com/openwisp/openwisp-notifications/tarball/master

script:
Expand Down
6 changes: 4 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ For ``check`` app,
from openwisp_monitoring.check.admin import CheckAdmin as BaseCheckAdmin
from swapper import load_model
Check = load_model('Check')
Check = load_model('check', 'Check')
admin.site.unregister(Check)
Expand All @@ -808,7 +808,9 @@ For ``device_monitoring`` app,
from django.contrib import admin
from openwisp_monitoring.device_monitoring.admin import DeviceAdmin as BaseDeviceAdmin
from openwisp_controller.config.models import Device
from swapper import load_model
Device = load_model('config', 'Device')
admin.site.unregister(Device)
Expand Down
16 changes: 16 additions & 0 deletions openwisp_monitoring/check/apps.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
from django.apps import AppConfig
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _
from openwisp_monitoring.check import settings as app_settings
from swapper import load_model


class CheckConfig(AppConfig):
name = 'openwisp_monitoring.check'
label = 'check'
verbose_name = _('Network Monitoring Checks')

def ready(self):
self._connect_signals()

def _connect_signals(self):
if app_settings.AUTO_PING:
from .base.models import auto_ping_receiver

post_save.connect(
auto_ping_receiver,
sender=load_model('config', 'Device'),
dispatch_uid='auto_ping',
)
43 changes: 18 additions & 25 deletions openwisp_monitoring/check/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models.signals import post_save
from django.db import models, transaction
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from openwisp_monitoring.check import settings as app_settings
from openwisp_monitoring.check.tasks import auto_create_ping

from openwisp_controller.config.models import Device
from openwisp_utils.base import TimeStampedEditableModel


Expand Down Expand Up @@ -75,26 +74,20 @@ def perform_check(self, store=True):
return self.check_instance.check(store=True)


if app_settings.AUTO_PING:
from django.db import transaction
from django.dispatch import receiver
from openwisp_monitoring.check.tasks import auto_create_ping

@receiver(post_save, sender=Device, dispatch_uid='auto_ping')
def auto_ping_receiver(sender, instance, created, **kwargs):
"""
Implements OPENWISP_MONITORING_AUTO_PING
The creation step is executed in the background
"""
# we need to skip this otherwise this task will be executed
# every time the configuration is requested via checksum
if not created:
return
with transaction.atomic():
transaction.on_commit(
lambda: auto_create_ping.delay(
model=sender.__name__.lower(),
app_label=sender._meta.app_label,
object_id=str(instance.pk),
)
def auto_ping_receiver(sender, instance, created, **kwargs):
"""
Implements OPENWISP_MONITORING_AUTO_PING
The creation step is executed in the background
"""
# we need to skip this otherwise this task will be executed
# every time the configuration is requested via checksum
if not created:
return
with transaction.atomic():
transaction.on_commit(
lambda: auto_create_ping.delay(
model=sender.__name__.lower(),
app_label=sender._meta.app_label,
object_id=str(instance.pk),
)
)
3 changes: 1 addition & 2 deletions openwisp_monitoring/check/classes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
from django.core.exceptions import ValidationError
from swapper import load_model

from openwisp_controller.config.models import Device

Check = load_model('check', 'Check')
Metric = load_model('monitoring', 'Metric')
Device = load_model('config', 'Device')


class BaseCheck(object):
Expand Down
3 changes: 2 additions & 1 deletion openwisp_monitoring/check/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def perform_check(uuid):
@shared_task
def auto_create_ping(model, app_label, object_id):
"""
Called by openwisp_monitoring.check.models.auto_ping_receiver
Called by django signal (dispatch_uid: auto_ping)
registered in check app's apps.py file.
"""
Check = load_model('check', 'Check')
ping_path = 'openwisp_monitoring.check.classes.Ping'
Expand Down
4 changes: 3 additions & 1 deletion openwisp_monitoring/device/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@
from swapper import load_model

from openwisp_controller.config.admin import DeviceAdmin as BaseDeviceAdmin
from openwisp_controller.config.models import Device

from ..monitoring.admin import MetricAdmin
from . import settings as app_settings

DeviceData = load_model('device_monitoring', 'DeviceData')
DeviceMonitoring = load_model('device_monitoring', 'DeviceMonitoring')
Chart = load_model('monitoring', 'Chart')
Device = load_model('config', 'Device')


class DeviceAdmin(BaseDeviceAdmin):
change_form_template = 'admin/config/device/change_form.html'

def get_extra_context(self, pk=None):
ctx = super().get_extra_context(pk)
if pk:
Expand Down
3 changes: 1 addition & 2 deletions openwisp_monitoring/device/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
from rest_framework.response import Response
from swapper import load_model

from openwisp_controller.config.models import Device

from ... import settings as monitoring_settings
from ...monitoring.exceptions import InvalidChartConfigException
from ..schema import schema
Expand All @@ -29,6 +27,7 @@
Chart = load_model('monitoring', 'Chart')
Metric = load_model('monitoring', 'Metric')
AlertSettings = load_model('monitoring', 'AlertSettings')
Device = load_model('config', 'Device')
DeviceData = load_model('device_monitoring', 'DeviceData')


Expand Down
18 changes: 8 additions & 10 deletions openwisp_monitoring/device/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
from django.core.cache import cache
from django.db.models.signals import post_delete, post_save
from django.utils.translation import gettext_lazy as _
from django_netjsonconfig.signals import checksum_requested
from openwisp_notifications.signals import notify
from openwisp_notifications.types import register_notification_type
from swapper import load_model

from openwisp_controller.config.signals import checksum_requested
from openwisp_controller.connection.signals import is_working_changed

from . import settings as app_settings
from .signals import device_metrics_received, health_status_changed
from .utils import get_device_recovery_cache_key, manage_short_retention_policy
Expand All @@ -25,7 +27,7 @@ def ready(self):
self.device_recovery_detection()

def connect_device_signals(self):
from openwisp_controller.config.models import Device
Device = load_model('config', 'Device')

post_save.connect(
self.device_post_save_receiver,
Expand Down Expand Up @@ -56,8 +58,7 @@ def device_recovery_detection(self):
if not app_settings.DEVICE_RECOVERY_DETECTION:
return

from openwisp_controller.config.models import Device

Device = load_model('config', 'Device')
DeviceData = load_model('device_monitoring', 'DeviceData')
DeviceMonitoring = load_model('device_monitoring', 'DeviceMonitoring')
health_status_changed.connect(
Expand Down Expand Up @@ -96,13 +97,10 @@ def trigger_device_recovery_checks(cls, instance, **kwargs):
trigger_device_checks.delay(pk=instance.pk)

@classmethod
def connect_is_working_changed(self):
from openwisp_controller.connection.models import DeviceConnection
from openwisp_controller.connection.signals import is_working_changed

def connect_is_working_changed(cls):
is_working_changed.connect(
self.is_working_changed_receiver,
sender=DeviceConnection,
cls.is_working_changed_receiver,
sender=load_model('connection', 'DeviceConnection'),
dispatch_uid='is_working_changed_monitoring',
)

Expand Down
7 changes: 5 additions & 2 deletions openwisp_monitoring/device/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from collections import OrderedDict
from datetime import datetime

import swapper
from cache_memoize import cache_memoize
from dateutil.relativedelta import relativedelta
from django.core.exceptions import ValidationError
Expand Down Expand Up @@ -45,7 +46,7 @@ class AbstractDeviceData(object):

def __init__(self, *args, **kwargs):
self.data = kwargs.pop('data', None)
return super().__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

@property
def data_user_friendly(self):
Expand Down Expand Up @@ -182,7 +183,9 @@ def json(self, *args, **kwargs):

class AbstractDeviceMonitoring(TimeStampedEditableModel):
device = models.OneToOneField(
'config.Device', on_delete=models.CASCADE, related_name='monitoring'
swapper.get_model_name('config', 'Device'),
on_delete=models.CASCADE,
related_name='monitoring',
)
STATUS = Choices(
('unknown', _(app_settings.HEALTH_STATUS_LABELS['unknown'])),
Expand Down
2 changes: 1 addition & 1 deletion openwisp_monitoring/device/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class Migration(migrations.Migration):
'device_monitoring', 'DeviceData'
),
},
bases=('config.device',),
bases=(swapper.get_model_name('config', 'Device'),),
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class Migration(migrations.Migration):
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name='monitoring',
to='config.Device',
to=swapper.get_model_name('config', 'Device'),
),
),
],
Expand Down
4 changes: 2 additions & 2 deletions openwisp_monitoring/device/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from django.contrib.contenttypes.fields import GenericRelation
from swapper import get_model_name, swappable_setting

from openwisp_controller.config.models import Device
from openwisp_controller.config.models import Device as BaseDevice

from .base.models import AbstractDeviceData, AbstractDeviceMonitoring


class DeviceData(AbstractDeviceData, Device):
class DeviceData(AbstractDeviceData, BaseDevice):
checks = GenericRelation(get_model_name('check', 'Check'))
metrics = GenericRelation(get_model_name('monitoring', 'Metric'))

Expand Down
5 changes: 3 additions & 2 deletions openwisp_monitoring/device/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
from django.urls import reverse
from swapper import load_model

from openwisp_controller.config.models import Config, Device
from openwisp_controller.config.tests import CreateConfigTemplateMixin
from openwisp_controller.config.tests.utils import CreateConfigTemplateMixin

from ...monitoring.tests import TestMonitoringMixin
from ..utils import manage_short_retention_policy

Metric = load_model('monitoring', 'Metric')
DeviceData = load_model('device_monitoring', 'DeviceData')
Chart = load_model('monitoring', 'Chart')
Config = load_model('config', 'Config')
Device = load_model('config', 'Device')


class TestDeviceMonitoringMixin(CreateConfigTemplateMixin, TestMonitoringMixin):
Expand Down
2 changes: 1 addition & 1 deletion openwisp_monitoring/device/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Chart = load_model('monitoring', 'Chart')
Metric = load_model('monitoring', 'Metric')
DeviceData = load_model('device_monitoring', 'DeviceData')
User = get_user_model()


class TestAdmin(DeviceMonitoringTestCase):
Expand All @@ -15,7 +16,6 @@ class TestAdmin(DeviceMonitoringTestCase):
"""

def _login_admin(self):
User = get_user_model()
u = User.objects.create_superuser('admin', 'admin', '[email protected]')
self.client.force_login(u)

Expand Down
8 changes: 4 additions & 4 deletions openwisp_monitoring/device/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,12 @@ def test_invalid_chart_config(self):
d = self._create_device(organization=self._create_org())
m = self._create_object_metric(name='test_metric', content_object=d)
c = self._create_chart(metric=m, test_data=None)
c.configuration = 'invalid'
c.save()
with redirect_stderr(StringIO()) as stderr:
c.configuration = 'invalid'
c.save()
r = self.client.get(self._url(d.pk.hex, d.key))
response = self.client.get(self._url(d.pk.hex, d.key))
self.assertIn('InvalidChartConfigException', stderr.getvalue())
self.assertEqual(r.status_code, 200)
self.assertEqual(response.status_code, 200)

def test_available_memory(self):
o = self._create_org()
Expand Down
Loading

0 comments on commit 87e7135

Please sign in to comment.