Skip to content

Commit 97eceeb

Browse files
committed
[change] Added cache for org config, refactoring
Org config settings are now cached to ensure DeviceChecksumview is not degraded. This will be invalidated on org settings update/delete which are rare. Refactored code and tests for readability. Signed-off-by: DragnEmperor <[email protected]>
1 parent 0b1bef4 commit 97eceeb

File tree

15 files changed

+172
-115
lines changed

15 files changed

+172
-115
lines changed

docs/user/settings.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,8 @@ For more information on these settings, you can refer to the `the celery
743743
documentation regarding automatic retries for known errors.
744744
<https://docs.celeryq.dev/en/stable/userguide/tasks.html#automatic-retry-for-known-exceptions>`_
745745

746-
``OPENWISP_CONTROLLER_WHOIS_ENABLED``
747-
-------------------------------------
746+
``OPENWISP_CONTROLLER_WHO_IS_ENABLED``
747+
--------------------------------------
748748

749749
============ =========
750750
**type**: ``bool``
@@ -754,7 +754,7 @@ documentation regarding automatic retries for known errors.
754754
Allows to enable WhoIs lookup feature.
755755

756756
.. image:: https://github.com/user-attachments/assets/0737d39c-1fad-4fca-aca9-9b42bc321763
757-
:alt: whois admin setting
757+
:alt: who_is admin setting
758758

759759
This feature is used to fetch details of a device based on its last
760760
reported public IP address. The fetched details include ASN, CIDR,
@@ -776,7 +776,7 @@ This feature is disabled by default and requires setting the
776776

777777
This setting represents the Account ID of your Maxmind Account which can
778778
be obtained by following the steps mentioned in the :doc:`WhoIs Lookup
779-
<whois>`.
779+
<who-is>`.
780780

781781
This setting is required for WhoIs lookup feature to work.
782782

@@ -790,6 +790,6 @@ This setting is required for WhoIs lookup feature to work.
790790

791791
This setting represents the License Key of your Maxmind Account which can
792792
be obtained by following the steps mentioned in the :doc:`WhoIs Lookup
793-
<whois>`.
793+
<who-is>`.
794794

795795
This setting is required for WhoIs lookup feature to work.

docs/user/whois.rst renamed to docs/user/who-is.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ WHOIS lookup
66
The WhoIs lookup feature is disabled by default.
77

88
In order to enable this feature you have to follow the `setup
9-
instructions <controller_setup_whois_lookup_>`_ below and then
9+
instructions <controller_setup_who_is_lookup_>`_ below and then
1010
activate it via :ref:`global setting or from the admin interface
11-
<OPENWISP_CONTROLLER_WHOIS_ENABLED>`.
11+
<OPENWISP_CONTROLLER_WHO_IS_ENABLED>`.
1212

1313
WhoIs feature includes fetching details of the last public ip address
1414
reported by a device to ensure better device management.
1515

1616
The fetched details include Organization Name, ASN, CIDR, Address,
1717
Timezone.
1818

19-
.. _controller_setup_whois_lookup:
19+
.. _controller_setup_who_is_lookup:
2020

2121
Setup
2222
-----

openwisp_controller/config/apps.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def __setmodels__(self):
6363
self.org_limits = load_model("config", "OrganizationLimits")
6464
self.cert_model = load_model("django_x509", "Cert")
6565
self.org_model = load_model("openwisp_users", "Organization")
66+
self.org_config_model = load_model("config", "OrganizationConfigSettings")
6667

6768
def connect_signals(self):
6869
"""
@@ -74,6 +75,10 @@ def connect_signals(self):
7475
* cache invalidation
7576
"""
7677
from . import handlers # noqa
78+
from .who_is.handlers import (
79+
device_who_is_info_delete_handler,
80+
invalidate_org_settings_cache,
81+
)
7782

7883
m2m_changed.connect(
7984
self.config_model.clean_templates,
@@ -156,6 +161,21 @@ def connect_signals(self):
156161
sender=self.org_model,
157162
dispatch_uid="organization_allowed_devices_post_save_handler",
158163
)
164+
post_delete.connect(
165+
device_who_is_info_delete_handler,
166+
sender=self.device_model,
167+
dispatch_uid="device.delete_who_is_info",
168+
)
169+
post_save.connect(
170+
invalidate_org_settings_cache,
171+
self.org_config_model,
172+
dispatch_uid="invalidate_org_config_cache_on_org_config_save",
173+
)
174+
post_delete.connect(
175+
invalidate_org_settings_cache,
176+
self.org_config_model,
177+
dispatch_uid="invalidate_org_config_cache_on_org_config_delete",
178+
)
159179

160180
def register_menu_groups(self):
161181
register_menu_group(
@@ -312,7 +332,6 @@ def enable_cache_invalidation(self):
312332
devicegroup_delete_handler,
313333
vpn_server_change_handler,
314334
)
315-
from .whois.handlers import device_whois_info_delete_handler
316335

317336
post_save.connect(
318337
DeviceChecksumView.invalidate_get_device_cache,
@@ -370,11 +389,6 @@ def enable_cache_invalidation(self):
370389
sender=self.vpn_model,
371390
dispatch_uid="vpn.invalidate_checksum_cache",
372391
)
373-
post_delete.connect(
374-
device_whois_info_delete_handler,
375-
sender=self.device_model,
376-
dispatch_uid="device.delete_whois_info",
377-
)
378392

379393
def register_dashboard_charts(self):
380394
register_dashboard_chart(

openwisp_controller/config/base/device.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ def _get_initial_values_for_checked_fields(self):
337337
if not present_values:
338338
return
339339
self.refresh_from_db(fields=present_values.keys())
340-
for field in present_values:
340+
# TODO: check
341+
for field in self._changed_checked_fields:
341342
setattr(self, f"_initial_{field}", field)
342343
setattr(self, field, present_values[field])
343344

@@ -381,7 +382,7 @@ def _check_last_ip(self):
381382
if self._initial_last_ip == models.DEFERRED:
382383
return
383384

384-
self.whois_service.trigger_whois_lookup()
385+
self.who_is_service.trigger_who_is_lookup()
385386

386387
self._initial_last_ip = self.last_ip
387388

@@ -424,12 +425,12 @@ def status(self):
424425
return self._get_config_attr("get_status_display")
425426

426427
@cached_property
427-
def whois_service(self):
428+
def who_is_service(self):
428429
"""
429430
Used as a shortcut to get WhoIsService instance
430431
for the device.
431432
"""
432-
from ..whois.service import WhoIsService
433+
from ..who_is.service import WhoIsService
433434

434435
return WhoIsService(self)
435436

openwisp_controller/config/base/multitenancy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class AbstractOrganizationConfigSettings(UUIDModel):
4343
),
4444
verbose_name=_("Configuration Variables"),
4545
)
46-
whois_enabled = FallbackBooleanChoiceField(
46+
who_is_enabled = FallbackBooleanChoiceField(
4747
help_text=_("Whether WhoIs details lookup is enabled"),
48-
fallback=app_settings.WHOIS_ENABLED,
48+
fallback=app_settings.WHO_IS_ENABLED,
4949
verbose_name=_("WhoIs Enabled"),
5050
)
5151

openwisp_controller/config/migrations/0060_whoisinfo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ class Migration(migrations.Migration):
7878
),
7979
migrations.AddField(
8080
model_name="organizationconfigsettings",
81-
name="whois_enabled",
81+
name="who_is_enabled",
8282
field=openwisp_utils.fields.FallbackBooleanChoiceField(
8383
blank=True,
8484
default=None,
85-
fallback=app_settings.WHOIS_ENABLED,
85+
fallback=app_settings.WHO_IS_ENABLED,
8686
help_text="Whether WhoIs details lookup is enabled",
8787
null=True,
8888
verbose_name="WhoIs Enabled",

openwisp_controller/config/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .base.tag import AbstractTaggedTemplate, AbstractTemplateTag
1111
from .base.template import AbstractTemplate
1212
from .base.vpn import AbstractVpn, AbstractVpnClient
13-
from .base.whois import AbstractWhoIsInfo
13+
from .base.who_is import AbstractWhoIsInfo
1414

1515

1616
class Device(AbstractDevice):
@@ -116,7 +116,7 @@ class Meta(AbstractOrganizationLimits.Meta):
116116

117117
class WhoIsInfo(AbstractWhoIsInfo):
118118
"""
119-
Concrete Whois model
119+
Concrete WhoIs model
120120
"""
121121

122122
class Meta(AbstractWhoIsInfo.Meta):

openwisp_controller/config/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ def get_setting(option, default):
6969
)
7070
GEOIP_ACCOUNT_ID = get_setting("GEOIP_ACCOUNT_ID", None)
7171
GEOIP_LICENSE_KEY = get_setting("GEOIP_LICENSE_KEY", None)
72-
WHOIS_ENABLED = get_setting("WHOIS_ENABLED", False)
72+
WHO_IS_ENABLED = get_setting("WHO_IS_ENABLED", False)

openwisp_controller/config/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ def update_last_ip(device, request):
7373
if device.last_ip != ip:
7474
device.last_ip = ip
7575
update_fields.append("last_ip")
76-
# for cases of devices who do not have whois record
77-
elif not device.whois_service.get_whois_info():
78-
device.whois_service.trigger_whois_lookup()
76+
# for cases of devices who do not have who_is record
77+
elif not device.who_is_service.get_device_who_is_info():
78+
device.who_is_service.trigger_who_is_lookup()
7979
if device.management_ip != management_ip:
8080
device.management_ip = management_ip
8181
update_fields.append("management_ip")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from django.core.cache import cache
2+
from django.db import transaction
3+
4+
from .service import WhoIsService
5+
6+
7+
# Remove the related WhoIs record for that ip from db and cache
8+
# If other active devices are linked to it, then new lookup will
9+
# be triggered for them.
10+
def device_who_is_info_delete_handler(instance, **kwargs):
11+
transaction.on_commit(
12+
lambda: WhoIsService.delete_who_is_record.delay(instance.last_ip)
13+
)
14+
15+
16+
def invalidate_org_settings_cache(instance, **kwargs):
17+
org_pk = instance.organization_id
18+
cache.delete(WhoIsService.ORG_SETTINGS_CACHE_KEY.format(org_pk=org_pk))

0 commit comments

Comments
 (0)