apps.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from django.apps import AppConfig
  2. from django.conf import settings
  3. from django.core.cache import cache
  4. from django.db import models
  5. from django.db.migrations.operations import AlterModelOptions
  6. from django.utils.translation import gettext as _
  7. from PIL import Image
  8. from core.events import *
  9. from netbox.events import EVENT_TYPE_KIND_DANGER, EVENT_TYPE_KIND_SUCCESS, EVENT_TYPE_KIND_WARNING, EventType
  10. from utilities.migration import custom_deconstruct
  11. # Ignore verbose_name & verbose_name_plural Meta options when calculating model migrations
  12. AlterModelOptions.ALTER_OPTION_KEYS.remove('verbose_name')
  13. AlterModelOptions.ALTER_OPTION_KEYS.remove('verbose_name_plural')
  14. # Use our custom destructor to ignore certain attributes when calculating field migrations
  15. models.Field.deconstruct = custom_deconstruct
  16. # Cap the maximum size of an image Pillow will decode, to mitigate decompression-bomb DoS attacks. Pillow raises a
  17. # DecompressionBombError when an image's declared dimensions exceed 2x this value, before allocating pixel buffers.
  18. # Django's & DRF's ImageField already convert that exception into a validation error, so no additional handling is
  19. # required; this single assignment covers all image upload paths (UI forms, REST API, and direct model saves).
  20. Image.MAX_IMAGE_PIXELS = 25_000_000
  21. class CoreConfig(AppConfig):
  22. name = "core"
  23. def ready(self):
  24. from core.api import schema # noqa: F401
  25. from core.checks import ( # noqa: F401
  26. check_duplicate_indexes,
  27. check_postgresql_version,
  28. check_redis_version,
  29. )
  30. from netbox import context_managers # noqa: F401
  31. from netbox.models.features import register_models
  32. # Importing netbox.search.jobs registers its system job(s) (e.g. the
  33. # search-cache flush safety net) in registry['system_jobs'] before the
  34. # RQ worker reads that registry at startup. The module is otherwise only
  35. # imported lazily, so this import is load-bearing, not cosmetic.
  36. from netbox.search import jobs as search_jobs # noqa: F401
  37. from netbox.search import signals as search_signals # noqa: F401
  38. from . import data_backends, events, search # noqa: F401
  39. # Register models
  40. register_models(*self.get_models())
  41. # Register core events
  42. EventType(OBJECT_CREATED, _('Object created')).register()
  43. EventType(OBJECT_UPDATED, _('Object updated')).register()
  44. EventType(OBJECT_DELETED, _('Object deleted'), destructive=True).register()
  45. EventType(JOB_STARTED, _('Job started')).register()
  46. EventType(JOB_COMPLETED, _('Job completed'), kind=EVENT_TYPE_KIND_SUCCESS).register()
  47. EventType(JOB_FAILED, _('Job failed'), kind=EVENT_TYPE_KIND_WARNING).register()
  48. EventType(JOB_ERRORED, _('Job errored'), kind=EVENT_TYPE_KIND_DANGER).register()
  49. # Clear Redis cache on startup in development mode
  50. if settings.DEBUG:
  51. try:
  52. cache.clear()
  53. except Exception:
  54. pass